public void TestParseStatusLineOnBranch() { string statusLine = "# On branch 0.1 "; GitBranch gitBranch = new GitBranch(); Assert.AreEqual("0.1", gitBranch.ParseStatusLineOutput(statusLine)); }
public void TestParseStatusLineOnMaster() { string statusLine = "# On branch master "; GitBranch gitBranch = new GitBranch(); Assert.AreEqual("master", gitBranch.ParseStatusLineOutput(statusLine)); }
/// <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); })); }
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); }
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\")")); }
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); }
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> >()); }
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))); }
/// <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()); }
/// <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))); }
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); }
/// <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)); }
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; }
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); }
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 }); }
private IObservable <GitCommit> GetCommitsImpl(GitBranch branch) { _commitHistory.Clear(); return(RepositoryDetails.BranchManager.GetCommitsForBranch(branch, 0, 0, GitLogOptions.IncludeMerges)); }
public static void Matches(this GitBranch branch, GitBranch other) { Assert.AreEqual(other, branch); }
/// <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; }
public IBranch CreateBranch(string name) { GitBranch gBranch = new GitBranch(name); return(gBranch); }
/// <inheritdoc /> public Task <IList <GitCommit> > GetCommitsForBranch(GitBranch branch, CancellationToken token, GitLogOptions logOptions, int number = 25) { return(this.branchManager.GetCommitsForBranch(branch, 0, number, logOptions, token)); }
/// <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())); }
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; } }
/// <inheritdoc /> public IObservable <GitBranch> GetRemoteBranch(GitBranch branch, IScheduler scheduler = null) { return(Observable.Return <GitBranch>(null)); }