Определить коммиты, введенные в ветвь, путем слияния в git?
Я пытаюсь определить коммиты, введенные в родительскую ветку из-за слияния, используя идентификатор слияния.
3 ответа
TL;DR
Используйте ответ max630, если это настоящее слияние. Чтобы исключить само слияние, используйте его небольшой вариант: M^1..M^2
,
Долго
Здесь вы просите найти коммиты, которые стали доступны в результате слияния. Эта идея достижимости является концепцией теории графов. Таким образом, если вы нарисуете результат слияния, ответ будет более понятным.
Найти базы слияния
Предположим, что график "до слияния" выглядит так, где *
это фиксация базы слияния и L
а также R
левый и правый боковой кончик фиксирует:
...--*--...--L <-- mainline
\
o--...--R <-- sidebranch
Тогда график "после слияния" выглядит так:
...--*--...--L---M <-- mainline
\ /
o--...--R <-- sidebranch
Вновь введенные коммиты, теперь, очевидно,:-) те, которые находятся в нижнем ряду, то есть те, которые доступны из (и включая) R
, но исключая фиксацию базы слияния. Мы достигаем их, начиная со второго родителя M
, который R
, затем работает по обратной связи от R
его родителю, другому родителю и так далее. Это приводит к дну o
узел, который подключается обратно для фиксации *
,
Если у вас есть имя как sidebranch
указывая на R
Вам нужно только найти базу слияния:
mb=$(git merge-base $all mainline^1 sidebranch)
который использует синтаксис "первый родитель коммита" для идентификации коммита L
от коммита M
: ^1
суффикс. Если у вас больше нет имени sidebranch
Вы можете определить совершить R
используя синтаксис "второй родитель коммита":
mb=$(git merge-base $all mainline^1 mainline^2)
К сожалению, это не единственный возможный входной граф. Довольно типично иметь график "до слияния", который выглядит следующим образом:
...--* <-- mainline
\
o--...--R <-- sidebranch
Бег git merge
без --no-ff
выполнит операцию "ускоренной перемотки вперед", которая на самом деле не является слиянием: в результате вы получите линейный граф, а не слияние:
...--*--o--...--R <-- mainline, sidebranch
Здесь, если у вас еще нет записи reflog для основной ветки, найти коммит буквально невозможно *
, Если у вас есть запись reflog, она тривиальна: mainline@{number}
, используя соответствующие number
, (Нахождение подходящего number
это вопрос просмотра рефлога, чтобы найти обновление от ускоренной перемотки вперед. Если вы только что сделали слияние, это просто 1
а также HEAD@{1}
.)
mb=$(git rev-parse mainline@{1}) # for instance
Причину я поставил $all
В приведенном выше примере команды для поиска базы слияния есть еще одна третья возможность, когда у вас есть несколько баз слияния:
...--o--*---o--...--L
\ /
X
/ \
...--o--*---o--...--R
Здесь вы хотите исключить все базы слияния. замещать $all
с --all
если необходимо.
Теперь у вас есть все необходимое
Теперь, когда вы знаете базу (ы) слияния, найдя их с git merge-base
если слияние было реальным слиянием, коммиты, которые были сделаны достижимыми слиянием, являются просто теми, которые достижимы из R
сам, но не из базы (ов) слияния:
git rev-list sidebranch --not $mb
использование git log
скорее, чем git rev-list
если вы хотите проверять коммиты, а не просто перечислять их.
Упрощая это
Все вышеперечисленное предназначено для нахождения базы (слияний) слияния и исключения их, чтобы мы получили коммит R
и его достижимые предки без получения какого-либо коммита L
, Но нам не нужно начинать это исключение конкретно с базы слияния. Мы можем просто начать это с L
сам.
Называть L
нам просто нужно назвать предыдущее значение mainline
или первый родитель слияния M
, Первый родитель M
является M^1
или же M~1
, так что пока мы знаем хэш-идентификатор M
мы можем просто добавить суффикс и сказать "исключить это".
Для этого есть даже краткий синтаксис. Вместо:
git rev-list M^2 --not M^1
или немного короче:
git rev-list M^2 ^M^1
мы можем использовать синтаксис из двух точек:
git rev-list M^1..M^2
что у нас наверху.
Обратите внимание, что все это предполагает "реальное слияние": если слияние было ускоренным, вы должны вместо этого использовать reflog.
Команда git log <id>~1..<id>
отобразит список всех слитых коммитов, а сам коммит слился.
Вы можете оформить ветку и использовать git log для просмотра коммитов и Id коммитов в ветке. git log -n10 --oneline
даст вам историю предыдущих 10 коммитов в этой ветке.