2

I've resolved some conflicts and committed a merge. Is it possible to restore exactly the merge state that was before running git commit, not changing the index or the working tree? For regular single-parent commits, the command which does this is git reset --soft HEAD^, but for merge commits it doesn't work as expected, because there is no single parent to reset to.

lizarisk
  • 7,562
  • 10
  • 46
  • 70
  • Possible duplicate of [Undo a Git merge that hasn't been pushed yet](http://stackoverflow.com/questions/2389361/undo-a-git-merge-that-hasnt-been-pushed-yet) – Josh Lee Feb 01 '17 at 15:33
  • 1
    Nope, I'm asking about something similar to `reset --soft` – lizarisk Feb 01 '17 at 15:41
  • Can you state your goal more precisely? It sounds like you fixed all the conflicts and committed, but realized you wanted to perform more changes? – Josh Lee Feb 01 '17 at 15:50
  • Yes, I'd like to get back to the merge state – lizarisk Feb 01 '17 at 15:51
  • It's not clear what precisely you're looking to do - what "merge state"? What you seem to be describing is the "merge conflict" state which has everything to do with the working tree and nothing to do with commits. – Pockets Feb 01 '17 at 19:48
  • This is a great resource straight from Github: [How to undo \(almost\) anything with Git](https://github.com/blog/2019-how-to-undo-almost-anything-with-git) – jasonleonhard Feb 03 '17 at 21:17

3 Answers3

2

You have a commit-sha for your merge state. Find the commit by git log or, git reflog command.

$ git reflog                       # copy the commit-sha of merge state
$ git reset --soft <commit-sha>

$ git status                       # see the undo changes

N.B. If you do --soft reset then the changes of the commits you back exists in your working directory.

Sajib Khan
  • 22,878
  • 9
  • 63
  • 73
  • I was asking about something similar to `reset --soft`, not `reset --hard` – lizarisk Feb 01 '17 at 15:40
  • you can do `--soft reset` here, in that case undo changes exists in your working directory. – Sajib Khan Feb 01 '17 at 15:47
  • I don't want to go back to a particular commit, I'd like to get back to the merge state. – lizarisk Feb 01 '17 at 15:50
  • Yes, you have a `commit-sha for merge`. By `git log` or `git reflog` you can see easily **"Merge branch '***' of...** similar commit message. Then copy the `commit-sha` and back to the merge state. – Sajib Khan Feb 01 '17 at 15:56
  • I'd like to do `blah; git commit` and re-create that merge commit. What you propose allows me to do `git commit --amend`, not create a new commit for the merge. – lizarisk Feb 01 '17 at 16:15
  • Using commit --amend will produce the same output and is easier. – Josh Lee Feb 01 '17 at 16:26
2

I don't think this is supported, but you can fake it by doing git reset --soft HEAD@{1} and then writing the commit id that you were merging to .git/MERGE_HEAD.

You'll lose the commit message, though ("Merge commit 'cafebab' into HEAD").

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
1

git reset --soft HEAD^ is a synonym for git reset --soft HEAD^1 which means reset softly to the first parent. If it is the second parent (second parent != grandparent, that would be HEAD~2) you want to reset to, use git reset --soft HEAD^2. Alternatively you can of course also do git reset --soft @{1} which means the first entry in the reflog of the current branch if the merge was the last thing you did.

Vampire
  • 35,631
  • 4
  • 76
  • 102
  • 1
    That won't take me back to the merge state. I'd like to be able to re-create that merge commit again. – lizarisk Feb 01 '17 at 15:50
  • Is maybe `git commit --amend` what you are really after? What do you want to achieve? Add some changes to the merge commit or resolve some conflict in another way, then `git commit --amend` definitely is what you are after. – Vampire Feb 01 '17 at 16:06