Phil Evans
Phil Evans

Reputation: 920

Can I restrospectively add a message to a git merge

I just did a branch merge on git, to update my (allegedly) frozen branch of a specific code run. Because I am an idiot, I forgot to add '-m message' on the cmd line (so used to git commit prompting). i.e. I did:

git checkout frozenBranch
git merge liveBranch

And of course this now means that the last commit message for 'frozenBranch' is the latest 'liveBranch' commit message; whereas what I really wanted was the last commit for 'frozenBranch' to read something like "merged to the livebranch on 2019Feb8; this is the version used to propduce the V2.1 data release"

Is there a way to retroactively add a log message to a merge? I can see how to edit a message for a normal commit, not for a merge.

If not I guess I can check out frozenBranch, make some trivial change, commit and re-merge, but this is a little inelegant!

Upvotes: 3

Views: 472

Answers (2)

mtraceur
mtraceur

Reputation: 3736

The best way I've got so far is to

  1. reset the branch back to the commit before the merge,
    $ git reset --hard "${commit_before_merge}"
    
    then
  2. merge again, this time with fast-forward turned off:
    $ git merge --no-ff "${branch_you_merged_from)"
    

One cool bonus is that this just adds a merge commit to the history, it doesn't replace any commits, so you don't have to force push and no one else has to deal with you breaking pulls for them.

Example

So let's say you just merged branch live-branch into frozen-branch, and it was a fast forward of four (4) commits. Then you can type:

# Take your current branch four commits back:
$ git reset --hard HEAD~4

# Merge again, this time forcing a merge commit:
$ git merge --no-ff live-branch

Tips and Tricks

You can use git log to find the commit you fast-forwarded from, and either grab the hash or count how many commits ago it was.

Or, if you still have the output from the git merge command that did the fast-forward, it currently starts like this:

$ git merge live-branch
Updating 0850cf3..491e984
Fast-forward

and conveniently, that first abbreviated commit hash is the starting commit that you want to reset to:

$ git reset --hard 0850cf3

If you already deleted the branch you merged from, you can just re-create it from the merged-into branch first:

git branch --delete live-branch  # oops

# no worries, since the merge was a fast-forward, you can
# remake the branch and it has exactly the same history:
git branch live-branch

# now do the steps described earlier:
git checkout HEAD~4
git merge --no-ff live-branch

If you deleted the branch locally but not remotely, you can also just recreate it like this:

git branch live-branch origin/live-branch

(this example assumes you're using the defaults of having the remote repository named origin and of the branch having same name remotely as locally).

If you just did the merge (more precisely, if it was the last Git operation that changed what commit your branch head is on), you don't need to count/remember the number of commits you merged - you can just use HEAD@{1} to refer to the commit you were on before the fast-forward:

git checkout HEAD@{1}
git merge --no-ff live-branch

More generally, just as you can use use ~NUMBER to go back NUMBER commits in the commit history, you can use @{NUMBER} to go back NUMBER commits in your "movements" through the commit history.

So you can use git reflog to find the right movement to go back to. For example, if you just finished working in live-branch, switched to frozen-branch, merged live-branch, switched to another-branch, realized you accidentally fast-forwarded and wanted to add that merge commit, and went back to frozen-branch, your reflog might start something like this:

491e984 (HEAD -> frozen-branch, live-branch) HEAD@{0}: checkout: moving from another-branch to main
00ae7c3 (another-branch, origin/another-branch) HEAD@{1}: checkout: moving from main to another-branch
491e984 (HEAD -> frozen-branch, live-branch) HEAD@{2}: merge live-branch: Fast-forward
0850cf3 HEAD@{3}: checkout: moving from live-branch to frozen-branch
491e984 (HEAD -> frozen-branch, live-branch) HEAD@{4} commit: Add epic live-branch feature
d2ffe45 HEAD@{4} commit: Fix bug in live-branch

So in our example, you would look for the line that's right before (under) merge live-branch: Fast-forward, because that's the commit you were on before the fast-forward merge happened - in this case, that's the HEAD@{3}: checkout: moving from live-branch to frozen-branch line, so you could use HEA@{3}. Once you're comfortable reading the reflog, it sometimes ends up being faster and easier than trying to count the merged commits or find the right commit hash.

Of course, if you didn't already push the fast-forwarded merge to frozen-branch, resetting is even easier:

git reset --hard origin/frozen-branch

(this example assumes you're using the default of having the remote repository named origin).

Upvotes: 1

Romain Valeri
Romain Valeri

Reputation: 22057

You can modify your last commit message (merge or not) with

git commit --amend -m "New message"

If you didn't push yet, perfect, you're set. If you did, you'll have to force push to update the old ref (check with your coworkers).

Upvotes: 1

Related Questions