git удалить фиксацию слияния из истории

Моя история Git выглядит так:

История Git

Я хотел бы объединить фиолетовые коммиты в один. Я не хочу видеть их снова в моем журнале коммитов.

Я пытался сделать git rebase -i 1, но даже несмотря на то, что 1 находится на синей ветке (см. рисунок), я все еще вижу каждый коммит на своей фиолетовой ветке.

Как я могу полностью удалить фиолетовую ветку (из журнала коммитов)?


person Benjamin Toueg    schedule 10.07.2013    source источник
comment
Ваш репозиторий выталкивается куда-нибудь, что другие люди извлекли из него?   -  person Schleis    schedule 10.07.2013
comment
Обе ветви являются чисто местными.   -  person Benjamin Toueg    schedule 10.07.2013


Ответы (5)


Сделайте git rebase -i <sha before the branches diverged>, это позволит вам удалить фиксацию слияния, и журнал будет состоять из одной строки, как вы и хотели. Вы также можете удалить любые коммиты, которые вам больше не нужны. Причина, по которой ваша перебазировка не работала, заключалась в том, что вы не возвращались достаточно далеко.

ПРЕДУПРЕЖДЕНИЕ: этим вы переписываете историю. Выполнение этого с изменениями, которые были отправлены в удаленное репо, вызовет проблемы. Я рекомендую делать это только с локальными коммитами.

person Schleis    schedule 10.07.2013
comment
Даже если я выберу ша до того, как ветки разошлись, я вижу все коммиты фиолетовой ветки -_- - person Benjamin Toueg; 10.07.2013
comment
Да, тогда вы удалите их в редакторе, который предлагает git rebase, и они будут удалены. - person Schleis; 10.07.2013
comment
Удаление коммитов привело к потере всех модификаций слияния. Но я сделал программный сброс и получил то, что хотел (порядок не соответствует первоначальным ожиданиям). - person Benjamin Toueg; 10.07.2013
comment
этот ответ неполный в деталях, из какой ветки вы инициируете перебазирование? - person grgry; 17.02.2016
comment
@gregorynich Вы имеете дело только с одной веткой, в нее просто слилась другая ветка. В результате все коммиты отображаются в истории, вопрос ОП не касается других веток. - person Schleis; 17.02.2016
comment
Совершенно уверен, что вы не хотите «удалять» коммиты. 'удалить' - это не вариант перебазирования, а удалить. если вы удалите фиксацию, вы потеряете внесенные ею изменения. Вы хотите раздавить коммиты. - person thecoshman; 02.10.2017
comment
Почему эта перебазировка должна быть интерактивной? Я заметил, что иначе это не сработает, или я что-то упускаю. - person Cosmin Lehene; 16.11.2017
comment
@CosminLehene, если он не интерактивен, вы не сможете редактировать список коммитов. - person Schleis; 28.11.2017
comment
Это сработало для меня. После завершения перебазирования; Я должен был сделать git push -f origin develop - person Awi; 23.03.2019

Начиная с репо в исходном состоянии

Исходная история репо

Чтобы удалить фиксацию слияния и объединить ветку в одну фиксацию в основной ветке

Сжатые коммиты, без слияния

Используйте эти команды (заменив 5 и 1 на SHA соответствующих коммитов):

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

Чтобы сохранить фиксацию слияния, но сжать коммиты ветки в одну:

Сжатые коммиты, сохраненная фиксация слияния

Используйте эти команды (заменив 5, 1 и C на SHA соответствующих коммитов):

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

Чтобы удалить фиксацию слияния и заменить ее отдельными фиксациями из ветки

Ветка перенесена в основную ветку, без слияния

Просто сделайте (заменив 5 на SHA соответствующего коммита):

git rebase 5 master

И, наконец, полное удаление ветки

Ветка полностью удалена

Используйте эту команду (заменив C и D на SHA соответствующих коммитов):

git rebase --onto C D~ master
person Allen Luce    schedule 24.10.2017
comment
в git rebase 5 master случае, почему это не A B C 1 2 3 4 5 D ... порядок? - person Roy; 04.06.2018
comment
Эта команда берет коммиты, которые master не имеют общего с 5, и помещает их поверх 5. Коммит в C не является частью линии 5, он первый, который был перемещен поверх 5. - person Allen Luce; 04.06.2018
comment
Если вы хотите получить A B C 1 2 3 4 5 D ... вы можете сделать: git rebase C 5; git rebase 5 master - person Allen Luce; 04.06.2018

Просто удалить фиксацию слияния

Если все, что вы хотите сделать, это удалить фиксацию слияния (2), чтобы этого никогда не было, команда выглядит следующим образом:

git rebase --onto <sha of 1> <sha of 2> <blue branch>

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

person Warren    schedule 04.02.2018
comment
Из всех ответов я считаю, что это самый простой и самый простой. Спасибо. - person Roshambo; 23.07.2020
comment
Это первый шаг к вопросу, и я согласен, самый простой, который делает именно то, что просили. Второй шаг будет git merge --squash <purple branch name> - person Tony; 09.12.2020

Есть два способа решить эту проблему в зависимости от того, что вы хотите:

Решение 1. Удалите фиолетовые фиксации, сохранив историю (на случай, если вы захотите откатиться)

git revert -m 1 <SHA of merge>

-m 1 указывает, какую родительскую строку выбрать

Фиолетовые коммиты все еще будут в истории, но поскольку вы откатились, вы не увидите код из этих коммитов.


Решение 2. Полностью удалите фиолетовые коммиты (изменение, нарушающее работу, если репозиторий открыт для общего доступа).

git rebase -i <SHA before branching out>

и удалить (удалить строки), соответствующие фиолетовым коммитам.

Это было бы менее сложно, если бы коммиты не делались после слияния. Дополнительные коммиты увеличивают вероятность конфликтов во время revert/rebase.

person prem    schedule 13.07.2013
comment
Это звучит неправильно. Оставляя в стороне тот факт, что трудно сказать, что первоначальный постер хотел сделать с фиолетовыми коммитами в первую очередь, если вы вернете слияние, это нормально, это сделает обратный патч изменений из этого коммита и добавит его как другой коммит, отменяющий фиолетовый коммит. Это как 1 - 1 = 0. Но если вы затем перебазируете фиолетовые коммиты, вы оставите восстановленный патч, если только вы не перебазируете и его. Если вы этого не сделаете, это будет похоже на применение -1 к вашей истории, а не 0, так что вы оставите изменения, которые вам не нужны. - person ; 14.07.2013
comment
@Cupcake, при условии, что были два отдельных ответа. Я пересмотрел ответ, чтобы он был менее запутанным: P - person prem; 21.07.2013
comment
AFAIK, это не то, о чем просит ОП. Он хочет сохранить изменения, но удалить шум из своего журнала. Для этого ему нужно раздавить коммиты, удаление удалит изменения. - person thecoshman; 02.10.2017
comment
Правда, похоже, что исходный вопрос был перефразирован. Этот ответ не для проблемы OP. - person prem; 30.10.2019

Для полного контроля над операцией и сохранения любых коммитов слияния, которые вы хотите сохранить, современный подход заключается в использовании

git rebase -i -r

person squall3d    schedule 29.04.2021