There isn't; but, using git rev-list
and then further work, it would be possible to find items that point back to a given commit. You must first choose some starting point (probably --all
), then exclude the target rev and its parents:
git rev-list --all --not rev
This of course produces a long list of revs, many of which are uninteresting, so it needs further filtering: you want those where a parent of the rev is rev
.
This shell script (with no error checking etc) only handles first-parent:
target=$(git rev-parse $1)
git rev-list --all --not $target |
while read rev; do
if [ $(git rev-parse --verify --quiet $rev^) = $target ]; then
echo $rev
fi
done
but it should be pretty obvious how to fancy it up from there (see the documentation for git rev-list
). Use:
git rev-list -1 --parents $rev
to turn a single rev into a list of "the rev and its parents", for merges, e.g.:
set -- $(git rev-list -1 --parents $rev)
shift # discard the rev itself
echo there are $# parents and they are $*
for parent do
if [ $parent = $target ]; then
echo $rev has $target as a parent
fi
done
Edit: in a large repo, you can get a better starting point with git branch --contains
(as noted by RainerBlome in "referencing the child of a commit". Note that you need to parse away the *
indicating current branch, and if you have HEAD "detached" the "current branch" is "no branch" and you might want to add HEAD
as a starting point. Then, git rev-list --parents | grep ...
is a quick way to find desirable refs. I've used these suggestions to improve performance, etc.
Here's a complete script, with some error checking too; lightly tested.
#! /bin/sh
#
# git-rev-list-children.sh
find_branches()
{
local target="$1"
set -- $(git branch --contains $target |
sed -e 's/^\* (.*)/HEAD/' -e 's/^[* ] //')
case $# in
0) echo "there are no branches containing $revname"; return 1;;
esac
echo $@
}
find_children()
{
local target="$1"
shift
git rev-list --parents "$@" ^$target | grep " $target" |
while read line; do
set -- $line
echo $1
done
}
# add option parsing (--short?) here if desired
case $# in
0) echo "usage: git-rev-list-children <rev> ..." >&2; exit 1;;
esac
for revname do
target=$(git rev-parse "$revname") || exit 1
set -- $(find_branches "$revname" || exit 1)
find_children "$target" "$@"
done