Все внутренние связи Git указывают назад, от дочернего элемента к родительскому:
A <-B <-C <-D
↖︎ [this is an up-and-left arrow, but it may not work in some fonts]
E <-F
Тем не менее, git rev-list
имеет возможность переворачивать ссылки при ходьбе по графику.Таким образом, вы можете перемещаться по графику от F
в обратном направлении, переворачивая каждую ссылку, чтобы составить список детей.Проблема в том, что только Git видит ссылки, по которым он переходит:
A-> B <-C <-D
↘︎ [this is a down-and-right arrow]
E-> F
Это означает, что даже при использовании опции git rev-list
, которая делает это (--children
), Git будет требоватьчто у B
есть один ребенок, а именно E
.Чтобы заставить Git утверждать, что у B
есть двое детей, E
и C
, вы должны начать с обоих F
и D
, чтобы git rev-list
шел от D
в C
в B
:
A-> B-> C-> D
↘︎ [this is a down-and-right arrow]
E-> F
Вы можете заставить Git запускаться со всех имен веток, используя --branches
, или со всех имен тегов, используя --tags
, или со всеми ссылками (включая такие, как refs/stash
) с использованием --all
.Добавьте --topo-order
к команде git rev-list
, и вы получите список коммитов и их потомков.Из этого списка вы захотите получить последний коммит, который приводит к F
, но также имеет несколько дочерних элементов.К сожалению, вывод от git rev-list
здесь все еще не очень полезен.Чтобы выполнить эту работу быстро, вы можете написать свой собственный считыватель графиков, в этом случае вы можете сделать свою собственную внутреннюю разметку и просто использовать git rev-list --parents --all
или аналогичный.
(Эта работа намного проще в Mercurial, хотя даже там это может все еще быть нетривиальным.)