Changing author/mail on specific commit/s

2019-09-26 09:19发布

问题:

I have a repository on bitbucket which is aligned with the online repository (origin), while using Atlassian Sourcetree as tool for managing it.

Let's say it has 20 commits.

Sourcetree for some reason haves its share of fun changing project settings and I wrongly pushed 2 commits (let's say commit 15 and 16 as some other coworker which uses the machine too.

I want to put my name and mail in those commits.

Let's imagine the tree like this (without branches, just master)

Commit number -> comment -> commit id -> author/mail

  • 18 -> commit comment blabla -> 29huh23 -> me me@mycompany.com
  • 17 -> commit 17 feature XYZ -> abs2881 -> me me@mycompany.com
  • 16 -> commit 16 feature KWZ -> anu2716 -> someone other@othercompany.com
  • 15 -> commit 15 feature IHZ -> 11suhs2 -> someone other@othercompany.com
  • 14 -> commit 14 feature UYZ -> 1uuhw87 -> me me@mycompany.com

someone other@othercompany.com should become me.

I'm admin on the repo.

How to do it in a simple way? It's possible from Sourcetree? Should I do it from the terminal?

Could it be a workable solution to manually modify files in the .git folder and create a new repo and commit there?

Question is not duplicate as suggeste duplicate answers does not work well.

EDIT - CORRECT PROCEDURE FOR ANYONE LOOKING HOW TO DO IT WITHOUT TOO MUCH RESEARCH

Since everyone is marking this as duplicate while is not, as other procedures are INCOMPLETE and leave someone (like me) who is not very cool with git with problems and questions, the correct procedure is:

From SourceTree, launch terminal with the terminal button on top right when the repo is open.

Then paste this and execute, with the substitutions suitable for your case

    #!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

This though, will produce a secondary "backup" branch, because when rewriting history, which left me with much doubts.

I had to do this additional step to remove the "backup" branch and actually push the new history to the repo and find the new history with correct name/mail:

git push --force --tags origin 'refs/heads/*'

Here the full guide.

Thanks to everyone who pointed me to the right direction.

回答1:

There is not a "simple" way to do this. The author and committer information are part of the commit; changing them changes the commit ID. Changing the commit ID means the subsequent commits' parent info has to change, and that changes those commit's IDs. In other words, to change it you need a history rewrite.

History rewrites are not particularly difficult to do, but they come with a significant cost when the affected commits have already been shared (or, maybe more precisely, when the "old" version of an affected commit would be removed from the already-shared history of a branch).

To do such a rewrite, it is necessary to coordinate with everyone else who has already received the "old" commits. I often hear people say this would be too burdensome, because of how many people have a repo. In that case, you can't afford to do the rewrite. If you ignore that advice, what will probably happen is someone else, trying to "fix" the error they receive, will undo your rewrite, and then you'll have a truly splintered repository that's of little use to anyone until an even bigger coordinated effort is completed to clean it up.

With all that said, if you still want to do a history rewrite just to clean up a few commits' email addresses, check out git filter-branch with the --env-filter option.