У меня есть репозиторий с мастером веток и A и много операций слияния между ними. Как я могу найти коммит в моем репозитории, когда ветка A была создана на основе master?
Мой репозиторий в основном выглядит так:
-- X -- A -- B -- C -- D -- F (master)
\ / \ /
\ / \ /
G -- H -- I -- J (branch A)
Я ищу ревизию А, которая не git merge-base (--all)
находит.
Ответы:
Я искал то же самое, и я нашел этот вопрос. Спасибо, что спросили!
Однако я обнаружил, что ответы, которые я вижу здесь, похоже, не совсем дают ответ, который вы просили (или что я искал) - они, похоже, дают
G
коммит, а неA
коммит.Итак, я создал следующее дерево (буквы назначены в хронологическом порядке), чтобы я мог проверить вещи:
Это выглядит немного иначе, чем у вас, потому что я хотел убедиться, что получил (ссылаясь на этот график, а не ваш) B, но не A (и не D или E). Вот письма, прикрепленные к префиксам SHA и сообщениям о коммитах (мое репо можно клонировать отсюда , если это кому-нибудь интересно):
Таким образом, цель: найти B . Вот три способа, которые я нашел после небольшой переделки:
1. визуально с гитком:
Вы должны визуально увидеть такое дерево (если смотреть с мастера):
или здесь (если смотреть из темы):
в обоих случаях я выбрал коммит
B
в моем графике. После того, как вы щелкнете по нему, его полный SHA будет представлен в поле ввода текста чуть ниже графика.2. визуально, но из терминала:
git log --graph --oneline --all
(Изменить / примечание: добавление
--decorate
также может быть интересным; оно добавляет указание имен веток, тегов и т. Д. Не добавляя это в приведенную выше командную строку, поскольку приведенные ниже результаты не отражают ее использование.)который показывает (при условии
git config --global color.ui auto
):Или прямым текстом:
в любом случае мы видим коммит 6aafd7f как самую низкую общую точку, то есть
B
на моем графике илиA
на вашем.3. С магией раковины:
Вы не указываете в своем вопросе, хотите ли вы что-то подобное выше, или единственную команду, которая просто даст вам одну ревизию, и больше ничего. Ну, вот последнее:
Который вы также можете вставить в ваш ~ / .gitconfig как (примечание: конечная черта важна; спасибо Брайану за то, что вы обратили на это внимание) :
Что можно сделать с помощью следующей (свернутой в кавычки) командной строки:
Примечание:
zsh
могло бы быть так же легкоbash
, но неsh
будет работать - синтаксис не существует в vanilla . (Еще раз спасибо, @conny, за то, что сообщили мне об этом в комментарии к другому ответу на этой странице!)<()
sh
Примечание: альтернативная версия выше:
Спасибо liori за то, что он указал, что вышеупомянутое может упасть при сравнении идентичных ветвей, и придумать альтернативную форму diff, которая удаляет форму sed из смеси, и делает это «более безопасным» (то есть возвращает результат (а именно, самый последний коммит), даже если вы сравниваете мастер с мастером):
В виде строки .git-config:
Из оболочки:
Итак, в моем дереве тестов (которое было недоступно некоторое время, извините, оно вернулось), теперь оно работает как для мастера, так и для темы (давая коммиты G и B соответственно). Еще раз спасибо, Лиори, за альтернативную форму.
Итак, вот что я [и liori] придумал. Кажется, это работает для меня. Это также допускает дополнительную пару псевдонимов, которые могут оказаться полезными:
Счастливого парения!
источник
diff
«S , если-то-иначе режим и Стирание изменения / удаления строки из его вывода вместо подсчета на имеющих достаточно большой контекст, на.:diff --old-line-format='' --new-line-format='' <(git rev-list …) <(git rev-list …)|head -1
.git log -n1 --format=format:%H $(git log --reverse --format=format:%H master..topic | head -1)~
я думаю, будет работатьgit merge-base --fork-point ...
дать коммит B (commit6aafd7f
) для этого дерева? Когда вы опубликовали это, я был занят другими вещами, и это звучало хорошо, но я, наконец, просто попробовал это, и я не заставляю его работать ... Я либо получаю что-то более новое, либо просто тихий сбой (без ошибок сообщение, но статус выхода 1), пытаясь аргументы , какgit co master; git merge-base --fork-point topic
,git co topic; git merge-base --fork-point master
,git merge-base --fork-point topic master
(или для проверки) и т.д. Есть ли что - то , что я делаю неправильно или не хватает?--fork-point
основан на reflog, поэтому он будет работать, только если вы внесли изменения локально. Даже тогда записи reflog могли истечь. Это полезно, но совсем не надежно.Вы можете искать
git merge-base
:источник
--all
опцию "git merge-base
"git merge-base
пять часов после того, как мой ответ был опубликован (вероятно, в ответ на мой ответ). Тем не менее, я оставлю этот ответ как есть, потому что он все еще может быть полезен для кого-то еще, кто находит этот вопрос через поиск.Я использовал
git rev-list
для такого рода вещей. Например, (обратите внимание на 3 точки)выплюнет точку ветвления. Теперь это не идеально; так как вы пару раз слили мастер в ветвь А, это разделит пару возможных точек ветвления (в основном, исходную точку ветвления, а затем каждую точку, в которой вы слили мастер в ветвь А). Однако это должно как минимум сузить возможности.
Я добавил эту команду в мои псевдонимы
~/.gitconfig
как:так что я могу назвать это как:
источник
G
вместоA
, согласно графику в исходном вопросе.) У меня есть ответA
, который я получу, что я буду публиковать в настоящее время.git checkout topic
а затем запустить егоtopic
вместоbranch-a
), он перечисляет648ca357b946939654da12aaf2dc072763f3caee
и37ad15952db5c065679d7fc31838369712f0b338
- и то,37ad159
и другое648ca35
в предке текущих веток (последняя является текущей HEAD oftopic
), но ни одна точка не имеет смысла до того, как произошло ветвление. Вы получаете что-то другое?Если вам нравятся краткие команды,
Вот объяснение.
Следующая команда дает вам список всех коммитов в master, которые произошли после того, как было создано branch_name
Поскольку вы заботитесь только о самых ранних из этих коммитов, вам нужна последняя строка вывода:
Родитель самого раннего коммита, который не является предком «branch_name», по определению находится в «branch_name» и находится в «master», так как он является предком чего-то в «master». Итак, у вас есть самый ранний коммит, который есть в обеих ветках.
Команда
это просто способ показать ссылку на родительский коммит. Вы могли бы использовать
или что угодно.
PS: я не согласен с аргументом, что порядок предков не имеет значения. Это зависит от того, что вы хотите. Например, в этом случае
имеет смысл выводить C2 как «ветвящийся» коммит. Это когда разработчик разветвился от "мастера". Когда он разветвился, ветвь «Б» даже не слилась в его ветке! Вот что дает решение в этом посте.
Если вам нужен последний коммит C, такой, что все пути от источника до последнего коммита в ветви «A» проходят через C, то вы хотите игнорировать порядок предков. Это чисто топология и дает вам представление о том, когда две версии кода работают одновременно. Вот тогда вы бы использовали подходы, основанные на слиянии, и в моем примере он вернет C1.
источник
git rev-list commit^^!
может быть упрощено какgit rev-parse commit^
git rev-list --first-parent ^branch_name master
с ,git rev-list --first-parent branch_name ^master
потому что если главный ветвь 0 фиксаций впереди другой ветви (быстро FORWARDABLE к нему), вывод не будет создан. С моим решением, выход не создается, если мастер строго впереди (т. Е. Ветвь полностью объединена), что я и хочу.git rev-list --first-parent ^topic master
будет только принять вас обратно к первой фиксации после последнего слияния изmaster
вtopic
(если вообще существует).Учитывая, что так много ответов в этой ветке не дают ответа на вопрос, который был задан, вот краткое изложение результатов каждого решения, а также сценарий, который я использовал для репликации репозитория, приведенного в вопросе.
Журнал
Создавая репозиторий с заданной структурой, мы получаем git log:
Мое единственное добавление, это тег, который делает его явным о точке, в которой мы создали ветвь и, следовательно, о коммите, который мы хотим найти.
Решение, которое работает
Единственное решение, которое работает, это то, которое предоставлено lindes, правильно возвращает
A
:Как указывает Чарльз Бейли , это решение очень хрупкое.
Если вы
branch_A
в ,master
а затем сливаютсяmaster
вbranch_A
без промежуточных фиксаций , то решение Lindes' только дает вам самый последний первый divergance .Это означает, что для моего рабочего процесса, я думаю, мне придется придерживаться маркировки точки ветвления длинных ветвей, так как я не могу гарантировать, что они могут быть надежно найдены позже.
Это на самом деле все сводится к тому,
git
s не хватает того , чтоhg
называют по имени филиалов . Блоггер jhw называет эти родословные и семьи в своей статье « Почему я люблю Mercurial больше, чем Git», и в своей последующей статье « Больше о Mercurial против Git» (с графиками!) . Я бы рекомендовал человек прочитать их , чтобы понять , почему некоторые ртутные новообращенные избегают что не названы филиалов вgit
.Решения, которые не работают
Решение , предлагаемое mipadi возвращает два ответа,
I
иC
:Решение, предоставленное Грегом Хьюгиллом, вернулось
I
Решение, предоставленное Карлом, возвращает
X
:Сценарий
Я сомневаюсь, что версия git имеет большое значение для этого, но:
Спасибо Чарльзу Бэйли за то, что он показал мне более компактный способ создания сценария репозитория.
источник
diff -u <(git rev-list branch_A) <(git rev-list master) | tail -2 | head -1
. Спасибо за предоставление инструкций по созданию репо :)В общем, это невозможно. В истории ветвей ветвление и слияние до того, как названная ветвь была разветвленной, а промежуточная ветвь двух именованных ветвей выглядит одинаково.
В git ветки - это просто текущие названия подсказок разделов истории. У них действительно нет сильной идентичности.
Обычно это не является большой проблемой, так как база слияния (см. Ответ Грега Хьюгилла) двух коммитов, как правило, гораздо более полезна, предоставляя самый последний коммит, которым поделились две ветви.
Решение, основанное на порядке родителей коммитов, очевидно, не будет работать в ситуациях, когда ветвь полностью интегрирована в какой-то момент в истории ветки.
Этот метод также не работает, если объединение интеграции было выполнено с обращенными родителями (например, временная ветвь использовалась для выполнения тестового объединения в мастер, а затем быстро пересылалась в ветвь функций для дальнейшего развития).
источник
git
было эквивалентhg
«ы имени филиалов, это сделало бы управление долгоживущими ветвями технического обслуживания , так гораздо проще.Как насчет чего-то вроде
источник
diverges = !bash -c 'git rev-parse $(diff <(git log --pretty=oneline ${1}) <(git log --pretty=oneline ${2}) | tail -1 | cut -c 3-42)^'
(без временных файлов)G
вместоA
, согласно графику в исходном вопросе.) Я думаю, что я нашел ответ, который я опубликую в настоящее время.diff -u <(git rev-list branch_A) <(git rev-list master) | tail -2 | head -1
конечно, я что-то упускаю, но IMO, все проблемы, описанные выше, вызваны тем, что мы всегда пытаемся найти точку ветвления, уходящую в историю, и это вызывает всевозможные проблемы из-за доступных комбинаций слияния.
Вместо этого я следовал другому подходу, основанному на том факте, что обе ветви имеют большую историю, точно вся история до ветвления на 100% одинакова, поэтому вместо того, чтобы вернуться назад, мое предложение о продвижении вперед (с 1-го commit), ищем 1-ую разницу в обеих ветках. Точка ветвления будет просто родителем первого найденного различия.
На практике:
И это решает все мои обычные дела. Конечно, есть пограничные, которые не покрыты, но ... чао :-)
источник
comm --nocheck-order -1 -2 <(git rev-list --reverse --topo-order topic) <(git rev-list --reverse --topo-order master) | head -1
Недавно мне тоже нужно было решить эту проблему, и в итоге я написал для этого скрипт на Ruby: https://github.com/vaneyckt/git-find-branching-point
источник
После долгих исследований и дискуссий становится ясно, что нет волшебной палочки, которая бы работала во всех ситуациях, по крайней мере, в текущей версии Git.
Вот почему я написал пару патчей, которые добавляют концепцию
tail
ветки. Каждый раз, когда создается ветвь, создается указатель на исходную точку,tail
ссылка. Эта ссылка обновляется каждый раз, когда ветка перебазируется.Чтобы найти точку ветвления ветки devel, все, что вам нужно сделать, это использовать
devel@{tail}
, вот и все.https://github.com/felipec/git/commits/fc/tail
источник
Вот улучшенная версия моего предыдущего ответа предыдущего ответа . Он полагается на сообщения коммитов от слияний, чтобы найти, где ветвь была впервые создана.
Он работает на всех репозиториях, упомянутых здесь, и я даже обратился к некоторым хитрым, которые появились в списке рассылки . Я также написал тесты для этого.
источник
Следующая команда покажет SHA1 коммита A
git merge-base --fork-point A
источник
Кажется, я получаю некоторую радость от
Последняя строка, которую вы получите, это первый коммит на ветке, так что тогда нужно получить его родителя. Так
Кажется, работает для меня и не требует различий и так далее (что полезно, поскольку у нас нет этой версии различий)
Исправление: это не работает, если вы находитесь в основной ветке, но я делаю это в скрипте, так что это не проблема
источник
Чтобы найти коммиты из точки ветвления, вы можете использовать это.
источник
Иногда это фактически невозможно (за некоторыми исключениями, когда вам может повезти иметь дополнительные данные), и решения здесь не будут работать.
Git не сохраняет историю ссылок (которая включает ветки). Он сохраняет только текущую позицию для каждой ветви (главы). Это означает, что вы можете потерять некоторую историю веток в git со временем. Когда вы, например, разветвляетесь, сразу теряется, какая ветка была оригинальной. Все, что делает ветка, это:
Вы можете предположить, что первым подтверждено ветвь. Это имеет место, но это не всегда так. Ничто не мешает вам совершить коммит в первую ветку после вышеуказанной операции. Кроме того, временные метки git не гарантируют надежность. Только тогда, когда вы посвятите себя обоим, они действительно станут структурно ветвями.
В то время как в диаграммах мы склонны к нумерации коммитов концептуально, git не имеет реального стабильного понятия последовательности, когда ветки дерева коммитов. В этом случае вы можете предположить, что числа (указывающие порядок) определяются меткой времени (было бы интересно увидеть, как пользовательский интерфейс git обрабатывает вещи, когда вы устанавливаете все метки времени на одно и то же).
Это то, что человек ожидает концептуально:
Вот что вы на самом деле получаете:
Вы могли бы предположить, что B1 является исходной веткой, но она может просто заразиться мертвой веткой (кто-то сделал checkout -b, но никогда не выполнял ее). До тех пор, пока вы не подтвердите обе эти возможности, вы не получите легитимную структуру веток в git:
Вы всегда знаете, что C1 предшествовал C2 и C3, но вы никогда не могли достоверно узнать, предшествовал ли C2 раньше C3 или C3 до C2 (потому что вы можете установить время на своей рабочей станции, например, на что угодно). B1 и B2 также вводят в заблуждение, так как вы не можете знать, какая ветвь появилась первой. Во многих случаях вы можете сделать очень хорошее и, как правило, точное предположение. Это немного похоже на гоночную трассу. При прочих равных с машинами, вы можете предположить, что машина, которая находится на круге позади, начала круг позади. У нас также есть соглашения, которые очень надежны, например, master почти всегда будет отображать ветки с наибольшим временем жизни, хотя, к сожалению, я видел случаи, когда даже это не так.
Пример, приведенный здесь, является примером сохранения истории:
Реальное здесь также вводит в заблуждение, потому что мы, люди, читаем его слева направо, от корня к листу (ссылка). Git этого не делает. Где мы делаем (A-> B) в наших головах git делает (A <-B или B-> A). Это читает это от ссылки до корня. Реферы могут быть где угодно, но имеют тенденцию быть листами, по крайней мере, для активных веток. Ссылка указывает на коммит, а коммиты содержат только то же самое для своих родителей, а не для своих детей. Когда коммит является коммитом слияния, у него будет более одного родителя. Первый родитель всегда является исходным коммитом, который был объединен. Другие родители всегда коммиты, которые были объединены в первоначальный коммит.
Это не очень эффективное представление, скорее, выражение всех путей, которые git может взять из каждого ref (B1 и B2).
Внутренняя память Git выглядит примерно так (не то, что родительский объект A появляется дважды):
Если вы сбросите raw git commit, вы увидите ноль или более родительских полей. Если есть ноль, это означает, что родитель отсутствует, а фиксация является корнем (у вас может быть несколько корней). Если он есть, это означает, что слияния не было и это не корневой коммит. Если их несколько, это означает, что фиксация является результатом слияния, и все родители после первого являются коммитами слияния.
Когда оба поразят А, их цепь будет одинаковой, до этого их цепь будет совершенно другой. Первый коммит, который есть у двух других коммитов, является общим предком и откуда они расходятся. здесь может быть некоторая путаница между терминами commit, branch и ref. На самом деле вы можете объединить коммит. Это то, что действительно делает слияние. Ссылка просто указывает на фиксацию, а ветвь - это не что иное, как ссылка в папке .git / refs /head. Расположение папки определяет, что ссылка является ветвью, а не чем-то другим, например тегом.
Когда вы теряете историю, слияние будет выполнять одно из двух в зависимости от обстоятельств.
Рассматривать:
В этом случае слияние в любом направлении создаст новый коммит с первым родителем в качестве коммита, на который указывает текущая извлеченная ветвь, и вторым родителем в качестве коммита в конце ветви, которую вы слили в текущую ветвь. Он должен создать новый коммит, поскольку обе ветви имеют изменения со времени их общего предка, которые должны быть объединены.
На данный момент D (B1) теперь имеет оба набора изменений из обеих ветвей (себя и B2). Однако вторая ветвь не имеет изменений от B1. Если вы объединяете изменения из B1 в B2 так, чтобы они были синхронизированы, то вы можете ожидать что-то, похожее на это (вы можете заставить git merge сделать это так, однако с помощью --no-ff):
Вы получите это, даже если у B1 есть дополнительные коммиты. Пока в B2 нет изменений, которых нет в B1, две ветви будут объединены. Он выполняет ускоренную перемотку вперед, которая похожа на перебазирование (перебазирование также использует или линеаризует историю), за исключением того, что в отличие от перебазирования, поскольку только одна ветвь имеет набор изменений, ей не нужно применять набор изменений из одной ветви поверх этой из другой.
Если вы прекратите работу над B1, то в целом все хорошо для сохранения истории в долгосрочной перспективе. Только B1 (который может быть главным) продвигается обычно, поэтому местоположение B2 в истории B2 успешно представляет точку, в которой оно было объединено с B1. Это то, что git ожидает от вас, чтобы ветвь B от A, затем вы можете объединить A в B столько, сколько захотите, по мере накопления изменений, однако при объединении B обратно в A не ожидается, что вы будете работать над B и далее. , Если вы продолжаете работать над своей веткой после быстрой перемотки вперед, объединяя ее с веткой, над которой вы работали, то каждый раз стираете предыдущую историю B. Вы действительно создаете новую ветку каждый раз после быстрой перемотки в исходный код, а затем в ответ.
От 1 до 3 и от 5 до 8 являются структурными ветвями, которые появляются, если вы следите за историей в течение 4 или 9. В git нет способа узнать, к какой из этих неназванных и не связанных структурных ветвей принадлежит именованная и ссылочная ветви как конец структуры. Из этого рисунка можно предположить, что от 0 до 4 принадлежит B1, а от 4 до 9 принадлежит B2, но, кроме 4 и 9, я не мог знать, какая ветвь принадлежит какой ветви, я просто нарисовал его так, чтобы иллюзия этого. 0 может принадлежать B2, а 5 может принадлежать B1. В этом случае существует 16 различных вариантов, к которым именованной ветви может принадлежать каждая из структурных ветвей.
Есть много стратегий мерзавца, которые работают вокруг этого. Вы можете заставить git merge никогда не переходить вперед и всегда создавать ветку слияния. Ужасный способ сохранить историю ветвей - использовать теги и / или ветви (теги действительно рекомендуется) в соответствии с некоторыми соглашениями по вашему выбору. Я действительно не рекомендовал бы фиктивный пустой коммит в ветке, в которую вы сливаетесь. Очень распространенное соглашение - не объединяться в ветку интеграции, пока вы не захотите по-настоящему закрыть свою ветку. Это практика, которой люди должны придерживаться, иначе вы работаете над тем, чтобы иметь ветви. Однако в реальном мире идеал - это не всегда практическое значение, а правильные поступки не жизнеспособны для любой ситуации. Если что ты
источник
man git-reflog
и часть о датах: «master@ enjone.week.ago} означает« где master указывал неделю назад в этом локальном репозитории »». Или обсуждение<refname>@{<date>}
вman gitrevisions
. Иcore.reflogExpire
вman git-config
.Не совсем решение вопроса, но я подумал, что стоит отметить подход, который я использую, когда у меня долгоживущая ветвь:
В то же время я создаю ветку, я также создаю тег с тем же именем, но с
-init
суффиксом, например,feature-branch
иfeature-branch-init
.(Это довольно странно, что это такой сложный вопрос!)
источник
Простой способ облегчить просмотр точки ветвления
git log --graph
- использовать эту опцию--first-parent
.Например, взять репо из принятого ответа :
Теперь добавьте
--first-parent
:Это облегчает!
Обратите внимание, если в репо много веток, вы захотите указать 2 ветви, которые вы сравниваете, вместо того, чтобы использовать
--all
:источник
Похоже, проблема заключается в том, чтобы найти самый последний срез с одним коммитом между двумя ветвями на одной стороне и самый ранний общего предка с другой (вероятно , начальная фиксацию репо). Это соответствует моей интуиции о том, что такое точка «разветвления».
Помните, что это совсем не просто вычислить с помощью обычных команд оболочки git, поскольку
git rev-list
- наш самый мощный инструмент - не позволяет нам ограничивать путь, по которому достигается коммит. Самое близкое, что у нас естьgit rev-list --boundary
, это то , что может дать нам набор всех коммитов, которые «заблокировали наш путь». (Запись:git rev-list --ancestry-path
это интересно, но я не знаю, как это сделать здесь.)Вот сценарий: https://gist.github.com/abortz/d464c88923c520b79e3d . Это относительно просто, но из-за цикла это достаточно сложно, чтобы оправдать суть.
Обратите внимание, что большинство других решений, предлагаемых здесь, не могут работать во всех ситуациях по простой причине: они
git rev-list --first-parent
не надежны при линеаризации истории, потому что могут быть слияния с любым порядком.git rev-list --topo-order
с другой стороны, это очень полезно - для прогулочных коммитов в топографическом порядке - но выполнение различий хрупко: для данного графа существует несколько возможных топографических упорядочений, поэтому вы зависите от определенной стабильности упорядочений. Тем не менее, решение strongk7, вероятно, работает чертовски хорошо большую часть времени. Однако он медленнее, потому что мне приходится проходить всю историю репо ... дважды. :-)источник
Следующее реализует git эквивалент svn log --stop-on-copy и может также использоваться для нахождения источника ветви.
Подходить
Подобно тому, как все реки текут к морю, все ветви текут к господству, и поэтому мы находим основу слияния между, казалось бы, не связанными ветвями. Когда мы возвращаемся от головы ветви к предкам, мы можем остановиться на первой потенциальной базе слияния, поскольку в теории это должна быть начальная точка этой ветви.
Ноты
детали: https://stackoverflow.com/a/35353202/9950
источник
Вы можете использовать следующую команду для возврата самого старого коммита в branch_a, который недоступен из master:
Возможно , с дополнительной проверкой здравомыслия , что родитель , что совершить это на самом деле можно добраться от мастера ...
источник
Вы можете проверить список журналов ветви A, чтобы найти, из какого коммита он был создан, а также полную историю коммитов, на которые указывает эта ветка. Reflogs в
.git/logs
.источник
Я полагаю, что нашел способ, который имеет дело со всеми угловыми случаями, упомянутыми здесь:
Чарльз Бэйли совершенно прав, что решения, основанные на порядке предков, имеют лишь ограниченную ценность; в конце дня вам нужна какая-то запись «этот коммит пришел из ветви X», но такая запись уже существует; по умолчанию «git merge» будет использовать сообщение коммита, например «Merge branch 'branch_A' to master», это говорит о том, что все коммиты от второго родителя (commit ^ 2) пришли из 'branch_A' и были объединены с первым parent (commit ^ 1), который является 'master'.
Вооружившись этой информацией, вы можете найти первое слияние 'branch_A' (когда действительно появилось 'branch_A') и найти базу слияния, которая будет точкой ветвления :)
Я пробовал с репозиториями Марка Бута и Чарльза Бейли, и решение работает; как это не могло? Единственный способ, которым это не сработает, - это если вы вручную изменили сообщение фиксации по умолчанию для слияний, чтобы информация о ветвях действительно терялась.
Для полезности:
Тогда вы можете сделать '
git branch-point branch_A
'.Наслаждаться ;)
источник
git merge -m
чтобы сказать, что я слил, а не название потенциально эфемерной ветви (например, «объединить магистраль превращается в особенность XYZ-рефактор»). Предположим, я был менее полезным с моим-m
в моем примере? Проблема просто не разрешима в ее полной общности, потому что я могу сделать одну и ту же историю с одной или двумя временными ветвями, и нет никакой возможности определить разницу.