Exemple #1
0
        public void TestParseStatusLineOnBranch()
        {
            string    statusLine = "# On branch 0.1  ";
            GitBranch gitBranch  = new GitBranch();

            Assert.AreEqual("0.1", gitBranch.ParseStatusLineOutput(statusLine));
        }
Exemple #2
0
        public void TestParseStatusLineOnMaster()
        {
            string    statusLine = "# On branch master    ";
            GitBranch gitBranch  = new GitBranch();

            Assert.AreEqual("master", gitBranch.ParseStatusLineOutput(statusLine));
        }
Exemple #3
0
        /// <inheritdoc />
        public IObservable <Unit> Rebase(GitBranch parentBranch, IScheduler scheduler = null)
        {
            return(Observable.Create <Unit>(
                       async(observer, token) =>
            {
                if (await this.branchManager.IsWorkingDirectoryDirty())
                {
                    observer.OnError(
                        new GitProcessException("The working directory is dirty. There are uncommited files."));
                }

                IList <string> gitArguments = new List <string> {
                    $"rebase -i  {parentBranch.FriendlyName}"
                };

                this.gitProcess.RunGit(gitArguments, showInOutput: true, scheduler: scheduler).Subscribe(
                    _ => { },
                    observer.OnError,
                    () =>
                {
                    observer.OnNext(Unit.Default);
                    observer.OnCompleted();
                }, token);
            }));
        }
Exemple #4
0
        public void UpdateData(IRepositoryInfoCacheData data)
        {
            var now       = DateTimeOffset.Now;
            var isUpdated = false;

            if (!Nullable.Equals(currentGitRemote, data.CurrentGitRemote))
            {
                currentGitRemote = data.CurrentGitRemote ?? GitRemote.Default;
                isUpdated        = true;
            }

            if (!Nullable.Equals(currentGitBranch, data.CurrentGitBranch))
            {
                currentGitBranch = data.CurrentGitBranch ?? GitBranch.Default;
                isUpdated        = true;
            }

            if (!Nullable.Equals(currentConfigRemote, data.CurrentConfigRemote))
            {
                currentConfigRemote = data.CurrentConfigRemote ?? ConfigRemote.Default;
                isUpdated           = true;
            }

            if (!Nullable.Equals(currentConfigBranch, data.CurrentConfigBranch))
            {
                currentConfigBranch = data.CurrentConfigBranch ?? ConfigBranch.Default;
                isUpdated           = true;
            }

            SaveData(now, isUpdated);
        }
