public void Adds_multiple_work_items_and_removes_checkin_command_comment()
        {
            StringWriter textWriter = new StringWriter();
            CommitSpecificCheckinOptionsFactory factory = new CommitSpecificCheckinOptionsFactory(textWriter, new Globals());

            CheckinOptions singletonCheckinOptions = new CheckinOptions();

            string commitMessage =
                @"test message

		formatted git commit message

		git-tfs-work-item: 1234 resolve
        git-tfs-work-item: 5678 associate

";

            string expectedCheckinComment =
                @"test message

		formatted git commit message

		"        ;

            var specificCheckinOptions = factory.BuildCommitSpecificCheckinOptions(singletonCheckinOptions, commitMessage);

            Assert.Equal(1, specificCheckinOptions.WorkItemsToResolve.Count);
            Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
            Assert.Contains("1234", specificCheckinOptions.WorkItemsToResolve);
            Assert.Contains("5678", specificCheckinOptions.WorkItemsToAssociate);
            Assert.Equal(expectedCheckinComment.Replace(Environment.NewLine, "NEWLINE"), specificCheckinOptions.CheckinComment.Replace(Environment.NewLine, "NEWLINE"));
        }
        public void Adds_work_item_to_associate_and_removes_checkin_command_comment()
        {
            StringWriter textWriter = new StringWriter();
            CommitSpecificCheckinOptionsFactory factory = new CommitSpecificCheckinOptionsFactory(textWriter, new Globals());

            CheckinOptions singletonCheckinOptions = new CheckinOptions();

            string commitMessage =
                @"test message

		formatted git commit message

		git-tfs-work-item: 1234 associate"        ;

            string expectedCheckinComment =
                @"test message

		formatted git commit message

		"        ;

            var specificCheckinOptions = factory.BuildCommitSpecificCheckinOptions(singletonCheckinOptions, commitMessage);

            Assert.Equal(1, specificCheckinOptions.WorkItemsToAssociate.Count);
            Assert.Contains("1234", specificCheckinOptions.WorkItemsToAssociate);
            Assert.Equal(expectedCheckinComment, specificCheckinOptions.CheckinComment);
        }
        public void Adds_reviewers_and_removes_checkin_command_comment()
        {
            StringWriter textWriter = new StringWriter();
            CommitSpecificCheckinOptionsFactory factory = new CommitSpecificCheckinOptionsFactory(textWriter, new Globals());

            CheckinOptions checkinOptions = new CheckinOptions();

            string commitMessage =
                "Test message\n" +
                "\n" +
                "Some more information,\n" +
                "in a paragraph.\n" +
                "\n" +
                "git-tfs-code-reviewer: John Smith\n" +
                "git-tfs-security-reviewer: Teddy Knox\n" +
                "git-tfs-performance-reviewer: Liam Fasterson";

            string expectedCheckinComment =
                "Test message\n" +
                "\n" +
                "Some more information,\n" +
                "in a paragraph.";

            var specificCheckinOptions = factory.BuildCommitSpecificCheckinOptions(checkinOptions, commitMessage);

            Assert.Equal(3, specificCheckinOptions.CheckinNotes.Count);
            Assert.Equal("John Smith", specificCheckinOptions.CheckinNotes["Code Reviewer"]);
            Assert.Equal("Teddy Knox", specificCheckinOptions.CheckinNotes["Security Reviewer"]);
            Assert.Equal("Liam Fasterson", specificCheckinOptions.CheckinNotes["Performance Reviewer"]);
            Assert.Equal(expectedCheckinComment, specificCheckinOptions.CheckinComment);
        }
        public void Sets_commit_message_as_checkin_comments()
        {
            TextWriter writer = new StringWriter();
            CommitSpecificCheckinOptionsFactory factory = new CommitSpecificCheckinOptionsFactory(writer, new Globals());

            string         originalCheckinComment  = "command-line input";
            CheckinOptions singletonCheckinOptions = new CheckinOptions()
            {
                CheckinComment = originalCheckinComment
            };

            string commitMessage =
                @"test message

		formatted git commit message"        ;

            var specificCheckinOptions = factory.BuildCommitSpecificCheckinOptions(singletonCheckinOptions, commitMessage);

            Assert.Equal(commitMessage, specificCheckinOptions.CheckinComment);
        }
