Я искал то же самое и нашел этот вопрос. Спасибо, что спросили!
Однако я обнаружил, что ответы, которые я вижу здесь, не кажутся вполне ответами, которые вы просили (или которые я искал) - они, кажется, дают коммит G
вместо A
commit.
Итак, я создал следующее дерево (буквы назначены в хронологическом порядке), чтобы я мог проверить вещи:
A - B - D - F - G <- "master" branch (at G)
\ \ /
C - E --' <- "topic" branch (still at E)
Это выглядит немного иначе, чем у вас, потому что я хотел убедиться, что получил (ссылаясь на этот график, а не ваш) B, но не A (и не D или E). Вот буквы, прикрепленные к префиксам SHA и сообщениям о коммитах (мой репо можно клонировать с здесь , если это кому-нибудь интересно):
G: a9546a2 merge from topic back to master
F: e7c863d commit on master after master was merged to topic
E: 648ca35 merging master onto topic
D: 37ad159 post-branch commit on master
C: 132ee2a first commit on topic branch
B: 6aafd7f second commit on master before branching
A: 4112403 initial commit on master
Итак, цель : найти B . Вот три способа, которые я нашел после небольшого переделывания:
1. визуально, с гитком:
Вы должны визуально увидеть такое дерево (если смотреть с мастера):
или здесь (если смотреть в тему):
в обоих случаях я выбрал коммит, равный B
в моем графике. После того, как вы щелкнете по нему, его полный SHA будет представлен в поле ввода текста чуть ниже графика.
2. визуально, но с терминала:
git log --graph --oneline --all
(Редактировать / примечание: добавление --decorate
также может быть интересным; оно добавляет указание имен веток, тегов и т. Д. Не добавляя это в командную строку выше, так как вывод ниже не отражает его использование.)
, который показывает (при условии git config --global color.ui auto
):
Или прямым текстом:
* a9546a2 merge from topic back to master
|\
| * 648ca35 merging master onto topic
| |\
| * | 132ee2a first commit on topic branch
* | | e7c863d commit on master after master was merged to topic
| |/
|/|
* | 37ad159 post-branch commit on master
|/
* 6aafd7f second commit on master before branching
* 4112403 initial commit on master
в любом случае мы видим коммит 6aafd7f как самую низкую общую точку, то есть B
на моем графике или A
на вашем.
3. С магией раковины:
Вы не указываете в своем вопросе, хотели ли вы что-то подобное выше, или единственную команду, которая просто даст вам одну ревизию, и больше ничего. Ну, вот последнее:
diff -u <(git rev-list --first-parent topic) \
<(git rev-list --first-parent master) | \
sed -ne 's/^ //p' | head -1
6aafd7ff98017c816033df18395c5c1e7829960d
Который вы также можете вставить в ~ / .gitconfig как (примечание: конечный тире важен; спасибо Брайан за то, что вы обратили на это внимание) :
[alias]
oldest-ancestor = !zsh -c 'diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne \"s/^ //p\" | head -1' -
Что можно сделать с помощью следующей (свернутой в кавычки) командной строки:
git config --global alias.oldest-ancestor '!zsh -c '\''diff -u <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | sed -ne "s/^ //p" | head -1'\'' -'
Примечание: zsh
могло бы с таким же успехом быть bash
, но sh
будет не работать - синтаксис <()
не существует в vanilla sh
. (Еще раз спасибо, @conny, за то, что сообщили мне об этом в комментарии к другому ответу на этой странице!)
Примечание: альтернативная версия выше:
Благодаря liori для , указывающим , что вышеупомянутое может упасть при сравнении идентичных ветвей, и появлению альтернативной формы diff, которая удаляет форму sed из смеси, и делает это «безопаснее» (т. е. возвращает результат (а именно, самый последний коммит) даже при сравнении мастера с мастером):
В виде строки .git-config:
[alias]
oldest-ancestor = !zsh -c 'diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1' -
Из скорлупы:
git config --global alias.oldest-ancestor '!zsh -c '\''diff --old-line-format='' --new-line-format='' <(git rev-list --first-parent "${1:-master}") <(git rev-list --first-parent "${2:-HEAD}") | head -1'\'' -'
Итак, в моем тестовом дереве (которое некоторое время было недоступно, извините, оно вернулось), теперь оно работает как для мастера, так и для темы (давая коммиты G и B соответственно). Еще раз спасибо, Лиори, за альтернативную форму.
Итак, вот что я [и liori] придумали. Кажется, это работает для меня. Он также допускает дополнительную пару псевдонимов, которые могут оказаться полезными:
git config --global alias.branchdiff '!sh -c "git diff `git oldest-ancestor`.."'
git config --global alias.branchlog '!sh -c "git log `git oldest-ancestor`.."'
Удачи!