Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

git

People also ask

How do you find which branch a commit belongs to?

It is based on "Find merge commit which include a specific commit". Find when a commit was merged into one or more branches. Find the merge commit that brought COMMIT into the specified BRANCH(es). Specifically, look for the oldest commit on the first-parent history of BRANCH that contains the COMMIT as an ancestor.

How do you check the content of a commit?

If you want to see what's happened recently in your project, you can use git log . This command will output a list of the latest commits in chronological order, with the latest commit first.

How do we know if there is a git commit?

The most basic and powerful tool to do this is the git log command. By default, with no arguments, git log lists the commits made in that repository in reverse chronological order; that is, the most recent commits show up first.


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

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$'

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".)


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.