Мені потрібно спливати та видаляти “середній” коміт у моїй головній гілці. Як я можу це зробити?


94

Наприклад, у такій головній гілці мені потрібно смітити лише коміт af5c7bf16e6f04321f966b4231371b21475bc4da, який є другим завдяки попередньому перебазуванню:

commit 60b413512e616997c8b929012cf9ca56bf5c9113
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Tue Apr 12 23:50:15 2011 +0200

    add generic config/initializers/omniauth.example.rb

commit af5c7bf16e6f04321f966b4231371b21475bc4da
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 00:15:50 2011 +0200

    show github user info if logged

commit e6523efada4d75084e81971c4dc2aec621d45530
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 17:20:48 2011 +0200

    add multiple .container at blueprint layout

commit 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Thu Apr 21 19:55:57 2011 +0200

    add %h1 Fantastic Logo + .right for 'Sign in with Github'

Мені потрібно погодувати

  • перший коміт 60b413512e616997c8b929012cf9ca56bf5c9113,
  • третій коміт e6523efada4d75084e81971c4dc2aec621d45530 та
  • останнє комітування 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22

"викидання" лише Другого коміту af5c7bf16e6f04321f966b4231371b21475bc4da

Як я можу це зробити? Заздалегідь дякую, Лука

Відповіді:


98

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

Повернути - це правильне рішення, коли гілка була надана спільно з іншими репозиторіями. git revert af5c7bf16зробить новий коміт, який просто скасовує зміни, внесені af5c7bf16. Таким чином історія не переписується, ви ведете чіткий запис про помилку, а інші репозиторії приймуть натиск.

Ось хороший спосіб стерти: git rebase -i <commit>^ це приведе вас до коміту безпосередньо перед тим, який ви хочете видалити. Інтерактивний редактор покаже вам список усіх комітів назад до цього моменту. Ви можете вибрати, стиснути тощо. У цьому випадку видаліть рядок коміту, який ви хочете стерти, і збережіть файл. Rebase закінчить свою роботу.


2
Якщо я оберу Rebase, який правильний коміт перебазувати? Мені потрібно кинути лише секунду ...
— Лука Г. Соаве

@ BBJ3 Див. Відповідь mipadi.
— Prajwal Dhatwalia

32

Якщо перебазування є варіантом, ви можете перебазувати і просто скинути його:

$ git rebase -i 414ceffc^

Якщо перебазувати не можна, ви можете просто скасувати його:

$ git revert af5c7bf16

якщо я отримав для "git rebase 414ceffc", який є старшим четвертим комітом, хіба я втрачу також третій e6523 і перший 60b41?
— Luca G. Soave

3
@Luca G. Soave: Ви "втрачаєте" коміт, лише якщо спеціально наказали git rebaseйого відмовитись (запустивши rebaseв інтерактивному режимі та видаливши його запис).
— mipadi

Дякую, mipadi, я віддаю свій голос JCotton по суті за широке пояснення, навіть якщо ви двоє сказали те саме ... ще раз спасибі.
— Luca G. Soave

29

Незважаючи на всі заслуги оригінальних відповідей, отриманих тут, я не зовсім знайшов їх, щоб задовільно відповісти на питання. Якщо ви потрапили в ситуацію, коли вам потрібно видалити коміт або колекцію комітів із середини історії, я пропоную ось що:

  • Створіть нову гілку з голови тієї, що містить усі коміти, і перейдіть до неї.
  • Поверніть нову гілку назад до точки, з якої ви хочете запустити нову базу.
  • Потім, (ось ключовий момент) вишня вибирає наступні коміти, які ви насправді хочете застосувати після цього, з початкової гілки до нової та пропускаєте коміти, які ви більше не хочете (тобто ті, які ви видаляєте).
  • За бажанням перейменуйте вихідну гілку на щось, що вказує на її старий код, а потім перейменуйте нову гілку на те, що називалася оригінальною.
  • Нарешті, натисніть зміни на віддаленому репо (якщо використовується). Ймовірно, вам доведеться застосувати «примусовий поштовх». Якщо у ваших співавторів виникають проблеми з витяганням версій, їм буде найпростіше просто клонувати репо знову з віддаленого джерела. Так чи інакше, ви, швидше за все, захочете поговорити з ними, якщо все одно вириваєте коміти з середини вашої історії!

Ось інформація про збір вишні: що означає комітування збору вишні за допомогою git?

Ось деякі з цього з Tortoise Git (як я щойно зробив). Безумовно, простіше використовувати утиліту gui для таких видів операцій! Вишневий пиріг за допомогою TortoiseGit


6
Це мала бути головна відповідь!
— MadOgre

Хороший спосіб використовувати вишневий пікінг, це рішення навіть краще, коли ви хочете "пропустити" більше одного коміту.
— Джонні Віллер,

Насправді не звертаючись до вихідного питання. Хоча запропоноване рішення працює, воно набагато більш трудомістке / незручне, і IMO не приносить ніякої користі. Якщо гілка вже була висунута (і використовується в дикій природі), стратегія повернення - це, мабуть, відповідь. Якщо ні, інтерактивне перебазування та усунення порушуючого коміту - ось що я б використав. Якщо його натиснули, але ми знаємо, що ним ніхто не користується, ви все одно можете піти за допомогою перебазування з подальшим силовим натисканням.
— raduw
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.