Как я могу определить, является ли одно обязательство предком другой фиксации (или наоборот)?

Git представляет собой DAG снимков с каждым node на графике, представляющем фиксацию. Каждая фиксация может содержать "n".

Учитывая любые две коммиты, существует ли один, краткий способ распознать "порядок" этих двух в DAG. git rev-list представляется наиболее перспективным, но я не могу найти правильное заклинание.

В идеале, у меня было бы что-то вроде следующего

$ git related hash1 hash2
hash1 is ancestor of hash2

ИЛИ

hash2 is ancestor of hash1

ИЛИ

hash1 unrelated to hash2

ИЛИ

hash1 is equal to hash2

Ответ 1

Используйте git merge-base --is-ancestor <commit1> <commit2>

Существует несколько способов найти ответ на этот вопрос. Самое простое - использовать

git merge-base --is-ancestor <commit> <commit>

Из документации для git merge-base:

--is-ancestor

Проверьте, является ли первый <commit> предком второго <commit>, и выйдите со статусом 0, если true, или со статусом 1, если нет. Ошибки сигнализируются ненулевым статусом, который не равен 1.

Другие опции

git журнал с тройной точкой ... обозначение

Другой вариант - использовать git log и использовать трехточечную нотацию ..., чтобы сообщить Git, чтобы выводить объединение объединения ребенка, за вычетом установленного пересечения. В основном, это говорит вам, как набор коммитов расходится друг с другом:

$ git log --oneline --graph --left-right \
--first-parent --decorate <commit1>...<commit2>

Вышеупомянутая команда покажет вам коммиты, достижимые из commit1 или commit2, но не оба, то есть C1 UNION C2 - C1 INTERSECTION C2, в терминах заданных операций.

Если ни одно из них не является родителем другого, вы увидите, что ребенок совершает оба действия, но если один из них является предком другого, вы увидите только вывод для фиксации потомков, поскольку содержится предок на пути потомка и, таким образом, исключается из вывода.

Вы можете узнать больше о git log и трехзначной нотации из следующих ресурсов:

git branch --contains option

git -rev-list (1) кажется, что он может быть использован для ответа на этот вопрос. Другой способ - просто привязать метки временных ярлыков к коммиттам, которые вы хотите протестировать, а затем использовать параметр --contains для git branch:

git branch --contains <commit-to-test>

На выходе будут все ветки, которые содержат коммит где-то в своем дереве фиксации, поэтому, используя временную ветвь на другой фиксации, вы можете увидеть, является ли коммит, который вы тестируете, предком.

Из документации:

--contains [<commit>]

Только ветки списка, которые содержат указанный commit (HEAD, если не указано).

Ответ 2

Следующая оболочка script может сделать трюк:

if git rev-list $SHA1 | grep -q $SHA2 ; then echo "$SHA2 is ancestor of $SHA1"
elif git rev-list $SHA2 | grep -q $SHA1 ; then echo "$SHA1 is ancestor of $SHA2"
else echo "$SHA1 unrelated to $SHA2" ; fi

Или, чтобы аккуратно включить его в псевдоним git:

git config --global alias.related '!function git_related() { if git rev-list $1 | grep -q $2 ; then echo "$2 is ancestor of $1" ; elif git rev-list $2 | grep -q $1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'

Ответ 3

if   (( $(git rev-list $1..$2|wc -l) == 0 )); then echo "$2 is ancestor of $1"
elif (( $(git rev-list $2..$1|wc -l) == 0 )); then echo "$1 is ancestor of $2"
else echo "$1 and $2 are unrelated"
fi

Ответ 4

git log  --oneline -1  OLD_SHA..NEW_SHA

Iff это дает вам некоторый журнал, тогда OLD_SHA является родителем NEW_SHA.

Ответ 5

Чтобы построить на @helmbert отличный псевдоним git related, здесь версия, которая также принимает имена ветвей (или HEAD и т.д.) в качестве аргументов, а не просто выполняет идентификаторы:

git config --global alias.related '!function git_related() { commit1=`git log -n 1 --format="%h" $1` ; commit2=`git log -n 1 --format="%h" $2` ; if git rev-list $commit1 | grep -q $commit2 ; then echo "$2 is ancestor of $1" ; elif git rev-list $commit2 | grep -q $commit1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'