Нужно найти список коммитов из веток B1-Bn которые слиты в ветку A, но не слиты в ветку C
Вот есть у нас такая система ветвлений. От основной ветки A мы создаём временные ветки B1, B2, B3, B4. А потом результат работы в этих ветках сливаем обратно в ветку А и в ветку C, которая параллельно живёт своей жизнью. Но вот бывает, что некоторые ветки (B2, B4 тут как пример) слить забывают.
Нужно получить список забытых комитов B2, B4, ну или А2, А4 из ветки A, дабы вытащить из них авторов и напомнить, что не надо забывать про ветку C
Вот пример проекта:
И вот что выходит:
>git log --oneline
f337859 (HEAD -> BranchA) A4 Merge branch 'BranchB4' into BranchA
bb2909f (BranchB4) B4
fa9365d A3 Merge branch 'BranchB3' into BranchA
bec4444 (BranchB3) B3
e2c4548 A2 Merge branch 'BranchB2' into BranchA
45145d0 (BranchB2) B2
ccb3d92 A1 Merge branch 'BranchB1' into BranchA
adf7ccd (BranchB1) B1
ef347fc (master) A0
>git log --oneline --no-merges BranchB1 BranchB2 BranchB3 BranchB4 ^BranchA
bb2909f (BranchB4) B4
bec4444 (BranchB3) B3
45145d0 (BranchB2) B2
adf7ccd (BranchB1) B1
ef347fc (master) A0
>git log --oneline --no-merges BranchB1 BranchB2 BranchB3 BranchB4 ^BranchC
bb2909f (BranchB4) B4
b6adf20 (BranchC) C3.1
bec4444 (BranchB3) B3
45145d0 (BranchB2) B2
12bee1b C1.2
adf7ccd (BranchB1) B1
ef347fc (master) A0
>git log --oneline --no-merges BranchA ^BranchC
bb2909f (BranchB4) B4
b6adf20 (BranchC) C3.1
bec4444 (BranchB3) B3
45145d0 (BranchB2) B2
12bee1b C1.2
adf7ccd (BranchB1) B1
ef347fc (master) A0
>git log --oneline --no-merges BranchA
bb2909f (BranchB4) B4
bec4444 (BranchB3) B3
45145d0 (BranchB2) B2
adf7ccd (BranchB1) B1
ef347fc (master) A0
>git log --oneline --no-merges BranchC
b6adf20 (BranchC) C3.1
bec4444 (BranchB3) B3
12bee1b C1.2
adf7ccd (BranchB1) B1
ef347fc (master) A0
Ответы (2 шт):
новая версия ответа, упрощённая
чтобы получить коммиты, достижимые из указателей b*, но недостижимые из указателя c:
$ git log --no-merges b1 b2 b3 b4 ^c
аналогично для достижимых из указателей b*, но недостижимых из указателя a:
$ git log --no-merges b1 b2 b3 b4 ^a
аналогично для достижимых из указателя a, но недостижимых из указателя c:
$ git log --no-merges a ^c
если все указатели у вас в хранилище исчерпываются только приведённым списком (a, c, b*), то приведённых команд более чем достаточно.
Если коротко, то вам нужно выполнить для каждого Bi (из B1,...,Bn) команду:
git log Bi A ^C
Она покажет нужные комиты для указанного бранча Bi. Потом нужно объединить результаты.
Теперь пояснение, как это работает.
Команды типа git log или git rev-list принимают группу параметров, которая в документации называется <revision range>. Эти параметры задают, какие комиты показывать.
Например, в команде
git log A..B
это A..B, а в
git log A
это A.
В общем случае это список комитов (или имен веток) или комитов с префиксом ^. Еще допускается вариант A..B, что есть другим способом записать ^A B.
Для того чтоб сформулировать, как этот список используется командами сначала объясню, что такое родительский (англ. parent) комит. Комит X является родительским для Y, если Y непосредственно порожден от X. На картинке в вопросе B3 и A2 родители A3, а A0 родитель A1 и B1.
В результат работы команды (git log или git rev-list) включаются все комиты, которые достижимы используя отношение parent из комитов из списка без префиксов ^ и не достижимы из комитов с префиксами ^.
В вашем вопросе для каждой ветки Bi нужно найти комиты достижимые из Bi (т.е. они есть в ветке Bi) и достижимые из A (т.е. они либо слиты в A из Bi или наоборот из A в Bi), но недостижимы из ветки C. Итого получаем команду git log Bi A ^C.

