Referencing the child of a commit in Git

Very probably not the fastest possible solution, but it does what I need:

#!/bin/bash

REV=$1

if [[ -z "$REV" ]]; then
    echo "Usage: git-get-child  []"
    exit
fi

HASH=$(git rev-parse $REV)

NUM=$2

if [[ -z "$NUM" ]]; then
    NUM=1
fi

git rev-list --all --parents | grep " $HASH" | sed -n "${NUM}s/\([^ ]*\) .*$/\\1/p"

The git rev-list --all --parents does exactly what I need: it iterates over all reachable commits, and prints the following line for each:

SHA1_commit SHA1_parent1 SHA1_parent2 etc.

The space in the grep expression ensures that only those lines are found where the SHA1 in question is a parent. Then we get the nth line for the nth child and get the child's SHA1.


The above method using git rev-list --all considers all available commits, which can be a lot and is often not necessary. If the interesting child commits are reachable from some branch, the number of commits that a script interested in child commits needs to process can be reduced:

branches=$(git branch --contains $commit| grep -v '[*] ('| sed -e 's+^..++')

will determine the set of branches that $commit is an ancestor of. With a modern git, at least version 2.21+, this should do the same without the need for sed (untested):

branches=$(git branch --format='%(refname:short)' --contains $commit| grep -v '[*] (')

Using this set, git rev-list --parents ^$commit $branches should yield exactly the set of all parent-child relationships between $commit and all branch heads that it is an ancestor of.

Tags:

Git