How to determine if Git merge is in process

后端 未结 5 1484
轻奢々
轻奢々 2020-12-09 09:30

Is there a Git command that can be used to determine if a merge is in-process (i.e. uncommitted)? I know I can simply check for .git/MERGE_HEAD, but is this pr

相关标签:
5条回答
  • 2020-12-09 10:07

    Since MERGE_HEAD is only available during a merge and is also future-proof, we can simply use git rev-list -1 MERGE_HEAD (conveniently, a plumbing command) which will exit with code 128 if MERGE_HEAD is not found. Pipe stdout and stderr to /dev/null for a cleaner check. Or even better, use git rev-parse -q --verify MERGE_HEAD.

    0 讨论(0)
  • 2020-12-09 10:13

    You can safely check for the existence of MERGE_HEAD in your git directory[1] to determine whether there's a merge in progress. The MERGE_HEAD file contains the commit ids that are being merged in, that will be the nth parents of the committed merge. For example, if I try to merge branch br1 which is at c085e0c:

    > git merge --no-ff --no-commit br1
    Automatic merge went well; stopping before committing as requested
    
    > cat .git/MERGE_HEAD
    c085e0caa2598064bfde9cc6318bd2c73fee2371
    

    If you are doing an octopus merge, then you will see more than one commit id in this file (newline separated):

    > git merge --no-ff --no-commit br2 br3
    Fast-forwarding to: br2
    Trying simple merge with br3
    Automatic merge went well; stopping before committing as requested
    
    > cat .git/MERGE_HEAD
    69b0169b1cba60de86161b375f013c59ad9581d8
    99dad0187351d61ae8e88d49c96d7383f9e8fa6d
    

    Using MERGE_HEAD is actually how git clients determine whether there's a merge in progress. Some provide this insight through leaky abstractions:

    > git merge --abort
    fatal: There is no merge to abort (MERGE_HEAD missing).
    

    So checking for the presence of MERGE_HEAD is perfectly acceptable and is is as future proof as anything in software - meaning that any changes to git-merge would have to take compatibility with other git clients into account and would (hopefully!) gracefully transition and/or provide backward compatibility.

    [1] You can trust the existence of MERGE_HEAD much more than you can trust that .git is underneath your working directory. Somebody could use the --git-dir flag or the GIT_DIR environment variable.

    0 讨论(0)
  • 2020-12-09 10:14

    Another option would be to test for the presence of a .git/MERGE_MSG file.

    That is because, before 2.14.x/2.15 (Q3 2017), you can end up in a situation where you do not have .git/MERGE_HEAD, even though the merge is in progress.

    See commit 9d89b35, commit 8e6a6bb, commit 62dc42b (23 Aug 2017), and commit e2de82f (21 Aug 2017) by Michael J Gruber (mjg).
    (Merged by Junio C Hamano -- gitster -- in commit 6e6ba65, 27 Aug 2017)

    Killing "git merge --edit" before the editor returns control left the repository in a state with MERGE_MSG but without MERGE_HEAD, which incorrectly tells the subsequent "git commit" that there was a squash merge in progress.
    This has been fixed.

    After Git 2.14.x/2.15, that won't be the case anymore, and testing for .git/MERGE_HEAD will be enough.

    0 讨论(0)
  • 2020-12-09 10:16

    git status

    you can run git status

    git will tell you what happening in your repository.

    E.g. * conflicting files (unmerged files)

    0 讨论(0)
  • 2020-12-09 10:20

    One trick is to use a Git command that will fail if a merge is in progress. You can then check the return code of the command. You'll also want to make sure that the command will not affect your working copy or index in the event that it succeeds. While there are many commands that fall into this category, one that seems appropriate is

    git merge HEAD
    

    which returns a 128 code if a merge is in progress, but 0 otherwise. Note that when a merge is not in-process, this command will simply print Already up-to-date since you are just merging with yourself. So, for scripting purposes, you can do this (in BASH)

    git merge HEAD &> /dev/null
    result=$?
    if [ $result -ne 0 ]
    then
        echo "Merge in progress."
    else
        echo "Merge not in progress."
    fi
    

    Note that even with the --quiet flag of git merge, an in-process merge will still cause this command to print to the error stream. This is why I redirect its output to /dev/null.

    0 讨论(0)
提交回复
热议问题