How can I list all branches that are ancestors of a commit?
I want to see all branches that are ancestors of commit abcdef1234
.
This is sort of the inverse of:
git branch --contains abcdef1234
The above command would list all branches that are descendants of abcdef1234
. I want to see a list of all branches that are ancestors of abcdef1234
.
I am also interested the equivalent for tags.
UPDATE
To be extra clear, I mean I want to see a list of all commits that meet 2 criteria:
abcdef1234
Obviously most commits at some point had a branch pointing to them when they were brand new. I am only interested in whether they are branches at this particular moment.
git branch --merged abcdef1234
should do what you want. It lists all branches that are merged into the named commit (and thus are ancestors of it), ie those whose tip commits are reachable from the named commit.
Here's what I suggested as a comment, in expanded form. (I think this is what you're asking for.)
We set K to your chosen commit ( abcdefg1234
in your example). Then, we want to iterate through all labels L where L has the form refs/heads/*
or refs/remotes/*
(all branches and remote-tracking branches). Each label L points to some specific commit C. If C is an ancestor of K, print label L.
[ Edit : as sschuberth answered, this is just git branch --merged
; the new feature I was thinking of is that git for-each-ref
also now implements --merged
, which means you can script things more easily, but if all you want is the names, git branch
does it. If you do want tags, see git tag --merged
, if available. If your version of Git is too old, read on to the script. :-) ]
Here is a shell script (untested!) that implements this. Note that git for-each-ref
has new capabilities in later versions of Git that would simplify this, but this should work all the way back to 1.6-ish—maybe 1.7-ish; I forget when git merge-base
acquired --is-ancestor
.
#! /bin/sh
# find branches and remote-tracking branches that targt
# ancestors of $1.
showthem() {
local tgt label lbltgt
tgt=$(git rev-parse "$1") || return $?
git for-each-ref --format='%(refname:short) %(objectname)'
refs/heads refs/remotes |
while read label lbltgt; do
if git merge-base --is-ancestor $lbltgt $tgt; then
echo "$label"
fi
done
return 0
}
case $# in
0) usage 1>&2; exit 1;;
1) showthem "$1";;
*) for i do "echo ${i}:"; showthem "$i" || exit; done
esac
(You may want to tweak this slightly, eg, to discard symbolic refs like origin/HEAD
.)
comm -23 <(git branch -a | sort) <(git branch -a --contains abcdefg1234 | sort)
This will give you all the branches that do not have commit abcdefg1234
; it's the output of git branch -a
minus the output of git branch -a --contains abcdefg1234
.
上一篇: 混帐清理旧分支
下一篇: 我如何列出作为提交祖先的所有分支?