public void CanQueryRebaseOperation() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, null); // Verify that we have a conflict. Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.False(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); RebaseStepInfo info = repo.Rebase.GetCurrentStepInfo(); Assert.Equal(0, repo.Rebase.GetCurrentStepIndex()); Assert.Equal(3, repo.Rebase.GetTotalStepCount()); Assert.Equal(RebaseStepOperation.Pick, info.Type); } }
public void RebaseWhileAlreadyRebasingThrows() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, null); // Verify that we have a conflict. Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.Equal(CurrentOperation.RebaseMerge, repo.Info.CurrentOperation); Assert.Throws <LibGit2SharpException>(() => repo.Rebase.Start(branch, upstream, onto, Constants.Identity, null)); } }
public GitResult <RebaseStatus> RebaseOntoMaster(Branch actualBranch) { try { RebaseResult rebaseResult = _repository.Rebase.Start(actualBranch, UpStreamMasterBranch, MasterBranch, GetIdentity(), null); return(new GitResult <RebaseStatus>(true, rebaseResult.Status)); } catch (LibGit2SharpException e) { return(new GitResult <RebaseStatus>(false, e)); } }
public void ContinuingRebaseWithUnstagedChangesThrows() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, null); // Verify that we have a conflict. Assert.Equal(CurrentOperation.RebaseMerge, repo.Info.CurrentOperation); Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.False(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); Assert.Throws <UnmergedIndexEntriesException>(() => repo.Rebase.Continue(Constants.Identity, null)); // Resolve the conflict foreach (Conflict conflict in repo.Index.Conflicts) { Touch(repo.Info.WorkingDirectory, conflict.Theirs.Path, repo.Lookup <Blob>(conflict.Theirs.Id).GetContentText(new FilteringOptions(conflict.Theirs.Path))); Commands.Stage(repo, conflict.Theirs.Path); } Touch(repo.Info.WorkingDirectory, filePathA, "Unstaged content"); Assert.Throws <UnmergedIndexEntriesException>(() => repo.Rebase.Continue(Constants.Identity, null)); Assert.True(repo.Index.IsFullyMerged); } }
public RebaseResult RebaseTicket(TicketInformation ticket) { var rebaseResult = new RebaseResult(); var pullRequest = GetPullRequestById(ticket.PullRequestId); if (pullRequest.id != null) { return(AttemptRebase(pullRequest.source.branch.name, pullRequest.destination.branch.name)); } Log.Debug("Pull request for ticket: {Key} could not be found.", ticket.JiraKey); rebaseResult.Status = RebaseStatus.FailedToFindPullRequest; return(rebaseResult); }
public void CanSpecifyFileConflictStrategy() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; RebaseOptions options = new RebaseOptions() { FileConflictStrategy = CheckoutFileConflictStrategy.Ours, }; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, options); // Verify that we have a conflict. Assert.Equal(CurrentOperation.RebaseMerge, repo.Info.CurrentOperation); Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.False(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); string conflictFile = filePathB; // Get the information on the conflict. Conflict conflict = repo.Index.Conflicts[conflictFile]; Assert.NotNull(conflict); Assert.NotNull(conflict.Theirs); Assert.NotNull(conflict.Ours); Blob expectedBlob = repo.Lookup <Blob>(conflict.Ours.Id); // Check the content of the file on disk matches what is expected. string expectedContent = expectedBlob.GetContentText(new FilteringOptions(conflictFile)); Assert.Equal(expectedContent, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, conflictFile))); } }
public void CanAbortRebase() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, null); // Verify that we have a conflict. Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.False(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); // Set up the callbacks to verify that checkout progress / notify // callbacks are called. bool wasCheckoutProgressCalled = false; bool wasCheckoutNotifyCalled = false; RebaseOptions options = new RebaseOptions() { OnCheckoutProgress = (x, y, z) => wasCheckoutProgressCalled = true, OnCheckoutNotify = (x, y) => { wasCheckoutNotifyCalled = true; return(true); }, CheckoutNotifyFlags = CheckoutNotifyFlags.Updated, }; repo.Rebase.Abort(options); Assert.False(repo.RetrieveStatus().IsDirty, "Repository workdir is dirty after Rebase.Abort."); Assert.True(repo.Index.IsFullyMerged, "Repository index is not fully merged after Rebase.Abort."); Assert.Equal(CurrentOperation.None, repo.Info.CurrentOperation); Assert.True(wasCheckoutProgressCalled, "Checkout progress callback was not called during Rebase.Abort."); Assert.True(wasCheckoutNotifyCalled, "Checkout notify callback was not called during Rebase.Abort."); } }
public void CanRebaseBranchOntoItself() { // Maybe we should have an "up-to-date" return type for scenarios such as these, // but for now this test is to make sure we do something reasonable SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch2Name); Branch b = repo.Branches[topicBranch2Name]; RebaseResult result = repo.Rebase.Start(b, b, null, Constants.Identity, new RebaseOptions()); Assert.Equal(0, result.TotalStepCount); Assert.Equal(RebaseStatus.Complete, result.Status); Assert.Equal(0, result.CompletedStepCount); } }
/// <summary> /// Attempt to rebase the source branch over the target branch /// If the rebase encountered merge conflicts, return a failed merge result /// </summary> /// <param name="source"></param> /// <param name="target"></param> /// <returns></returns> private RebaseResult AttemptRebase(string source, string target) { var rebaseResult = new RebaseResult(); try { if (_gitReader.IsRepositoryDirty()) { _gitManager.StashPendingChanges(); Log.Debug("Successfully stashed pending changes."); } _gitReader.FetchLatest(); var result = _gitManager.RebaseBranch(source, target); if (!result.RebaseSuccess) { Log.Warning("Rebase unsuccessful for branch: {Branch}. Status: {Status}.", source, result.Status); rebaseResult.Status = result.Status; return(rebaseResult); } _gitManager.PushBranch(source); Log.Debug("Successfully rebased and pushed branch: {SourceBranch}.", source); rebaseResult.Status = result.Status; rebaseResult.SourceBranch = source; return(rebaseResult); } catch (Exception ex) { Log.Error(ex.Message); rebaseResult.Status = RebaseStatus.Failed; return(rebaseResult); } }
public void CanRebase(string initialBranchName, string branchName, string upstreamName, string ontoName, int stepCount) { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, initialBranchName); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = (branchName == null) ? null : repo.Branches[branchName]; Branch upstream = repo.Branches[upstreamName]; Branch onto = (ontoName == null) ? null : repo.Branches[ontoName]; Commit expectedSinceCommit = (branch == null) ? repo.Head.Tip : branch.Tip; Commit expectedUntilCommit = upstream.Tip; Commit expectedOntoCommit = (onto == null) ? upstream.Tip : onto.Tip; int beforeStepCallCount = 0; int afterStepCallCount = 0; bool beforeRebaseStepCountCorrect = true; bool afterRebaseStepCountCorrect = true; bool totalStepCountCorrect = true; List <Commit> PreRebaseCommits = new List <Commit>(); List <CompletedRebaseStepInfo> PostRebaseResults = new List <CompletedRebaseStepInfo>(); ObjectId expectedParentId = upstream.Tip.Id; RebaseOptions options = new RebaseOptions() { RebaseStepStarting = x => { beforeRebaseStepCountCorrect &= beforeStepCallCount == x.StepIndex; totalStepCountCorrect &= (x.TotalStepCount == stepCount); beforeStepCallCount++; PreRebaseCommits.Add(x.StepInfo.Commit); }, RebaseStepCompleted = x => { afterRebaseStepCountCorrect &= (afterStepCallCount == x.CompletedStepIndex); totalStepCountCorrect &= (x.TotalStepCount == stepCount); afterStepCallCount++; PostRebaseResults.Add(new CompletedRebaseStepInfo(x.Commit, x.WasPatchAlreadyApplied)); }, }; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, options); // Validation: Assert.True(afterRebaseStepCountCorrect, "Unexpected CompletedStepIndex value in RebaseStepCompleted"); Assert.True(beforeRebaseStepCountCorrect, "Unexpected StepIndex value in RebaseStepStarting"); Assert.True(totalStepCountCorrect, "Unexpected TotalStepcount value in Rebase step callback"); Assert.Equal(RebaseStatus.Complete, rebaseResult.Status); Assert.Equal(stepCount, rebaseResult.TotalStepCount); Assert.Null(rebaseResult.CurrentStepInfo); Assert.Equal(stepCount, rebaseResult.CompletedStepCount); Assert.False(repo.RetrieveStatus().IsDirty); Assert.Equal(stepCount, beforeStepCallCount); Assert.Equal(stepCount, afterStepCallCount); // Verify the chain of source commits that were rebased. CommitFilter sourceCommitFilter = new CommitFilter() { IncludeReachableFrom = expectedSinceCommit, ExcludeReachableFrom = expectedUntilCommit, SortBy = CommitSortStrategies.Reverse | CommitSortStrategies.Topological, }; Assert.Equal(repo.Commits.QueryBy(sourceCommitFilter), PreRebaseCommits); // Verify the chain of commits that resulted from the rebase. Commit expectedParent = expectedOntoCommit; foreach (CompletedRebaseStepInfo stepInfo in PostRebaseResults) { Commit rebasedCommit = stepInfo.Commit; Assert.Equal(expectedParent.Id, rebasedCommit.Parents.First().Id); Assert.False(stepInfo.WasPatchAlreadyApplied); expectedParent = rebasedCommit; } Assert.Equal(repo.Head.Tip, PostRebaseResults.Last().Commit); } }
public void CanContinueRebase() { SelfCleaningDirectory scd = BuildSelfCleaningDirectory(); var path = Repository.Init(scd.DirectoryPath); using (Repository repo = new Repository(path)) { ConstructRebaseTestRepository(repo); Commands.Checkout(repo, topicBranch1Name); Assert.False(repo.RetrieveStatus().IsDirty); Branch branch = repo.Branches[topicBranch1Name]; Branch upstream = repo.Branches[conflictBranch1Name]; Branch onto = repo.Branches[conflictBranch1Name]; int beforeStepCallCount = 0; int afterStepCallCount = 0; bool wasCheckoutProgressCalled = false; bool wasCheckoutNotifyCalled = false; RebaseOptions options = new RebaseOptions() { RebaseStepStarting = x => beforeStepCallCount++, RebaseStepCompleted = x => afterStepCallCount++, OnCheckoutProgress = (x, y, z) => wasCheckoutProgressCalled = true, OnCheckoutNotify = (x, y) => { wasCheckoutNotifyCalled = true; return(true); }, CheckoutNotifyFlags = CheckoutNotifyFlags.Updated, }; RebaseResult rebaseResult = repo.Rebase.Start(branch, upstream, onto, Constants.Identity, options); // Verify that we have a conflict. Assert.Equal(CurrentOperation.RebaseMerge, repo.Info.CurrentOperation); Assert.Equal(RebaseStatus.Conflicts, rebaseResult.Status); Assert.True(repo.RetrieveStatus().IsDirty); Assert.False(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); // Verify that expected callbacks were called Assert.Equal(1, beforeStepCallCount); Assert.Equal(0, afterStepCallCount); Assert.True(wasCheckoutProgressCalled, "CheckoutProgress callback was not called."); // Resolve the conflict foreach (Conflict conflict in repo.Index.Conflicts) { Touch(repo.Info.WorkingDirectory, conflict.Theirs.Path, repo.Lookup <Blob>(conflict.Theirs.Id).GetContentText(new FilteringOptions(conflict.Theirs.Path))); Commands.Stage(repo, conflict.Theirs.Path); } Assert.True(repo.Index.IsFullyMerged); // Clear the flags: wasCheckoutProgressCalled = false; wasCheckoutNotifyCalled = false; RebaseResult continuedRebaseResult = repo.Rebase.Continue(Constants.Identity, options); Assert.NotNull(continuedRebaseResult); Assert.Equal(RebaseStatus.Complete, continuedRebaseResult.Status); Assert.False(repo.RetrieveStatus().IsDirty); Assert.True(repo.Index.IsFullyMerged); Assert.Equal(0, rebaseResult.CompletedStepCount); Assert.Equal(3, rebaseResult.TotalStepCount); Assert.Equal(3, beforeStepCallCount); Assert.Equal(3, afterStepCallCount); Assert.True(wasCheckoutProgressCalled, "CheckoutProgress callback was not called."); Assert.True(wasCheckoutNotifyCalled, "CheckoutNotify callback was not called."); } }