Показать объединенную разницу коммита слияния, включая файлы, добавленные любой родительской ветвью

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

Однако стандартный способ отображения слияний git для этого не подходит, поскольку он показывает только те фрагменты, которые каждый из нас изменил. Поэтому по умолчанию git show MERGE_COMMIT показывает только то, как были разрешены конфликты слияния вручную.

Что мне нужно: увидеть все изменения, произошедшие с момента расхождения ветвей, даже если не было конфликтов слияния, и приписать их одному из родителей.

git show -c и -m недостаточно: Я выяснил, что есть аргументы git diff-tree, которые также понимаются git show, а именно -m, -c и --cc.

  • --cc (используется по умолчанию git show MERGE_COMMIT) не показывает автоматически объединенные фрагменты и новые файлы.
  • -c Не показывает новые файлы
  • -m показывает новые файлы, но разделяет две ветви, из-за чего трудно судить, имеет ли объединенный файл семантический смысл.
  • Разница в базе слияния git diff $(git merge-base HEAD^1 HEAD^2) HEAD (спасибо @ 1615903) не атрибутирует изменения, как опции -c/--cc: используя эти два, перед тем, как получить разницу, я получаю по одному столбцу для каждого родителя, поэтому из столбца +/- я может сделать вывод, какой родитель внес это изменение.

Игрушечный пример. Базовый коммит создает file, ветка A добавляет несколько строк, ветка B добавляет несколько строк, одна в той же позиции, что и A, создавая конфликт. Кроме того, и A, и B добавляют file_a и file_b соответственно:

git init
# Add content to "file" to modify later
for f in `seq 1 15`; do echo "Line $f" >> file; done
git add file && git commit -m "initial commit"

# Divergent branch A: add "change a" to file and add new file_a
sed -i "s/Line 2/Line 2\nchange a/" file
sed -i "s/Line 10/Line 10\nchange a/" file
echo change a > file_a
git add . && git commit -m "change a"

# Divergent branch B: add "change b" to file and add new file_b
git checkout -b dev master~
sed -i "s/Line 14/Line 14\nchange b/" file
sed -i "s/Line 10/Line 10\nchange b/" file
echo change b > file_b
git add . && git commit -m "change b"

git checkout master
git merge dev
## Auto-merging file
## CONFLICT (content): Merge conflict in file
## Automatic merge failed; fix conflicts and then commit the result.

# Create the union -- remove the conflict markers
sed -i "/^[^Lc].*$/d" file
cat file
## Line 1
## Line 2
## change a
## [...]
## Line 10
## change a
## change b
## [...]
## Line 14
## change b
## Line 15

git add . && git commit -m "Merge 'dev' into 'master'"

Стандартный вариант показывает только ту строку, где был конфликт слияния (две ветки изменили одну и ту же строку)

git show HEAD:

[...]
diff --cc file
index 2fe2e63,019eb18..92b6fb7
--- a/file
+++ b/file
@@@ -9,7 -8,7 +9,8 @@@ Line 
  Line 8
  Line 9
  Line 10
 +change a
+ change b
  Line 11
  Line 12
  Line 13

С git show -c HEAD немного лучше, здесь показаны два других куска file, которые были решены автоматически:

[...]
diff --combined file
index 2fe2e63,019eb18..92b6fb7
--- a/file
+++ b/file
@@@ -1,6 -1,5 +1,6 @@@
  Line 1
  Line 2
 +change a
  Line 3
  Line 4
  Line 5
@@@ -9,9 -8,10 +9,11 @@@ Line 
  Line 8
  Line 9
  Line 10
 +change a
+ change b
  Line 11
  Line 12
  Line 13
  Line 14
+ change b
  Line 15

Чего еще не хватает, так это file_a и file_b, которые не отображаются.

Как насчет того, чтобы найти первого общего предка двух (или более) объединенных коммитов и провести сравнение с ним?

1615903 12.07.2024 11:55

Это будет git diff $(git merge-base HEAD^1 HEAD^2) HEAD, который не указывает, из какой ветки пришли изменения. В нем есть только один столбец +/-, поэтому я не знаю, кто из двух авторов ветки что изменил. Отредактировал вопрос, включив в него это, поскольку такой подход является шагом в правильном направлении.

akraf 12.07.2024 16:34
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

git show -c дает вам то, что вы хотите, комбинированные различия для обычных модификаций, за исключением того, что он не перечисляет такие вещи, как добавление и удаление, когда нет различий для объединения, поэтому (например) git show -m --oneline --raw сначала перечислить все изменения, а затем -c, чтобы покажите комбинированные различия там, где это имеет смысл. Добавьте --diff-filter=m, чтобы пропустить заголовок, если нет добавлений/удалений, чтобы два набора не перекрывались.

git show -m --oneline --raw; git show -c --oneline`

или

git show -m --oneline --raw --diff-filter=m; git show -c --oneline

Другие вопросы по теме