git видалити коміт злиття з історії


97

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

Історія Git

Я хотів би розчавити фіолетові коміти в єдиний. Я не хочу бачити їх більше ніколи в моєму журналі реєстрації.

Я намагався зробити a git rebase -i 1, але хоча 1це на синій гілці (пор. Малюнок), я все одно бачу кожну комітацію на моїй фіолетовій гілці.

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


Чи заштовхується ваше репо кудись, що з нього тягнули інші люди?
Schleis

Обидві гілки суто місцеві.
Бенджамін Туг

Відповіді:


100

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

ПОПЕРЕДЖЕННЯ: Ви переписуєте історію, роблячи це. Виконання цього зі змінами, які були передані до віддаленого репо, спричинить проблеми. Я рекомендую робити це лише з місцевими комітами.


4
Навіть якщо я виберу ша до того, як гілки розійдуться, я бачу всі коміти фіолетової гілки -_-
Бенджамін Туг

1
Так, тоді ви видалите їх у редакторі, який з’явиться, git rebaseі вони будуть видалені.
Schleis

4
Видалення комітів призвело до втрати всіх модифікацій злиття. Але я зробив м’який скидання, і мені вдалося отримати щось на зразок того, що я хотів (замовлення не відповідає початковим очікуванням).
Бенджамін Туг

2
ця відповідь неповна в деталях, з якої гілки ви ініціюєте перебазу?
grgry

3
Цілком впевнений, що ви не хочете "видаляти" коміти. 'видалити' не є можливістю у перебазуванні, але видалити є. якщо ви видалите коміт, ви втратите внесені ним зміни. Ви хочете зменшити комітети.
thecoshman

69

Починаючи з репо у вихідному стані

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

Щоб видалити коміт злиття та змити гілку в єдиний коміт на основній лінії

Змінені коміти, без злиття

Використовуйте такі команди (замінюючи 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.
Аллен Люс,

2
Якщо ви хочете отримати "ABC 1 2 3 4 5 D ...", ви можете зробити:git rebase C 5; git rebase 5 master
Аллен Люс,

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
прем

AFAIK це не те, про що вимагає ОП. Він хоче зберегти зміни, але прибрати шум зі свого журналу. Для цього йому потрібно стиснути коміти, видалення призведе до видалення змін.
thecoshman

Правда, схоже, оригінальне питання було переформульовано. Ця відповідь не стосується проблеми ОП.
прем

16

Просто видалити коміт злиття

Якщо все, що ви хочете зробити, це видалити коміт злиття (2) так, щоб ніколи не траплялося, команда виконується просто наступним чином

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

І тепер фіолетової гілки взагалі немає в журналі комітів синього кольору, і у вас знову є дві окремі гілки. Потім ви можете самостійно стиснути фіолетовий і виконувати будь-які інші маніпуляції, не виконуючи злиття.


З усіх відповідей я вважаю це найпростішим і найпростішим у виконанні. Дякую.
Рошембо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.