Example #5
0
        private int PerformRCheckin(TfsChangesetInfo parentChangeset)
        {
            var tfsRemote = parentChangeset.Remote;
            var repo      = tfsRemote.Repository;

            if (repo.WorkingCopyHasUnstagedOrUncommitedChanges)
            {
                throw new GitTfsException("error: You have local changes; rebase-workflow checkin only possible with clean working directory.")
                      .WithRecommendation("Try 'git stash' to stash your local changes and checkin again.");
            }

            // get latest changes from TFS to minimize possibility of late conflict
            _stdout.WriteLine("Fetching changes from TFS to minimize possibility of late conflict...");
            parentChangeset.Remote.Fetch();
            if (parentChangeset.ChangesetId != parentChangeset.Remote.MaxChangesetId)
            {
                throw new GitTfsException("error: New TFS changesets were found.")
                      .WithRecommendation("Try to rebase HEAD onto latest TFS checkin and repeat rcheckin or alternatively checkin s");
            }

            string tfsLatest = parentChangeset.Remote.MaxCommitHash;

            // we could rcheckin only if tfsLatest changeset is a parent of HEAD
            // so that we could rebase after each single checkin without conflicts
            if (!String.IsNullOrWhiteSpace(repo.CommandOneline("rev-list", tfsLatest, "^HEAD")))
            {
                throw new GitTfsException("error: latest TFS commit should be parent of commits being checked in");
            }

            if (Quick)
            {
                string[] revList = null;
                repo.CommandOutputPipe(tr => revList = tr.ReadToEnd().Split('\n').Where(s => !String.IsNullOrWhiteSpace(s)).ToArray(),
                                       "rev-list", "--parents", "--ancestry-path", "--first-parent", "--reverse", tfsLatest + "..HEAD");

                string currentParent = tfsLatest;
                foreach (string commitWithParents in revList)
                {
                    string[] strs       = commitWithParents.Split(' ');
                    string   target     = strs[0];
                    string[] gitParents = strs.AsEnumerable().Skip(1).Where(hash => hash != currentParent).ToArray();

                    string commitMessage = repo.GetCommitMessage(target, currentParent).Trim(' ', '\r', '\n');
                    var    commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, commitMessage);

                    _stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
                    long newChangesetId = tfsRemote.Checkin(target, currentParent, parentChangeset, commitSpecificCheckinOptions);
                    tfsRemote.FetchWithMerge(newChangesetId, gitParents);
                    if (tfsRemote.MaxChangesetId != newChangesetId)
                    {
                        throw new GitTfsException("error: New TFS changesets were found. Rcheckin was not finished.");
                    }

                    currentParent   = target;
                    parentChangeset = new TfsChangesetInfo {
                        ChangesetId = newChangesetId, GitCommit = tfsRemote.MaxCommitHash, Remote = tfsRemote
                    };
                    _stdout.WriteLine("Done with {0}.", target);
                }

                _stdout.WriteLine("No more to rcheckin.");
                return(GitTfsExitCodes.OK);
            }
            else
            {
                while (true)
                {
                    // determine first descendant of tfsLatest
                    string revList = repo.CommandOneline("rev-list", "--parents", "--ancestry-path", "--first-parent", "--reverse", tfsLatest + "..HEAD");
                    if (String.IsNullOrWhiteSpace(revList))
                    {
                        _stdout.WriteLine("No more to rcheckin.");
                        return(GitTfsExitCodes.OK);
                    }

                    string[] strs       = revList.Split(' ');
                    string   target     = strs[0];
                    string[] gitParents = strs.AsEnumerable().Skip(1).Where(hash => hash != tfsLatest).ToArray();

                    string commitMessage = repo.GetCommitMessage(target, tfsLatest).Trim(' ', '\r', '\n');
                    var    commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, commitMessage);
                    _stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
                    long newChangesetId = tfsRemote.Checkin(target, parentChangeset, commitSpecificCheckinOptions);
                    tfsRemote.FetchWithMerge(newChangesetId, gitParents);
                    if (tfsRemote.MaxChangesetId != newChangesetId)
                    {
                        throw new GitTfsException("error: New TFS changesets were found. Rcheckin was not finished.");
                    }

                    tfsLatest       = tfsRemote.MaxCommitHash;
                    parentChangeset = new TfsChangesetInfo {
                        ChangesetId = newChangesetId, GitCommit = tfsLatest, Remote = tfsRemote
                    };
                    _stdout.WriteLine("Done with {0}, rebasing tail onto new TFS-commit...", target);

                    repo.CommandNoisy("rebase", "--preserve-merges", "--onto", tfsLatest, target);
                    _stdout.WriteLine("Rebase done successfully.");
                }
            }
        }
