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.