How do I change the author and author email for multiple commits?

Viewed 41

This was a problem I wanted to solve. When I searched up this question, I saw answers using git filter-branch and git filter-repo.

I can say with 100% confidence that git filter-branch is too slow and I don't like that it can change the same commit in multiple branches. Not a useful method.

Next is git filter-repo. It seems like a good solution but I'm using Ubuntu 20.04 LTS which doesn't seem to be supported. I would need to spend a little time to update to 22.04 LTS. So only useful on supported distros and versions.

Now here is my answer:

initialCommit=$(git log original-branch --format=format:"%h" | tail -1)
readarray -t commitsArray < <(git log original-branch --author="Original Author <originalauthor@email.com>" --format=format:"%h")
startCommitIndex=$(("${#commitsArray[@]}"-1))

git checkout -b new-branch "$initialCommit"
if [[ "$initialCommit" == "${commitsArray[$startCommitIndex]}" ]]; then
    git commit --amend --author "New Author <newauthor@email.com>"
    startCommitIndex=$(($startCommitIndex - 1))
fi
for (( commitIndex=$startCommitIndex; commitIndex >= 0; commitIndex-- )); do
    git cherry-pick "${commitsArray[$commitIndex]}"
    git commit --amend --author "New Author <newauthor@email.com>"
done

We learned that git commit --amend --author "New Author <newauthor@email.com>" modifies the latest commit, also known as the HEAD commit (git log -1 --format=format:"%h").

Regarding --format=format:"%h", we can retrieve a commit's hash in two ways:

  1. --format=format:"%H": A long hash. Retrieves the full hash of the commit (40 characters long).
  2. --format=format:"%h": A shortened version of the hash that uses the first 7 to 9 characters (length varies depending on history length). Git is smart enough to figure out what commit is meant with this hash.

The git cherry-pick command allows you to pick a commit's hash from any branch and drop the contents of that commit into another branch. This creates a new commit hash in the branch with those contents, which becomes a HEAD commit.

git checkout -b new-branch "$initialCommit" creates a new branch with $initialCommit becoming the HEAD commit.

In this way, we are able to change the author and author email for multiple commits (that we found with readarray -t commitsArray < <(git log original-branch --author="Original Author <originalauthor@email.com>" --format=format:"%h")).

Afterwards, we could choose to remove our original branch (git branch -D original-branch) and rename our new branch (git branch -m new-branch original-branch). Then if satisfied later decide to push our changes to GitHub, GitLab, or wherever your git project is stored in remotely. Done!

0 Answers
Related