Eric
Eric

Reputation: 97601

How can I update SHA1s within commit messages after a rebase?

Consider this history:

E  BUG: fix regression in <sha-1 of C>
|
D  fixup! Do a thing
|
C  Add a feature
|
B  Do a thing
|
A  Initial commit

Is there a variant of git rebase -i --autosquash that will adjust the commit message of E to match the following?

E'  BUG: fix regression in <sha-1 of C'>
|
C'  Add a feature
|
BD' Do a thing
|
A   Initial commit

Upvotes: 2

Views: 95

Answers (1)

Mark Adelsberger
Mark Adelsberger

Reputation: 45689

I can't really think of an automated way. In an interactive rebase, you could mark commit E for either "reword" or "edit" and change the SHA yourself. (I think "edit" might be easier simply so that you could use log to find the correct SHA to fill in before kicking off the commit message editor.)

UPDATE

Bringing in some thoughts from the comments: If you're dealing with a rewrite of a large history with many such references, such that an interactive rebase with manual message edits is unrealistic, it's quite a lot harder to envision a solution.

While your question seems to focus on rebase, in comments you mention you might really be thinking of a filter-branch. (Which, it should be noted, is a very different operation, so that it's almost never easy to substitute one for the other...)

Your best bet in any case is to rewrite the commit messages in the same operation that caused the commit SHA values to change. (If you try to do it "after the fact", then the rewrite of a commit X's message will again change the SHA of not only X, but also any commits that reaches X via parent pointers; so you'll have to keep track of / work through multiple ID mappings at that point.)

In theory what you want is a msg-filter that does sed-type search-and-replace on the SHA values; but the trouble is where you get the "old sha to new sha" mapping.

There is a shell function map, which torek indicates can be of some help, at least from within the filter scripts. (The docs I found only confirm this to be available during execution of the commit-filter, but if torek says the other filters can see it then I'm inclined to think he's right. The question would be whether that might change in a future version, if indeed it's undocumented. If this worries you, you could shoe-horn the message edit into a commit filter, maybe...)

So you could write a script that looks at the old commit message (received on STDIN if you stick with msg-filter) and searches it for possible SHA values (strings of 40 characters in [0-9a-f]). On finding a possible value, it would call map and, if map returns what looks like a single SHA value, edit the message text. Then return the edited text on STDOUT. (But: I believe that will only work if you actually have the full 40-character SHA in your commit messages. If you abbreviate, that's another can of worms...)

(Note that map can return multiple SHA values, but the only case I've found for this is if you were doing something exotic with the commit-filter.)

Upvotes: 3

Related Questions