Подтвердить что ты не робот

Как я могу суммировать слияние для обнаружения ошибочного `git merge -s ours`?

Несколько раз в прошлом у нас была проблема, когда разработчики (либо явно, либо эффективно) выполняли git merge -s ours, когда им этого не было, коммиты были потеряны, и мы обнаружили это намного позже, когда очистка намного сложнее и требует много времени. Тесты не терпят неудачу, потому что те самые коммиты, которые добавили тесты, были молча возвращены вместе с кодом, который они тестировали.

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

Lines              Left(2b3c4d) Right(3c4d5e)
Common with base   970          930
Unique wrt base    20            50
Unique wrt other   15            45
Unique wrt merge   15            45
Common with merge  995          985

Но в случае, когда слияние было сделано неправильно, отменив много изменений или где было выполнено git merge -s ours, это может привести к сообщению примерно так:

Lines              Left(2b3c4d) Right(3c4d5e)
Common with base   970          930
Unique wrt base    20            50
Unique wrt other   15            45
Unique wrt merge   15             0 !!
Common with merge  990          935
Warning: 100% of changes from 3c4d5e are missing from merge commit!

Если этот отчет был запущен для каждой фиксации, мы могли бы отмечать (через задание jenkins) всякий раз, когда слияние было немного на вонючей стороне.

До сих пор я играл с git diff --stat, git diff --name-status и git diff --summary, но пока никто не дает мне то, что я хочу.

Лучшее, что я могу сделать до сих пор, приведет к чему-то вроде следующего для нормального слияния:

              base..left   base..right  left..merge  right..merge
              f67c4..a9eb4 f67c4..5b592 a9eb4..cb209 5b592..cb209
 a    |                    1 +          1 +          
 b    |       1 +                                    1 +
 base |       1 +          1 +          1 +          1 +
changed       2            2            2            2
insertions(+) 2            2            2            2
deletions(-)  0            0            0            0

и для слияния ours:

              base..left   base..right  left..merge  right..merge
              f67c4..a9eb4 f67c4..5b592 a9eb4..95637 5b592..95637
 a    |                    1 +                       1 -
 b    |       1 +                                    1 +
 base |       1 +          1 +                       2 +-
changed       2            2            0            3
insertions(+) 2            2            0            2
deletions(-)  0            0            0            2

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

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

Наконец, я хотел бы иметь возможность запускать эту итоговую утилиту на грязном репо, не сбрасывая сначала все мои изменения, поэтому мои текущие эксперименты с git diff.

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

Ближайшие существующие вопросы, которые я могу найти, следующие: Обнаружение слияния, сделанного '-s ours' (но единственный ответ там не help) и "git merge -s ours" и как показать разницу (но ответов на них вообще нет).

4b9b3361

Ответ 1

У меня была эта точная проблема, и в итоге я написал инструмент для обнаружения этих типов слияний. Хотя я не могу поделиться фактическим кодом (он технически принадлежит моему работодателю), алгоритм очень прост: пусть S1 - это набор всех файлов, которые имеют изменения между слиянием и вторым родителем слияния. Пусть S2 - множество всех файлов, имеющих изменения между слиянием и базой слияния. Вычитайте S2 из S1, и вы останетесь с набором файлов, которые, вероятно, потеряли изменения из-за слияния.

Это не только обнаружит слияния, сделанные с помощью -s ours, но также обнаружит неудачные слияния, когда некоторые, но не все, изменения во втором родителе превратили его в слияние.