Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: How to determine if a ref to a commit exists

Tags:

git

I need to find out if a ref to a commit exists. One thing that almost works is git show which sometimes returns non-zero if the ref does not exist. However, it also accepts paths within the current source tree. So if I have a file named master but the ref master does not exist, git show succeeds. I have not been able to find any more specific commands.

I would like the method to accept:

  • Names of branches
  • Commit hashes
  • Tags
  • Keywords like HEAD

Edit: I'm doing this because I want to preform sanity checks on user input programatically.

like image 534
timthelion Avatar asked Jan 06 '16 08:01

timthelion


1 Answers

You can use git rev-parse with the --verify flag to parse various refs and decode them to their SHA-1 hash value. This will get rid of all invalid refs and also file paths:

$ git rev-parse --verify HEAD
a93775d7fcd9bf27bbd89ee69e84a03e06223e9b
$ git rev-parse --verify HEAD~2
4100b19c32fac3e2c0838c85d180cd4f50500c2f
$ git rev-parse --verify master
e88352936f4ffc703cdfb0da95ad5592456feb0b
$ git rev-parse --verify origin/master
e88352936f4ffc703cdfb0da95ad5592456feb0b
$ git rev-parse --verify README.md
fatal: Needed a single revision
$ git rev-parse --verify doesnotexist
fatal: Needed a single revision

Note that this will unfortunately also accept other object types, e.g. trees:

$ git rev-parse --verify "HEAD^{tree}"
5fdca9a3c0db1e1414229a7b50dac20e4e87a3b8

What you can do is use git cat-file as this operates directly on Git’s object database. So it can only find objects that actually exist. It also parses any kind of revision argument you pass to it, so it can understand various references. By using the -t parameter, it will give you the type of the object you are passing. If that type is a commit, then whatever you passed is a valid way to specify an existing commit:

$ git cat-file -t HEAD
commit
$ git cat-file -t HEAD~2
commit
$ git cat-file -t master
commit
$ git cat-file -t origin/master
commit
$ git cat-file -t README.md
fatal: Not a valid object name README.md
$ git cat-file -t doesnotexist
fatal: Not a valid object name doesnotexist
$ git cat-file -t "HEAD^{tree}"
tree

So just check whether that returns commit and you seem to have a good way to verify whether a user input is a valid commit reference.

like image 109
poke Avatar answered Sep 21 '22 02:09

poke