Toast
Toast

Reputation: 657

Edit old commit messages using LibGit2Sharp

Is it possible to edit the commit message of a commit that is not the latest one using libgit2sharp?

Upvotes: 0

Views: 780

Answers (1)

SushiHangover
SushiHangover

Reputation: 74209

The analogy to git filter-branch is Repository.Refs.RewriteHistory.

As an example, lets rewrite all commit messages that contain foo by replacing foo with StackoverFlow:

repo.Refs.RewriteHistory (new RewriteHistoryOptions {
    OnError = OnError, 
    OnSucceeding = OnSucceeding,
    CommitHeaderRewriter = c =>
    CommitRewriteInfo.From (c, c.Message.Replace ("foo", "StackOverflow")),
}, commitsToRewrite);   

Pre-rewrite:

git log --oneline
b859690 Commit foo 3
327f702 Commit foo 2
75ac0b8 Commit foo 1

Post-rewrite:

git log --oneline
dc156e3 Commit StackOverflow 3
587f6c3 Commit StackOverflow 2
894361f Commit StackOverflow 1

Note: As you will see in the above log output, the SHAs have changed, just as they would via git filter-branch so you will have to force any pushes to remotes...

I would highly recommend going through the test fixture FilterBranchFixture.cs as this is the best documentation of RewriteHistory and you will find the different rewrite classes, like rewriting parents of a commit, being used here and how errors are handled...

WARNING! The rewritten history will have different object names for all the objects and will not converge with the original branch. You will not be able to easily push and distribute the rewritten branch on top of the original branch. Please do not use this command if you do not know the full implications, and avoid using it anyway, if a simple single commit would suffice to fix your problem. (See the "RECOVERING FROM UPSTREAM REBASE" section in git-rebase(1) for further information about rewriting published history.)

Cut/Paste Example:

using System;
using LibGit2Sharp;

namespace gitrewrite
{

    class MainClass
    {
        private static bool succeeding;
        private static Exception error;

        public static void Main (string[] args)
        {
            var repo = new Repository ("/Users/sushi/code/XamTests/RepoTestBed");

            // Assuming you might pre-filter, but for this example take ALL commits
            var commitsToRewrite = repo.Commits;

            repo.Refs.RewriteHistory (new RewriteHistoryOptions {
                OnError = OnError, 
                OnSucceeding = OnSucceeding,
                CommitHeaderRewriter = c =>
                    CommitRewriteInfo.From (c, c.Message.Replace ("foo", "StackOverflow")),
            }, commitsToRewrite);   
        }

        private static Action OnSucceeding {
            get {
                succeeding = false;
                return () => succeeding = true;
            }
        }

        private static Action<Exception> OnError {
            get {
                error = null;
                return ex => error = ex;
            }
        }
    }
}

Upvotes: 3

Related Questions