Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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));
     }
 }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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)));
            }
        }
Beispiel #7
0
        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.");
            }
        }
Beispiel #8
0
        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);
            }
        }
Beispiel #9
0
        /// <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);
            }
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        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.");
            }
        }