How to check if the commit exists in a Git repository by its SHA-1

前端 未结 4 1603
野的像风
野的像风 2020-12-10 00:10

In a similar topic Validate if commit exists they recommend:

git rev-list HEAD..$sha

If it exits without error code than the commit exists.

相关标签:
4条回答
  • 2020-12-10 00:46

    If you are sure that the sha are commits then cat-file -e can be used for example:

    if git cat-file -e $sha 2> /dev/null 
    then 
      echo exists 
    else 
      echo missing 
    fi
    

    This is pretty efficient as this is a built-in and doesn't do anything other than checking the sha exists:

    return !has_sha1_file(sha1);
    

    Otherwise if it is uncertain that the sha are commit objects you would need to determine the type as with the other answer using git cat-file -t. This is only slightly less performant as git would have to look at the file information. This isn't as costly as unpacking the whole file.

    0 讨论(0)
  • 2020-12-10 00:52
    git cat-file -e $sha^{commit}
    

    From git cat-file docs:

       -e
          Suppress all output; instead exit with zero status if <object> exists
          and is a valid object.
    

    This (1) shows that this is an intended use case for cat-file and (2) avoids the resources of actually outputting any commit contents.

    Appending ^{commit} ensures that the object is a commit (i.e. not a tree or blob) or -- as remram points out -- resolves to a commit.

    For example,

    if git cat-file -e $sha^{commit}; then
      echo $sha exists
    else
      echo $sha does not exist
    fi
    
    0 讨论(0)
  • 2020-12-10 00:54

    You can just run git cat-file -t $sha and check it returns "commit". You are right, you don't need to actually print the actual object for that...

    I'm not 100% sure that what goes on behind the scene is more efficient, though.

    test $(git cat-file -t $sha) == commit

    0 讨论(0)
  • 2020-12-10 01:06
    git rev-parse -q --verify "$sha^{commit}" > /dev/null
    

    From the git rev-parse docs:

       --verify
           Verify that exactly one parameter is provided, and that it can be turned into a raw 20-byte SHA-1 that can be used to access the object database. If so, emit it to the standard output; otherwise, error out.
    
           If you want to make sure that the output actually names an object in your object database and/or can be used as a specific type of object you require, you can add the ^{type} peeling operator to the parameter. For
           example, git rev-parse "$VAR^{commit}" will make sure $VAR names an existing object that is a commit-ish (i.e. a commit, or an annotated tag that points at a commit). To make sure that $VAR names an existing object of
           any type, git rev-parse "$VAR^{object}" can be used.
    
       -q, --quiet
           Only meaningful in --verify mode. Do not output an error message if the first argument is not a valid object name; instead exit with non-zero status silently. SHA-1s for valid object names are printed to stdout on
           success.
    

    As a bonus, if you don't suppress the output, you can get the full sha.

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