Как получить git-логи только текущей ветки и просто объединенного коммита - PullRequest
0 голосов
/ 13 июня 2018

Я использую эту команду git для получения журналов (от конкретного коммита) в обратном порядке и деталей коммита:

git log eab3e0ffdsfs.. --reverse -M --numstat --summary --pretty=format:commitId:%H%ndate:%cd%nsubject:%s%nauthor:%an%n

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

Однако я просто заинтересован в текущем ветке коммитов и журнале слитых коммитов.

Я попробовал следующие варианты:

git log --first-parent 8e146445d19b.. --reverse -M --numstat --summary --pretty=format:commitId:%H%ndate:%cd%nsubject:%s%nauthor:%an%n

дает коммиты текущей ветки, но я неполучать файлы, которые были изменены в этом объединенном коммите. Я просто получаю имя автора, тему и дату объединенного коммита.

Однако, если вы заходите на github и проверяете историю для своей ветви, вы получаете текущие фиксации ветвии просто объединенный коммит, включающий в себя измененные файлы.

Можем ли мы добиться этого с помощью команды git?

Спасибо

1 Ответ

0 голосов
/ 13 июня 2018

Попробуйте добавить -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 значительно уменьшает проблему.

...