Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell git branch name from commit hash?

Tags:

git

bash

I have a bash script which accepts a string of either a branch name (e.g., "master", or "feature/foo") or a commit hash (e.g. "1234abcd").

I have the repository checked out, so I can call git.

What is the best way to determine whether the string is a branch name or a commit hash?

#!/bin/bash
commit_or_branch="$1"
cd /path/to/my_repo
git fetch
if <is_branch $commit_or_branch>
then
    echo "it's a branch"
else
    echo "it's a commit"
fi
like image 632
k107 Avatar asked Apr 17 '15 18:04

k107


People also ask

How do you pull from a commit hash?

To pull up a list of your commits and their associated hashes, you can run the git log command. To checkout a previous commit, you will use the Git checkout command followed by the commit hash you retrieved from your Git log.

How do I find my branch hash?

Retrieving the hash If you want to turn references (branches and tags) into hash, you can use git show-ref and git for-each-ref commands. Using the git reflog command is also used if you want to have the history on the head of your branches.


2 Answers

If you would like a robust mechanism to tell relative names (e.g. you SHA1 is possibly one or so commits behind a named branch), you can use git name-rev to resolve it.

Examples:

$ git config remote.upstream.url
https://github.com/RobotLocomotion/drake.git

$ git log --oneline -n 5
7530a95 Merge pull request #5743 from soonho-tri/pr-reformat-mathematical_program
ebc8f25 Suppresses console output of speed_bump.obj genrule. (#5726)
d8b9a0b Merge pull request #5735 from david-german-tri/namespaces
79e10e8 Remove redundant 'symbolic::' prefix from mathematical_program code
b68b590 Clean up mathematical_program code by adding using std::*

$ git name-rev HEAD
HEAD master
$ git name-rev 79e10e8
79e10e8 master^2
$ git name-rev HEAD~20
HEAD~20 remotes/origin/issue/5646_return_binding~3

Reference: Git Tips (old commit)

UPDATE: As @kporter mentioned, there is also the --name-only flag (with new commits as of 2020/04/21):

$ git name-rev HEAD
HEAD tags/last_sha_with_original_matlab~313
$ git name-rev --name-only HEAD~20
tags/last_sha_with_original_matlab~333

Command-Line Reference: git name-rev

like image 136
Eric Cousineau Avatar answered Sep 20 '22 15:09

Eric Cousineau


You can use git show-ref:

git show-ref --head | grep refs

If it is empty, it is a SHA1 (or an invalid object, which isn't good).
If not, it is a branch name.


A better technique comes from "Validate if commit exists", using git merge-base:

A branch name will result in a different string (the SHA1)

C:\Users\vonc\prog\b2d>git merge-base master master
de4accfd28c5f25fcc057d56996b83450be5dc60

a SHA1 will result in the same result (or at least starts with the same result):

C:\Users\vonc\prog\b2d>git merge-base 03949c3d3f88a378c6a08e57daa97059b52813f1 03949c3d3f88a378c6a08e57daa97059b52813f1
03949c3d3f88a378c6a08e57daa97059b52813f1

foobar will fail:

C:\Users\vonc\prog\b2d>git merge-base xxx xxx
fatal: Not a valid object name xxx

That means something like:

if [[ git merge-base $string $string ]]; then
  if [[ $(git merge-base $string $string) == $string* ]]; then
    echo "SHA1"
  else
    echo "branch"
  fi
else
  echo "Not a valid object name '$string'"
fi
like image 21
VonC Avatar answered Sep 17 '22 15:09

VonC