Search code examples
gitgit-filter-branch

How to change author of specific commits based on a predicate


All answers I see regarding this question (here, here) only ever offer ways to either change the most recent commit(s) or all commits, however I want to change the author of only past commits that match a certain predicate. I have looked at git filter-branch (deprecated), git-filter-repo (its replacement), and bfg, but can't figure out how to make this change.

The way I intuitively tried to approach this is:

  1. First find all commits that I'm trying to change.
  2. Change author of those commits.

I have other commits in the history with the same author that I do not want to change, I only want to change commits that match a certain predicate.

So for step 1, find all commits whose commit messages have a specific substring:

git log --pretty=format:'%H %s' | grep 'My Commit Message' | awk '{print $1}'

Then for step 2, I expected to be able to do something like:

step1command | xargs -I@ git commit --amend --author "New Name <name@email.com>" @

But it doesn't seem to be so simple. How should I go about this?

Thanks!


Solution

  • Thanks to @phd's help, I was able to figure out a working solution:

    git filter-branch --env-filter '
    if git show -s --format="%s" $GIT_COMMIT | grep "My commit message";
    then
        export GIT_AUTHOR_NAME="New Name"
        export GIT_AUTHOR_EMAIL="new@email.com"
    fi
    ' --tag-name-filter cat -- --branches --tags
    

    Then run git push -f to force change the existing commits in the remote repo.

    Note, this only changes the author name and email, not the committer. For that, you'd want to change GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL also, like in this answer.