git удалить коммит слияния из истории


99

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

История Git

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

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

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


Ваше репо продвигается куда-нибудь, что другие люди извлекли из него?
— Schleis

Оба филиала чисто местные.
— Benjamin Toueg

Ответы:


102

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

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


4
Даже если я выберу ша до того, как ветви разойдутся, я увижу все коммиты фиолетовой ветви -_-
— Benjamin Toueg

1
Да, затем вы удаляете их в редакторе, который появляется, git rebaseи они будут удалены.
— Schleis

4
Удаление коммитов привело к потере всех модификаций слияния. Но я сделал мягкий сброс и смог получить что-то совсем то, что хотел (порядок не соответствует первоначальным ожиданиям).
— Benjamin Toueg

2
этот ответ неполон, из какой ветви вы инициируете перебазирование?
— grgry

3
Совершенно уверен, что вы не хотите «удалять» коммиты. «удалить» нельзя в rebase, но удалить можно. если вы удалите фиксацию, вы потеряете внесенные в нее изменения. Вы хотите раздавить коммиты.
— thecoshman

71

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

Оригинальная история репо

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

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

Используйте эти команды (заменив 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

в git rebase 5 masterслучае, почему это не порядок "ABC 1 2 3 4 5 D ..."?
— Рой

1
Эта команда берет коммиты, которые masterне имеют ничего общего с 5ними, и накладывает их поверх 5. Коммит в Cне является частью линии 5, он первым перемещается поверх 5.
— Allen Luce

2
Если вы хотите закончить с «ABC 1 2 3 4 5 D ...», вы можете сделать:git rebase C 5; git rebase 5 master
— Аллен Люс

19

Чтобы просто удалить фиксацию слияния

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

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

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


1
Я считаю, что это самый простой и самый простой из всех ответов. Спасибо.
— Рошамбо

16

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

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

git revert -m 1 <SHA of merge>

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

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


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

git rebase -i <SHA before branching out>

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

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


Это звучит неправильно. Оставляя в стороне тот факт, что трудно сказать, что исходный плакат хотел сделать с фиолетовыми коммитами в первую очередь, если вы отмените слияние, это нормально, это сделает обратный патч изменений из этого коммита и добавит его как другой коммит, отменяющий фиолетовый коммит. Это как 1 - 1 = 0. Но если вы затем удалите фиолетовые коммиты, вы оставите возвращенный патч, если вы не удалите и его. Если вы этого не сделаете, это как применить -1к своей истории, а не 0, так что вы оставите изменения, которые вам не нужны.

@Cupcake, были предоставлены два отдельных ответа. Я изменил ответ, чтобы он был менее запутанным: P
— prem

AFAIK, это не то, о чем просит OP. Он хочет сохранить изменения, но убрать шум из журнала. Для этого ему нужно сжать коммиты, удаление приведет к удалению изменений.
— thecoshman 02

Правда, похоже, первоначальный вопрос перефразирован. Этот ответ не относится к проблеме OP.
— прет
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.