Exemple #5
0
        public void TestIsBranchStatusLine()
        {
            GitBranch gitBranch = new GitBranch();

            Assert.IsTrue(gitBranch.IsBranchStatusLine("# On branch 0.1"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("# Changes not staged for commit:"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#   (use \"git add <file>...\" to update what will be committed)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#   (use \"git checkout -- <file>...\" to discard changes in working directory)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#       modified:   build/MSBuildCodeMetrics.build"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("# Untracked files:"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#   (use \"git add <file>...\" to include in what will be committed)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("#       build/git.bat"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("no changes added to commit (use \"git add\" and/or \"git commit -a\")"));

            Assert.IsTrue(gitBranch.IsBranchStatusLine("On branch 0.1"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("Changes not staged for commit:"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("  (use \"git add <file>...\" to update what will be committed)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("  (use \"git checkout -- <file>...\" to discard changes in working directory)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine(""));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("      modified:   build/MSBuildCodeMetrics.build"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine(""));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("Untracked files:"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("  (use \"git add <file>...\" to include in what will be committed)"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine(""));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("      build/git.bat"));
            Assert.IsFalse(gitBranch.IsBranchStatusLine("no changes added to commit (use \"git add\" and/or \"git commit -a\")"));
        }
Exemple #6
0
        private IEnumerable <string> ExtractLogParameter(
            GitBranch branch,
            int skip,
            int limit,
            GitLogOptions logOptions,
            string revisionRange)
        {
            IList <string> arguments = new List <string>();

            arguments.Add($"{revisionRange} ");

            if (branch != null)
            {
                arguments.Add($"--branches={branch.FriendlyName} ");
            }

            if (skip > 0)
            {
                arguments.Add($"--skip={skip}");
            }

            if (limit > 0)
            {
                arguments.Add($"--max-count={limit}");
            }

            arguments.Add("--full-history");

            if (logOptions.HasFlag(GitLogOptions.TopologicalOrder))
            {
                arguments.Add("--topo-order");
            }

            if (!logOptions.HasFlag(GitLogOptions.IncludeMerges))
            {
                arguments.Add("--no-merges");
                arguments.Add("--first-parent");
            }

            GenerateFormat(arguments);

            if (logOptions.HasFlag(GitLogOptions.BranchOnlyAndParent))
            {
                var ignoreBranches = new StringBuilder("--not ");

                IList <GitBranch> branches = this.GetLocalBranches().ToList().Wait();

                foreach (GitBranch testBranch in branches)
                {
                    if (testBranch != branch)
                    {
                        ignoreBranches.Append($"{testBranch.FriendlyName} ");
                    }
                }

                arguments.Add($" {ignoreBranches} -- ");
            }

            return(arguments);
        }
Exemple #7
0
        public async Task <IEnumerable <GitCommit> > GetCommitsRange(GitBranch fromBranch, GitBranch toBranch)
        {
            var from = new Branch()
            {
                Name   = fromBranch.Name,
                Target = new Commit()
                {
                    Hash = fromBranch.Target.Hash
                }
            };

            var to = new Branch()
            {
                Name   = toBranch.Name,
                Target = new Commit()
                {
                    Hash = toBranch.Target.Hash
                }
            };

            var commits = await _youTrackClient.RepositoriesClient.GetCommitsRange(_gitWatcher.ActiveRepo.Name,
                                                                                   _gitWatcher.ActiveRepo.Owner, from, to);

            return(commits.MapTo <List <GitCommit> >());
        }
Exemple #8
0
        public async Task TestBranchAsync()
        {
            await git.InitRepoAsync();

            io.WriteFile("file1.txt", "Text 1");
            await git.CommitAllChangesAsync("Message 1");

            branches = await git.GetBranchesAsync();

            Assert.AreEqual(1, branches.Count);

            await git.BranchAsync("branch1");

            branches = await git.GetBranchesAsync();

            Assert.AreEqual(2, branches.Count);
            GitBranch current = branches.First(branch => branch.IsCurrent);

            Assert.AreEqual("branch1", current.Name);

            Assert.AreEqual(branches[0].TipSha, branches[1].TipSha);
            io.WriteFile("file1.txt", "Text on branch 1");
            await git.CommitAllChangesAsync("Message 1");

            branches = await git.GetBranchesAsync();

            Assert.AreNotEqual(branches[0].TipSha, branches[1].TipSha);

            await git.CheckoutAsync("master");

            branches = await git.GetBranchesAsync();

            current = branches.First(branch => branch.IsCurrent);
            Assert.AreEqual("master", current.Name);
        }
 private static bool AreLocalRemotePair(GitBranch branch1, GitBranch branch2)
 {
     return
         (branch1.IsRemote &&
          branch2.IsTracking &&
          0 == Txt.CompareOic(branch2.RemoteName, branch1.Name));
 }
        /// <inheritdoc />
        public IObservable <GitRefLog> GetRefLog(GitBranch branch, IScheduler scheduler = null)
        {
            if (branch == null)
            {
                throw new ArgumentNullException(nameof(branch));
            }

            string[] arguments = { "reflog", "--format=\"%H\u001f%h\u001f%gd\u001f%gs\u001f%ci\"", branch.FriendlyName };

            return(_gitProcessManager.RunGit(arguments, scheduler: scheduler).Select(StringToRefLog));
        }
 /// <inheritdoc />
 public IObservable <GitCommit> GetCommitsForBranch(
     GitBranch branch,
     int skip,
     int limit,
     GitLogOptions logOptions,
     IScheduler scheduler = null)
 {
     return(Observable.Return(new[] { "log" })
            .CombineLatest(ExtractLogParameter(branch, skip, limit, logOptions, "HEAD"), (cmd, other) => cmd.Concat(other))
            .SelectMany(x => _gitProcessManager.RunGit(x, scheduler: scheduler).Select(ConvertStringToGitCommit)));
 }
Exemple #12
0
        /// <inheritdoc />
        public IObservable <GitCommit> GetCommitsForBranch(
            GitBranch branch,
            int skip,
            int limit,
            GitLogOptions logOptions,
            IScheduler scheduler = null)
        {
            string[] arguments =
                new[] { "log" }.Concat(this.ExtractLogParameter(branch, skip, limit, logOptions, "HEAD")).ToArray();

            return(this.gitProcessManager.RunGit(arguments, scheduler: scheduler).Select(this.ConvertStringToGitCommit));
        }
        private IObservable <IEnumerable <string> > ExtractLogParameter(
            GitBranch branch,
            int skip,
            int limit,
            GitLogOptions logOptions,
            string revisionRange)
        {
            IList <string> arguments = new List <string>();

            arguments.Add($"{revisionRange} ");

            if (branch != null)
            {
                arguments.Add($"--branches={branch.FriendlyName} ");
            }

            if (skip > 0)
            {
                arguments.Add($"--skip={skip}");
            }

            if (limit > 0)
            {
                arguments.Add($"--max-count={limit}");
            }

            arguments.Add("--full-history");

            if (logOptions.HasFlag(GitLogOptions.TopologicalOrder))
            {
                arguments.Add("--topo-order");
            }

            if (!logOptions.HasFlag(GitLogOptions.IncludeMerges))
            {
                arguments.Add("--no-merges");
                arguments.Add("--first-parent");
            }

            GenerateFormat(arguments);

            var argumentsObservable = Observable.Return(arguments);

            if (logOptions.HasFlag(GitLogOptions.BranchOnlyAndParent))
            {
                argumentsObservable = argumentsObservable.CombineLatest(
                    GetLocalBranches().Where(x => x != branch).Select(x => x.FriendlyName).ToList().Select(x => $"--not {string.Join(" ", x)} --"),
                    (arg, branches) => arg.Concat(new[] { branches }).ToList());
            }

            return(argumentsObservable);
        }
        public void CreatesSemverForReleaseBranch()
        {
            //arrange
            var gitRef = new GitRef {
                Id = "", Name = "refs/heads/release/1.0", ObjectId = ""
            };

            //act
            var result = new GitBranch(gitRef);

            //assert
            Assert.NotNull(result.Semver);
        }
        /// <inheritdoc />
        public IObservable <int> GetCommitCount(GitBranch branchName, IScheduler scheduler = null)
        {
            if (branchName == null)
            {
                throw new ArgumentNullException(nameof(branchName));
            }

            return(_gitProcessManager.RunGit(new[] { $"rev-list --count {branchName.FriendlyName}" }, scheduler: scheduler)
                   .ToList()
                   .FirstAsync()
                   .Select(x => Convert.ToInt32(x, CultureInfo.InvariantCulture))
                   .FirstAsync());
        }
Exemple #16
0
        /// <inheritdoc />
        public IObservable <Unit> CheckoutBranch(GitBranch branch, bool force = false, IScheduler scheduler = null)
        {
            IList <string> arguments = new List <string> {
                $"checkout {branch.FriendlyName}"
            };

            if (force)
            {
                arguments.Add("-f");
            }

            IObservable <Unit> observable = this.gitProcessManager.RunGit(arguments, showInOutput: true, scheduler: scheduler).WhenDone();

            return(observable.Finally(() => this.currentBranch.OnNext(branch)));
        }
Exemple #17
0
        public async Task TestBehindAsync()
        {
            await git.CloneRepoAsync();

            // 2 commits
            io.WriteFile("file1.txt", "text 1");
            await git.CommitAllChangesAsync("Message 1");

            io.WriteFile("file1.txt", "text 2");
            await git.CommitAllChangesAsync("Message 2");

            // Push push
            await git.PushAsync();

            await git.UncommitAsync();

            await git.UndoUncommitedAsync();

            branches = await git.GetBranchesAsync();

            GitBranch local  = branches.First(branch => branch.IsLocal);
            GitBranch remote = branches.First(branch => branch.IsRemote);

            Assert.AreEqual(0, local.AheadCount);
            Assert.AreEqual(1, local.BehindCount);
            Assert.AreEqual(true, local.IsFetchable);
            Assert.AreEqual(false, local.IsPushable);
            Assert.AreEqual(0, remote.AheadCount);
            Assert.AreEqual(0, remote.BehindCount);
            Assert.AreEqual(false, remote.IsFetchable);
            Assert.AreEqual(false, remote.IsPushable);

            io.WriteFile("file1.txt", "text 3");
            await git.CommitAllChangesAsync("Message 3");

            branches = await git.GetBranchesAsync();

            local  = branches.First(branch => branch.IsLocal);
            remote = branches.First(branch => branch.IsRemote);
            Assert.AreEqual(1, local.AheadCount);
            Assert.AreEqual(1, local.BehindCount);
            Assert.AreEqual(false, local.IsFetchable);
            Assert.AreEqual(false, local.IsPushable);
            Assert.AreEqual(0, remote.AheadCount);
            Assert.AreEqual(0, remote.BehindCount);
            Assert.AreEqual(false, remote.IsFetchable);
            Assert.AreEqual(false, remote.IsPushable);
        }
Exemple #18
0
        /// <inheritdoc />
        public async Task <GitCommandResponse> Rebase(CancellationToken token, GitBranch parentBranch)
        {
            if (await this.branchManager.IsWorkingDirectoryDirty(token))
            {
                return(new GitCommandResponse(false, "Cannot rebase: You have unstaged changes.", null, 0));
            }

            GitCommandResponse response = await this.FetchOrigin(token);

            if (response.Success == false)
            {
                return(response);
            }

            return(await this.gitProcess.RunGit($"rebase  {parentBranch.FriendlyName}", token));
        }
        private async Task <R> MergeAsync(BranchName branchName)
        {
            Log.Debug($"Merge branch {branchName} into current branch ...");

            R <IReadOnlyList <GitBranch> > branches = await gitBranchService.GetBranchesAsync(CancellationToken.None);

            if (branches.IsFaulted)
            {
                return(R.Error("Failed to merge", branches.Exception));
            }

            // Trying to get both local and remote branch
            branches.Value.TryGet(branchName, out GitBranch localbranch);
            branches.Value.TryGet($"origin/{branchName}", out GitBranch remoteBranch);

            GitBranch branch = localbranch ?? remoteBranch;

            if (localbranch != null && remoteBranch != null)
            {
                // Both local and remote tip exists, use the branch with the most resent tip
                R <GitCommit> localTipCommit = await gitCommitService.GetCommitAsync(localbranch.TipSha.Sha, CancellationToken.None);

                R <GitCommit> remoteTipCommit = await gitCommitService.GetCommitAsync(remoteBranch.TipSha.Sha, CancellationToken.None);

                if (localTipCommit.IsFaulted || remoteTipCommit.IsFaulted)
                {
                    return(R.Error("Failed to merge", remoteTipCommit.Exception));
                }

                if (remoteTipCommit.Value.CommitDate > localTipCommit.Value.CommitDate)
                {
                    branch = remoteBranch;
                }
            }

            if (branch == null)
            {
                return(R.Error($"Failed to Merge, not valid branch {branchName}"));
            }


            return(await gitMergeService.MergeAsync(branch.Name, CancellationToken.None));
        }
Exemple #20
0
        private static void CopyToUncommitedCommit(
            GitBranch currentBranch,
            MRepository repository,
            GitStatus status,
            MCommit commit,
            CommitId parentId)
        {
            int modifiedCount = status.AllChanges;
            int conflictCount = status.Conflicted;

            string subject = $"{modifiedCount} uncommitted changes in working folder";

            if (conflictCount > 0)
            {
                subject =
                    $"{conflictCount} conflicts and {modifiedCount} changes, {ShortSubject(status)}";
                commit.HasConflicts = true;
            }
            else if (status.IsMerging)
            {
                subject          = $"{modifiedCount} changes, {ShortSubject(status)}";
                commit.IsMerging = true;
            }

            GitCommit gitCommit = new GitCommit(
                CommitSha.Uncommitted,
                subject,
                subject,
                "",
                DateTime.Now,
                DateTime.Now,
                new List <CommitId> {
                parentId
            });

            repository.GitCommits[CommitId.Uncommitted] = gitCommit;

            commit.SetBranchName(currentBranch?.Name ?? "master");

            commit.Tickets  = "";
            commit.BranchId = null;
        }
Exemple #21
0
        private void AddVirtualUncommitted(GitBranch currentBranch, GitStatus status, MRepository repository)
        {
            MCommit commit = repository.Commit(CommitId.Uncommitted);

            repository.Uncommitted = commit;

            commit.IsVirtual = true;

            CommitId headCommitId = CommitId.NoCommits;

            if (currentBranch != null)
            {
                CommitId headId     = new CommitId(currentBranch.TipSha.Sha);
                MCommit  headCommit = repository.Commit(headId);
                headCommitId = headCommit.Id;
            }

            CopyToUncommitedCommit(currentBranch, repository, status, commit, headCommitId);

            SetChildOfParents(commit);
        }
Exemple #22
0
        private static MSubBranch ToBranch(GitBranch gitBranch, MRepository repository)
        {
            BranchName branchName = gitBranch.Name;

            if (gitBranch.IsRemote && branchName.StartsWith(Origin))
            {
                branchName = branchName.Substring(Origin.Length);
            }

            string gitBranchTipId = gitBranch.TipSha.Sha;

            return(new MSubBranch
            {
                Repository = repository,
                SubBranchId = Guid.NewGuid().ToString(),
                Name = branchName,
                TipCommitId = repository.Commit(new CommitId(gitBranchTipId)).Id,
                IsActive = true,
                IsCurrent = gitBranch.IsCurrent,
                IsDetached = gitBranch.IsDetached,
                IsRemote = gitBranch.IsRemote
            });
        }
Exemple #23
0
 private IObservable <GitCommit> GetCommitsImpl(GitBranch branch)
 {
     _commitHistory.Clear();
     return(RepositoryDetails.BranchManager.GetCommitsForBranch(branch, 0, 0, GitLogOptions.IncludeMerges));
 }
Exemple #24
0
 public static void Matches(this GitBranch branch, GitBranch other)
 {
     Assert.AreEqual(other, branch);
 }
Exemple #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BranchLeaf" /> class.
 /// </summary>
 /// <param name="branch">The branch that the lead represents.</param>
 public BranchLeaf(GitBranch branch)
     : base(branch.FriendlyName.Split('/').Last(), branch.FriendlyName)
 {
     Branch = branch;
 }
Exemple #26
0
        public IBranch CreateBranch(string name)
        {
            GitBranch gBranch = new GitBranch(name);

            return(gBranch);
        }
Exemple #27
0
 /// <inheritdoc />
 public Task <IList <GitCommit> > GetCommitsForBranch(GitBranch branch, CancellationToken token, GitLogOptions logOptions, int number = 25)
 {
     return(this.branchManager.GetCommitsForBranch(branch, 0, number, logOptions, token));
 }
Exemple #28
0
 /// <inheritdoc />
 public int GetCommitCount(GitBranch branchName, IScheduler scheduler = null)
 {
     return
         (Convert.ToInt32(
              this.gitProcessManager.RunGit(new[] { $"rev-list --count {branchName.FriendlyName}" }, scheduler: scheduler).ToList().Wait().First()));
 }
Exemple #29
0
        private void AddNode(GitBranch gitBranch)
        {
            if (gitBranch == null)
            {
                return;
            }

            string[]       nodeNames = gitBranch.FriendlyName.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
            StringComparer comparer  = StringComparer.CurrentCultureIgnoreCase;

            IList <BranchNode> currentLevel = this.branches;

            for (var i = 0; i < nodeNames.Length; ++i)
            {
                bool isLast = i == nodeNames.Length - 1;

                string currentNodeName = nodeNames[i];

                int index =
                    currentLevel.BinarySearchIndexOfBy(
                        (compareNode, name) => comparer.Compare(compareNode.Name, name),
                        currentNodeName);

                if ((index >= 0) && isLast)
                {
                    throw new Exception($"There is a duplicate leaf of name {gitBranch.FriendlyName}");
                }

                if (isLast)
                {
                    currentLevel.Add(new BranchLeaf(gitBranch));
                    return;
                }

                BranchNode node = null;
                if (index >= 0)
                {
                    node = currentLevel[index];
                }

                if (node is BranchLeaf)
                {
                    throw new Exception($"There is a leaf node with the same name as a parent {gitBranch.FriendlyName}");
                }

                var parent = node as BranchParent;

                if (parent == null)
                {
                    string fullName = string.Join("/", nodeNames, 0, i + 1);

                    parent = new BranchParent(currentNodeName, fullName);

                    if (index >= 0)
                    {
                        throw new Exception($"There is a duplicate node of name {gitBranch.FriendlyName}");
                    }

                    currentLevel.Insert(~index, parent);
                }

                currentLevel = parent.ChildNodes;
            }
        }
Exemple #30
0
 /// <inheritdoc />
 public IObservable <GitBranch> GetRemoteBranch(GitBranch branch, IScheduler scheduler = null)
 {
     return(Observable.Return <GitBranch>(null));
 }