Попробуйте добавить -m
к вашей наиболее успешной команде git log
, то есть:
git log -m --first-parent 8e146445d19b.. --reverse -M --numstat --summary --pretty=format:commitId:%H%ndate:%cd%nsubject:%s%nauthor:%an%n
(опции -c
и и --cc
также будут работать, но используйте -m
здесь.)
Здесь стоит отметить еще кое-что:
Однако мне просто интересны текущие ветки коммитов и журнал слитых коммитов.
Это первоекоманда is показывает вам коммиты текущей ветки.
При использовании Git важно понимать, что набор коммитов, который находится в текущей ветке , меняет при слияниидругие ветви:
D--E--F <-- br1
/
...--B--C
\
G--H--I <-- br2
Это чертеж серии коммитов (идентифицируемых одиночными заглавными буквами, а не их действительными хэш-идентификаторами) на двух ветвях.Более ранние коммиты находятся слева, более поздние коммиты - справа.
Теперь, я думаю, это интуитивно очевидно, и что все согласятся, что коммиты D-E-F
находятся только на ветке br1
, и коммитыG-H-I
только на ветке br2
.Но: какая ветвь или ветви являются коммитами B-C
(и любые более ранние) на?
Ответ в Git заключается в том, что эти коммиты находятся на обеих ветвях.Более того, если вы теперь git checkout br1
, а затем git merge br2
, вы получите это в результате:
D--E--F
/ \
...--B--C J <-- br1
\ /
G--H--I <-- br2
и теперь, внезапно, коммиты G-H-I
также находятся в обеих ветвях!
Когда вы добавляете --first-parent
, вы говорите Git, что когда он перемещается назад, начиная с J
, он должен при слиянии следовать только первый родителькаждого коммита слияния.Первый родитель J
- F
(I
- второй родитель), поэтому это означает: переход от J
до F
, F
до E
и т. Д. .
... но [с --first-parent
] Я не получаю файлы, которые были изменены в этом объединенном коммите.
По умолчанию, когдаgit log
показывает коммит слияния, он не показывает никаких различий.Три варианта, которые я упомянул выше, -m
, -c
и --cc
, сообщают git log
, что он должен показывать различия для коммитов слияния.
Причина в том, что есть три варианта, это способ слияниякоммиты показывать сложно.Для коммита без слияния это довольно просто: каждый коммит представляет собой полный снимок всех файлов, поэтому все, что Git должен сделать, это сравнить файлы, которые находятся в parent commit, к файлам, которые находятся в самом коммите.Например, для commit F
Git может просто извлечь все файлы из моментального снимка E
, затем все файлы из моментального снимка F
, и что бы это ни было отличается , ну, это изменение - эторазница от E
до F
.
При merge commit как J
, тем не менее, есть два родителя.Какой из них должен сравнивать Git с J
, E
или I
?git log
использует по умолчанию ответ: не беспокойтесь, это слишком сложно. :-) Если вы хотите убедить git log
показать что-то, вам нужна дополнительная опция.Два варианта - -c
и --cc
- говорят Git использовать комбинированный diff .
Комбинированный diff довольно сложен.Git извлекает все файлы из всех родителей и сравнивает их со всеми файлами в снимке слияния.Если любой родительский файл равен точно так же , что и файл коммита слияния, Git выбрасывает этот файл из списка файлов для сравнения.Итак, теперь у Git очень маленький список файлов: те файлы, которые в результате слияния не соответствуют любому входных снимков. 1 Затем Git сравнивает версию каждого родителякаждого такого файла по сравнению с окончательной объединенной версией, и объединяет различия, так что вы можете видеть все различные версии одновременно.Опции -c
и --cc
делают это.
Параметр -m
концептуально намного проще.При обнаружении коммита слияния Git просто разбивает слияние для отображения.Вместо одновременного сопоставления J
с F
и I
Git выполняет своего рода виртуальный коммит: J-from-F
, сравнивает его с F
и показывает, что diff,Затем, если вы не использовали --first-parent
, Git продолжает делать второй виртуальный коммит: J-from-I
, сравнивает его с I
и показывает , что diff.
Так как вывероятно, вы хотите рассматривать ваше слияние как изменение по сравнению с тем, что было до слияния, вам потребуются оба варианта: --first-parent
и -m
.
1 Одна из причинЭто позволяет быстро сравнивать файлы с точным соответствием в Git и не требует извлечения файлов из коммитов.Таким образом, выбрасывая все «одинаковые по крайней мере в одном родительском» файлы, Git значительно уменьшает проблему.