Example #6
0
        private int _PerformRCheckinQuick(TfsChangesetInfo parentChangeset, string refToCheckin)
        {
            var    tfsRemote = parentChangeset.Remote;
            var    repo      = tfsRemote.Repository;
            string tfsLatest = parentChangeset.Remote.MaxCommitHash;

            string[] revList = null;
            repo.CommandOutputPipe(tr => revList = tr.ReadToEnd().Split('\n').Where(s => !String.IsNullOrWhiteSpace(s)).ToArray(),
                                   "rev-list", "--parents", "--ancestry-path", "--first-parent", "--reverse", tfsLatest + ".." + refToCheckin);

            string currentParent  = tfsLatest;
            long   newChangesetId = 0;

            RCheckinCommit rc = new RCheckinCommit(repo);

            foreach (string commitWithParents in revList)
            {
                rc.ExtractCommit(commitWithParents, currentParent);
                rc.BuildCommitMessage(!_checkinOptions.NoGenerateCheckinComment, currentParent);
                string target = rc.Sha;
                string tfsRepositoryPathOfMergedBranch = FindTfsRepositoryPathOfMergedBranch(tfsRemote, rc.Parents, target);

                var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, rc.Message, rc.Commit);

                _stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
                try
                {
                    newChangesetId = tfsRemote.Checkin(target, currentParent, parentChangeset, commitSpecificCheckinOptions, tfsRepositoryPathOfMergedBranch);
                    var fetchResult = tfsRemote.FetchWithMerge(newChangesetId, false, rc.Parents);
                    if (fetchResult.NewChangesetCount != 1)
                    {
                        var lastCommit = repo.FindCommitHashByChangesetId(newChangesetId);
                        RebaseOnto(repo, lastCommit, target);
                        if (AutoRebase)
                        {
                            tfsRemote.Repository.CommandNoisy("rebase", "--preserve-merges", tfsRemote.RemoteRef);
                        }
                        else
                        {
                            throw new GitTfsException("error: New TFS changesets were found. Rcheckin was not finished.");
                        }
                    }

                    currentParent   = target;
                    parentChangeset = new TfsChangesetInfo {
                        ChangesetId = newChangesetId, GitCommit = tfsRemote.MaxCommitHash, Remote = tfsRemote
                    };
                    _stdout.WriteLine("Done with {0}.", target);
                }
                catch (Exception)
                {
                    if (newChangesetId != 0)
                    {
                        var lastCommit = repo.FindCommitHashByChangesetId(newChangesetId);
                        RebaseOnto(repo, lastCommit, currentParent);
                    }
                    throw;
                }
            }

            if (repo.IsBare)
            {
                repo.UpdateRef(refToCheckin, tfsRemote.MaxCommitHash);
            }
            else
            {
                repo.ResetHard(tfsRemote.MaxCommitHash);
            }
            _stdout.WriteLine("No more to rcheckin.");

            Trace.WriteLine("Cleaning...");
            tfsRemote.CleanupWorkspaceDirectory();

            return(GitTfsExitCodes.OK);
        }
Example #7
0
        private int _PerformRCheckinQuick(TfsChangesetInfo parentChangeset, string refToCheckin, IEnumerable <GitCommit> commitsToCheckin)
        {
            var    tfsRemote      = parentChangeset.Remote;
            string currentParent  = parentChangeset.Remote.MaxCommitHash;
            long   newChangesetId = 0;

            foreach (var commit in commitsToCheckin)
            {
                var    message = BuildCommitMessage(commit, !_checkinOptions.NoGenerateCheckinComment, currentParent);
                string target  = commit.Sha;
                var    parents = commit.Parents.Where(c => c.Sha != currentParent).ToArray();
                string tfsRepositoryPathOfMergedBranch = FindTfsRepositoryPathOfMergedBranch(tfsRemote, parents, target);

                var commitSpecificCheckinOptions = _checkinOptionsFactory.BuildCommitSpecificCheckinOptions(_checkinOptions, message, commit);

                _stdout.WriteLine("Starting checkin of {0} '{1}'", target.Substring(0, 8), commitSpecificCheckinOptions.CheckinComment);
                try
                {
                    newChangesetId = tfsRemote.Checkin(target, currentParent, parentChangeset, commitSpecificCheckinOptions, tfsRepositoryPathOfMergedBranch);
                    var fetchResult = tfsRemote.FetchWithMerge(newChangesetId, false, parents.Select(c => c.Sha).ToArray());
                    if (fetchResult.NewChangesetCount != 1)
                    {
                        var lastCommit = _globals.Repository.FindCommitHashByChangesetId(newChangesetId);
                        RebaseOnto(lastCommit, target);
                        if (AutoRebase)
                        {
                            tfsRemote.Repository.CommandNoisy("rebase", "--preserve-merges", tfsRemote.RemoteRef);
                        }
                        else
                        {
                            throw new GitTfsException("error: New TFS changesets were found. Rcheckin was not finished.");
                        }
                    }

                    currentParent   = target;
                    parentChangeset = new TfsChangesetInfo {
                        ChangesetId = newChangesetId, GitCommit = tfsRemote.MaxCommitHash, Remote = tfsRemote
                    };
                    _stdout.WriteLine("Done with {0}.", target);
                }
                catch (Exception)
                {
                    if (newChangesetId != 0)
                    {
                        var lastCommit = _globals.Repository.FindCommitHashByChangesetId(newChangesetId);
                        RebaseOnto(lastCommit, currentParent);
                    }
                    throw;
                }
            }

            if (_globals.Repository.IsBare)
            {
                _globals.Repository.UpdateRef(refToCheckin, tfsRemote.MaxCommitHash);
            }
            else
            {
                _globals.Repository.ResetHard(tfsRemote.MaxCommitHash);
            }
            _stdout.WriteLine("No more to rcheckin.");

            Trace.WriteLine("Cleaning...");
            tfsRemote.CleanupWorkspaceDirectory();

            return(GitTfsExitCodes.OK);
        }