29

Normally, when you rebase another author's commit with git, git adds a Commit: header with your name and email address. I have a situation where I don't want this to happen. I want the rebased commit to end up with the same SHA1 as it would have if the original author had done the equivalent rebase him/herself. Is this possible?

John
  • 27,926
  • 10
  • 75
  • 78
  • 2
    Even if you do this, the new commit will *not* have the same SHA1 as the original commit. The original commit contains: the "tree" containing all the files in your project, as they were at the time of the commit, the author name/email/date, the committer name/email/date, and a reference to the parent commit. When you rebase, you end up with a totally new commit, that just happens to have the same author information and a similar tree, but even if all that were exactly the same, it would have a new parent. So the SHA1 would change. – Tyler Apr 02 '11 at 05:50
  • Related (at least closely enough that I found this current question on Google while looking for the linked one): https://stackoverflow.com/q/4981126/5419599 – Wildcard Sep 22 '17 at 08:40

2 Answers2

31

All git commits have a committer field internally; you can see this by typing git cat-file commit HEAD immediately after committing something. As such you cannot erase it; you can only make it equal to the author field.

That said, you might be seeing git porcelain showing the commit field because the datestamp has changed. It's not possible to predict what someone else would get for the commit datestamp if they were rebasing, obviously, but you can alter it to be equal to the original commit timestamp, at least.

git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; git commit-tree "$@"' -- basecommit..HEAD

This will alter commits after basecommit, in the history of HEAD (including HEAD, not including basecommit), making their committer field identical to the author field in all respects. If the original author agrees to do the same thing, then you can get a consistent SHA1.

bdonlan
  • 214,833
  • 29
  • 259
  • 321
  • John: This is your answer. Go have a look at any commit you've made - you'll see committer information (name, email, date) there, identical to the author information. Not all methods of viewing commits show the committer date by default - try `gitk`, or `git log --pretty=full`. (or `fuller`, or even `raw`) – Cascabel Apr 02 '11 at 05:08
  • This worked flawlessly after a big rebase. I would feel better if it were writter with git filter-repo, though. Any experts out there? – Nei Neto Feb 26 '21 at 16:50
6

Try setting the environment variable GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL when rebasing (maybe also GIT_COMMITTER_DATE, too). (This will effect all commits created now, though.)

Paŭlo Ebermann
  • 71,139
  • 18
  • 140
  • 206
  • That doesn't work. It makes the value of the `Commit:` header identical to the `Author:` header. I want it removed entirely. – John Apr 02 '11 at 01:45
  • 2
    Make sure to only set those variables for that command to avoid affecting other commits: `GIT_COMMITER_NAME=... ... git rebase ...`. Otherwise just be sure to `unset` them after you're done! – Cascabel Apr 02 '11 at 05:16
  • @John: I think the `Commit:` header would be there always. More exactly, the raw commit has always an `author ...` and a `committer ...` header entry, even if those have the same value. Only some porcelain tools sometimes select to show only one or both. Use `git show-object ...` or `git cat-file -p ...` to see what is in the commit object. – Paŭlo Ebermann Apr 02 '11 at 15:38
  • @John: of course, bdonlan's answer says the same more clearly. – Paŭlo Ebermann Apr 02 '11 at 15:40
  • 1
    You're right -- once I set all of GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE to the appropriate values, the resulting SHA1 comes out the same as if the original author had done the same rebase on that date. – John Apr 05 '11 at 21:18