gitbashgit-plumbing

git scripting: How to list all git branches containing a commit


I can list all branches containing a certain commit using git branch --list --contains just fine. But as explained in the related question on how to list all branches, this is a porcelain command that should not be used in scripts.

The latter question suggests to use the plumbing command git for-each-ref, but that does not support --contains.

What is the correct plumbing interface to list all branches that contain a certain commit.


Solution

  • One possible solution using the plumbing commands git-for-each-ref and git merge-base (the latter suggested by Joachim himself):

    #!/bin/sh
    
    # git-branchesthatcontain.sh
    #
    # List the local branches that contain a specific revision
    #
    # Usage: git branchthatcontain <rev>
    #
    # To make a Git alias called 'branchesthatcontain' out of this script,
    # put the latter on your search path, and run
    #
    #   git config --global alias.branchesthatcontain \
    #       '!sh git-branchesthatcontain.sh'
    
    if [ $# -ne 1 ]; then
        printf "%s\n\n" "usage: git branchesthatcontain <rev>"
        exit 1
    fi
    
    rev=$1
    
    git for-each-ref --format='%(refname:short)' refs/heads | \
        while read ref; do
            if git merge-base --is-ancestor "$rev" "$ref"; then
                printf "%s\n" "$ref"
            fi;
        done
    
    exit $?
    

    The script is available at jub0bs/git-aliases on GitHub.

    (Edit: thanks to coredump for showing me how to get rid of that nasty eval.)