Git ведет учет прошлых конфликтов слияний? - PullRequest
3 голосов
/ 23 апреля 2019

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

Я пытался использовать git log --merges, но это, кажется, показывает успешные слияния.

Ответы [ 4 ]

2 голосов
/ 23 апреля 2019

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

Как это работает

Вы можете перечислить слияния с rev-list:

git rev-list --parents --min-parents=2 --all

Это предпочтительнее, чем git log, потому что вывод подходит для синтаксического анализа скриптом. Это создаст список коммитов слияния, по одному на строку. Детальный коммит - это первый хеш, а остальные хэши являются родителями. Например,

28171e725cc93e8cb85194931e7138c31f980a43 20af81cf6388026ecf0de4eec8783e7a38905ccd 2d77896f5fcc1a9b09f4f099aa6e945e8da86410

Здесь объединение между 20af и 2d77.

Проверьте первого родителя в оторванной голове:

git checkout -q --detach 20af81cf6388026ecf0de4eec8783e7a38905ccd

Затем объедините оставшихся родителей:

git merge -q --no-commit --no-ff 2d77896f5fcc1a9b09f4f099aa6e945e8da86410

Код состояния merge будет равен 1, если есть конфликты, которые вы можете изучить. В случае конфликта слияния вы увидите файлы с UU в статусе фарфора:

git status --porcelain

Затем вы можете прервать слияние, чтобы вернуться в состояние, в котором вы можете работать с репо:

git merge --abort

Сценарий

Я превратил это в сценарий в качестве демонстрации. Сценарий должен быть запущен в нетронутом хранилище, так как он будет запускать несколько команд git checkout и git merge.

https://gist.github.com/depp/f1838cf4559f9cde74b9d3052b8abbb0

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

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

2 голосов
/ 23 апреля 2019

Я думаю, вы могли бы извлечь выгоду из git-rerere в некоторой комбинации с предыдущими вопросами по его обучению:

Я думаю, что фактическое место хранения находится в .git/rr-cache, но я никогда не смотрел и не знаю, что там.

1 голос
/ 23 апреля 2019

Не легко ... но вы можете запустить скрипт, если вам нужно ...

Вы можете использовать git log, чтобы найти все коммиты слияния - при условии, что вы оставили автоматическое сообщение на месте, или использовать разумное сообщение, которое (надеюсь) всегда одинаково. Например:

git log --all --oneline --graph --decorate дает приличное древовидное представление репо - например:

*   a1a9bde (HEAD -> TESTER) Merge branch 'test' into TESTER
|\
| * 2ff3965 (test) updated
| * 12af0b0 s
* | eb9ab80 updated
* |   bec65ad (master) Merge branch 'master' of d:\software\sandpit\git-test
|\ \
| * \   595bff6 Merge branch 'master' of d:\software\gitRepos\git-test
| |\ \
| | * | 77d69c7 new file
| | |/
   :

Но для сценариев используйте только git log --oneline --all:

a1a9bde Merge branch 'test' into TESTER      <----- LETS LOOK AT THIS MERGE...
eb9ab80 updated
2ff3965 updated
bec65ad Merge branch 'master' of d:\software\sandpit\git-test
8a73cd1 updated test1
58080f2 new file
819226c new file
e122cc6 file for merge back to master
49acb0b file added in branch
a262470 yet another file
12af0b0 s

Или просто получите список хешей: git log --oneline --all | grep "Merge branch" | awk '{print $1}':

a1a9bde
bec65ad

обновление 1

или как Dietrich Epp (почти) предложил использовать git rev-list --min-parents=2 a1a9bde - это дает полный хэш любого коммита с 2 родителями - приятно Dietrich Epp!

обновление 1 - конец

Теперь пройдитесь по этим хэшам, например отсюда с помощью первого: a1a9bde

Вы можете получить родительский хеш как: git show --format="%P" 595bff6 - это приводит к:

eb9ab8029e6951f68a9c1008bb8611444d31528d 2ff3965b9aa1e6c49c82127e5f08199796a40780

Так что теперь вы можете запустить слияние с помощью:

  • Извлечение первого хеша: git checkout eb9ab8029e6951f68a9c1008bb8611444d31528d -B merge_test - это извлекает первый хеш на ветку с именем merge_test (и заменяет любую предыдущую ветку с тем же именем)

  • объединить второй хэш (пробный прогон): git merge --no-commit --no-ff 2ff3965b9aa1e6c49c82127e5f08199796a40780

  • Используйте git status | grep "both modified", чтобы увидеть конфликты - дает:
     both modified:   testfile1.txt     <---- THIS FILE IS A CONFLICT
  • Теперь сделайте то, что вам нужно, затем, наконец, приберите git merge --abort

Так или иначе - это немного больно, но все это можно довольно легко записать в сценарий, я предоставил команды для этого, но у меня нет стимула выписать сценарий ...: o

0 голосов
/ 29 апреля 2019

Для первого быстрого обзора вы можете использовать:

git log --merges --cc --all

Опция --cc (от git help log):

-c
   With this option, diff output for a merge commit shows the
   differences from each of the parents to the merge result
   simultaneously instead of showing pairwise diff between a parent
   and the result one at a time. Furthermore, it lists only files
   which were modified from all parents.

--cc
   This flag implies the -c option and further compresses the patch
   output by omitting uninteresting hunks whose contents in the
   parents have only two variants and the merge result picks one of
   them without modification.

Это покажет показать конфликты, но- AFAICT - немного больше о «ближних конфликтах».

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