0

I have a project with large number of commits (more than 1000) merged from different branches. I need to change author's name of the first commit.

Tried to do it with

git rebase -i --root

Set "edit" near this commit. Then used

git commit --amend --author="Author Name <email@address.com>
git rebase --continue

And I get an unimaginable amount of merge conflicts... Too much to resolve them manually.

The first error is (if resolve it I get similar errors after):

CONFLICT (add/add): Merge conflict in README.md
Could not apply a03a0ce1... master # Merge branch 'master' into 'dev'

Tried to use --rebase-merges flag but got the same result.

Does anybody know why it happens? Any other ways to solve? Thanks!

Alina
  • 21
  • 3
  • 1
    You should have said `git rebase -i --root --keep-merges`. But even then you should expect merge conflicts, plus things will be insanely complicated and the computer will probably explode. Plus what's your plan if you ever succeed at this insane plan? You'll have to push with force and thus destroy the entire history for everyone else working on the project, and they won't be happy. Just leave the history alone, would be my advice. – matt Aug 26 '22 at 10:18
  • https://stackoverflow.com/a/750182/7976758 Found in https://stackoverflow.com/search?q=%5Bgit%5D+change+email+multiple+commits – phd Aug 26 '22 at 10:39
  • 1
    Yes, it's important for client, if I don'to do it, we'll need to clear all history by making a new project !) Thanks for reply. – Alina Aug 26 '22 at 11:41
  • 1
    Since every single commit in your history will be replaced by this action, one way or another, you _are_ effectively clearing all history and making a new project. – matt Aug 26 '22 at 12:57

2 Answers2

2

Seems like you have problems in old commits. Try this

git filter-branch command. It lets rewrite history, preserve all information (including original commit times or merge information) https://git-scm.com/docs/git-filter-branch

git filter-branch --env-filter '
WRONG_NAME="wrong author"
NEW_NAME="correct author"
NEW_EMAIL="email@mail.com"

if [ "$GIT_COMMITTER_NAME" = "$WRONG_NAME" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_NAME" = "$WRONG_NAME" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

(can use filter WRONG_NAME or WRONG_EMAIL here)

or this

Use a git-filter-repo tool https://github.com/newren/git-filter-repo

  1. Install git-filter-repo
  2. Create a fresh clone of your project.
  3. Check email of invalid author with git shortlog --email
  4. Create a file .mailmap with content NewName <new-email-address@new.com> <old-mail@mail.ru>
  5. Command git filter-repo --use-mailmap
Rusty Nail
  • 120
  • 1
  • 7
  • 2
    All very true, but rewriting deep history in a shared repo is still a terrible idea. – matt Aug 26 '22 at 10:20
  • @matt it's really not that bad if you're working with people who know what they're doing. But when you're doing stuff on the internet, *then* you're in for fun. – hobbs Aug 26 '22 at 12:47
  • @hobbs I still think, though, that no one who advises `filter-branch/repo` should omit the warning. – matt Aug 26 '22 at 12:56
2

If your intention is to change all mentions to a specific author (identified by a name or an email), you can go with @RustyNail's answer.


If your intention is to modify just a single commit at the beginning of your history :

you can use the git replace/git filter-repo --force trick, mentionned in git-filter-repo's documentation :

Parent rewriting

To replace $commit_A with $commit_B (e.g. make all commits which had $commit_A as a parent instead have $commit_B for that parent), and rewrite history to make it permanent:

git replace $commit_A $commit_B
git filter-repo --force

In your case :

  • create, as you did, a copy of the initial commit with the correct author:
git checkout <original-hash>
git commit --amend --author="Author Name <email@address.com>"

# use 'git replace' to replace the old commit with the new one:
git replace <original-hash> HEAD
  • run git filter-repo --force

The warning mentionned by @matt still holds : if your repository is shared with many users (e.g: your fellow developpers), it can be very tricky to have everyone sync their work correctly with the rewritten history.

LeGEC
  • 46,477
  • 5
  • 57
  • 104