Given a commit id, how to determine if current branch contains the commit?

Solution 1:

There are multiple ways to achieve this result. First naive option is to use git log and search for a specific commit using grep, but that is not always precise

git log | grep <commit_id>

You are better off to use git branch directly to find all branches containing given COMMIT_ID using

git branch --contains $COMMIT_ID

The next step is finding out current branch which can be done since git 1.8.1 using

git symbolic-ref --short HEAD

And combined together as

git branch $(git symbolic-ref --short HEAD) --contains $COMMIT_ID

But the command above doesn't return true or false and there is a shorter version that returns exit code 0 if commit is in current branch OR exit code 1 if not

git merge-base --is-ancestor $COMMIT_ID HEAD

Exit code is nice, but as you want string true or false as answer you need to add a bit more and then combined with if from bash you get

if [ 0 -eq $(git merge-base --is-ancestor $COMMIT_ID HEAD) ]; then echo "true"; else echo "false"; fi

Solution 2:

Get a list of branch(es) that contains the specific commit.

# get all the branches where the commit exists
$ git branch --contains <commit-id>

Check if a branch has the specific commit.

# output the branch-name if the commit exists in that branch
$ git branch --contains <commit-id> | grep <branch-name>

Search the branch (say, feature) with exact matching.

$ git branch --contains <commit-id> | grep -E '(^|\s)feature$'

e.g. If you have 3 local branches called feature, feature1, feature2 then

$ git branch --contains <commit-id> | grep 'feature'

# output
feature
feature1
feature2

$ git branch --contains <commit-id> | grep -E '(^|\s)feature$'

# output
feature     

You can also search in both local and remote branches (use -a) or only in remote branches (use -r).

# search in both 'local' & 'remote' branches  
$ git branch -a --contains <commit-id> | grep -E '(^|\s)feature$'

# search in 'remote' branches  
$ git branch -r --contains <commit-id> | grep -E '(^|\s)feature$'

Solution 3:

Extracted comment by @torek as answer:

See the proposed duplicate for how to find all branches that contain a specified commit.

To find out if the current branch contains commit C, use the "plumbing" command git merge-base --is-ancestor. The current branch contains C if C is an ancestor of HEAD, so:

if git merge-base --is-ancestor $hash HEAD; then
    echo I contain commit $hash
else
    echo I do not contain commit $hash
fi

(Side note: in shell scripts, a command that exits zero is "true" while one that exits nonzero is "false".)

Solution 4:

Yeah another alternative:

git rev-list <branch name> | grep `git rev-parse <commit>`

This works best for me since it would also work on locally cached remote branches such as remotes/origin/master, on which git branch --contains won't work.

This covers more than OP's question about just "current branch" but I find it dumb to ask a "any branch" version of this question so I decide to post here anyway.

Solution 5:

To list local branches containing commit:

git branch --contains <commit-id>

and to list all branches, including remote only, containing commit:

git branch -a --contains <commit-id>

Similarly to check if commit is in particular branch:

git log <branch> | grep <commit_id>

and if branch does not exist locally prefix branch name with origin/