Search code examples
gitgit-merge

Git merge get source branch name after terminal window was closed


In Git how can I get the name of the source branch of a merge?

I started a merge yesterday, got conflicts which I did not finish resolving, then a windows update restarted my computer closing my terminal window.


Solution

  • TL;DR

    Look at the first line of .git/MERGE_MSG.

    Long-ish

    Per comment, we have the following situation:

    • Something—perhaps not you, or you'd probably remember what you did—ran git merge string.
    • This merge had conflicts, so it stopped in the middle of the merge.
    • Then, while you were working on that, something else did a machine restart (presumably safely but you lost context).
    • Additional Git commands may or may not have been run, but you are still in the middle of the conflicted merge.
    • You now want to get the string back.

    There is only one place that Git has saved the literal string, and that's in the MERGE_MSG file in the Git directory. If you have a typical setup and are in the top level of your work-tree, that's:

    $ cat .git/MERGE_MSG
    Merge branch 'A' into B
    
    # Conflicts:
    #   new-filename
    

    The first line will read:

    Merge branch 'string'
    

    or:

    Merge branch 'string' into <name>
    

    where name is the name of the branch you were on when the merge started. (The into <name> part is omitted if and only if <name> is the literal text master. This is one of the few places in Git where the name master gets special treatment: it changes the default merge message slightly.)

    If your Git directory (the repository proper) is somewhere else, use git rev-parse --git-dir to find it.

    The raw commit hash ID is easier to get:

    $ git rev-parse MERGE_HEAD
    243e415273b34b1553ce5eaeb6a189595d322015
    

    You can turn this into a set of branch names that point directly to this commit with git branch --points-at:

    $ git branch --points-at MERGE_HEAD
    

    but this may produce no names at all–e.g., if you ran git merge on a raw hash ID, or the branch name has been moved since then—or it might produce more than one name. So that first line of .git/MERGE_MSG is probably the place to look.

    Note, by the way, that you can view the commit(s) reachable from MERGE_HEAD with git log as usual:

    $ git log MERGE_HEAD
    

    This is sometimes a useful way to see what you are merging, depending on how many commits are on each "leg" of each branch:

    $ git log --decorate --oneline --graph --boundary MERGE_HEAD...HEAD
    

    With the repository I have been using, this produces:

    * 243e415 (A) modify renamed file too
    * 57b6097 rename in branch A
    | * c8d5dd8 (HEAD -> B) remove orig-filename
    |/  
    o 3a5c9ae (master) add orig-filename
    

    In this case, the visualization is probably sufficient, but in more complex graphs, adding --left-right may be helpful:

    $ git log --decorate --oneline --graph --left-right --boundary MERGE_HEAD...HEAD
    < 243e415 (A) modify renamed file too
    < 57b6097 rename in branch A
    | > c8d5dd8 (HEAD -> B) remove orig-filename
    |/  
    o 3a5c9ae (master) add orig-filename
    

    Note how "our" branch, HEAD aka B, is on the right of the three dots MERGE_HEAD...HEAD, and some commits are marked > because they are on our branch. "Their" branch, MERGE_HEAD aka A, are marked < because MERGE_HEAD is on the left of MERGE_HEAD...HEAD.

    (The --boundary option adjusts the set of commits included in the git log output so that we see the last commit here, in this case, on master. Without that this commit is excluded from the git log output.)