gitgit-mergemerge-conflict-resolution

How to find out parent revisions of an in-progress merge?


I've started a merge, but it had conflicts which I've resolved, and now it's all staged ready for commit. I just want to double-check which parent revisions I've merged.

Things tried so far:

The last one is the only option that really kind of worked, except it only shows one of the parents of my uncommitted merge.

There's got to be a better way than git commit! How do I do this properly?


Solution

  • Note that, because the merge commit doesn't exist yet, you won't be able to use git log or git show with the %P format specifier (which corresponds to parent hashes) to access the parents of that future merge commit.

    Simple merge

    In case of a simple merge of one branch into another, you can run

    git log -n 1 --pretty=format:"%H"
    git log -n 1 --pretty=format:"%H" MERGE_HEAD
    

    which will print the full SHAs of

    respectively.

    Octopus merge

    If any conflict arises during an octopus merge, which involves merging more than one branch into another, Git will abort the merge; therefore, your question wouldn't normally apply to that case. As pointed out by Andrew in his comment, though, the --no-commit flag can be used to intentionally interrupt the merge, even if it's free of conflicts. However, in that case, running

    git log -n 1 --pretty=format:"%H" MERGE_HEAD
    

    will only print the SHA of one of the branches being merged in; it won't list the SHAs of all of those branches.

    Everything's not lost, though; there is a way of printing all of them. It turns out that the .git/MERGE_HEAD file contains the SHAs of all the branches being merged; therefore, a more robust approach consists in simply dumping the contents of that file:

    cat .git/MERGE_HEAD
    

    To fix ideas, here is a (voluntarily contrived) example of an interrupted octopus merge:

    # set things up
    $ mkdir test_octopuss
    $ cd test_octopuss
    $ git init
    
    # create an initial commit
    $ printf "foo\n" > README.md
    $ git add README.md
    $ git commit -m "add 'foo' in README"
    
    # create three different commits on branches whose tips count the root commit as parent
    $ printf "bar\n" >> README.md 
    $ git commit -am "add 'bar' in README"
    $ git checkout -b another master^
    $ printf "bar\n" >> README.md 
    $ git commit -am "add 'bar' in README"
    $ git checkout -b yetanother master^
    $ printf "bar\n" >> README.md 
    $ git commit -am "add 'bar' in README"
    
    # get our bearings
    $ git log --oneline --graph --all --decorate
    * 93e4667 (HEAD, yetanother) add 'bar' in README
    | * a114920 (another) add 'bar' in README
    |/  
    | * 7adc927 (master) add 'bar' in README
    |/  
    * bc400cd add 'foo' in README
    
    # merge using the --no-commit flag (to pretend that the merge failed)
    $ git merge --no-commit master another
    Trying simple merge with master
    Trying simple merge with another
    Automatic merge went well; stopped before committing as requested
    
    # the following command fails to list all the heads being merged in
    $ git log -n 1 --pretty=format:"%H" MERGE_HEAD
    7adc927d9f7a0c8864d0ff784c0c53b0ded00616
    
    # list of all the heads being merged in the current branch
    $ cat .git/MERGE_HEAD
    7adc927d9f7a0c8864d0ff784c0c53b0ded00616
    a114920072210417a1fa6c9b2b33b5729097ee93