Найти точку ветвления с помощью Git? - PullRequest
404 голосов
/ 06 октября 2009

У меня есть репозиторий с мастером веток и А и большим количеством операций слияния между ними. Как мне найти коммит в моем репозитории, когда ветка A была создана на основе master?

Мой репозиторий в основном выглядит так:

-- X -- A -- B -- C -- D -- F  (master) 
          \     /   \     /
           \   /     \   /
             G -- H -- I -- J  (branch A)

Я ищу ревизию A, которую git merge-base (--all) не находит.

Ответы [ 21 ]

0 голосов
/ 27 мая 2012

Я полагаю, что нашел способ справиться со всеми упомянутыми здесь угловыми случаями:

branch=branch_A
merge=$(git rev-list --min-parents=2 --grep="Merge.*$branch" --all | tail -1)
git merge-base $merge^1 $merge^2

Чарльз Бэйли совершенно прав, что решения, основанные на порядке предков, имеют лишь ограниченную ценность; в конце дня вам нужна какая-то запись «этот коммит произошел из ветви X», но такая запись уже существует; по умолчанию «git merge» будет использовать сообщение коммита, например «Merge branch 'branch_A' to master», это говорит о том, что все коммиты от второго родителя (commit ^ 2) пришли из 'branch_A' и были объединены с первым parent (commit ^ 1), который является 'master'.

Вооружившись этой информацией, вы можете найти первое слияние 'branch_A' (когда действительно появилось 'branch_A') и найти базу слияния, которая будет точкой ветвления:)

Я пробовал с репозиториями Марка Бута и Чарльза Бейли, и решение работает; как это не могло? Единственный способ, которым это не сработает, - это если вы вручную изменили сообщение о фиксации по умолчанию для слияний, чтобы информация о ветвях действительно терялась.

За полезность:

[alias]
    branch-point = !sh -c 'merge=$(git rev-list --min-parents=2 --grep="Merge.*$1" --all | tail -1) && git merge-base $merge^1 $merge^2'

Тогда вы можете сделать 'git branch-point branch_A'.

Наслаждайся;)

...