15. Видалення комітів з гілки (revert)

Цілі

  • Навчитися видаляти останні коміти з гілки.

revert з попереднього розділу є потужною командою, яка дозволяє скасувати будь-які коміти у репозиторії. Однак, і оригінальний і «скасований» коміти видно в історії гілки (при використанні команди git log).

Часто ми робимо коміт, і відразу розуміємо, що це була помилка. Було б непогано мати команду «повернення», яка дозволила б нам удати, що неправильного коміту ніколи й не було. Ця команда навіть запобігла б появі небажаного коміту в історії git log.

01 Команда reset

Ми вже бачили команду reset і використовували її для узгодження області підготовки з обраним комітом (у попередньому уроці ми використовували коміт HEAD).

Якщо виконати команду reset із зазначенням посилання на коміт (позначка HEAD, хеш коміту, назва тегу або гілки тощо), то команда...

  1. Змінить поточну гілку, щоб вона вказувала на зазначений коміт.
  2. Опціонально відкотить область підготовки до відповідності із зазначеним комітом.
  3. Опціонально відкотить робочу директорію до відповідності із зазначеним комітом.

02 Перевірте нашу історію

Перевірмо нашу історію комітів.

Виконайте

git log

Результат

$ git log
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (HEAD -> main) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]

Ми бачимо, що два останніх коміти в цій гілці - «Oops» і «Revert Oops». Видалімо їх за допомогою команди відкочування reset.

03 Для початку позначте цю гілку

Але перш ніж видалити коміт, позначмо останній коміт тегом, щоб потім можна було його знайти.

Виконайте

git tag oops

Результат

$ git log
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (HEAD -> main, tag: oops) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
b7614c1 2023-11-28 | Added HTML header (tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]

04 Відкіт до коміту, що передує до oops

Дивлячись на історію логу (див. вище), ми бачимо, що коміт з тегом v1 є комітом, попереднім до помилкового коміту. Скиньмо гілку до цієї точки. Оскільки гілка має тег, ми можемо використовувати ім'я тегу в команді відкоту reset (якщо вона не має тега, ми можемо використовувати хеш коміта).

Виконайте

git reset --hard v1
git log

Результат

$ git reset --hard v1
HEAD is now at b7614c1 Added HTML header
$ git log
b7614c1 2023-11-28 | Added HTML header (HEAD -> main, tag: v1) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]

Наша гілка main тепер вказує на коміт v1, а комітів "Revert Oops" і "Oops" в гілці вже немає. Параметр --hard вказує, що робоча директорія повинна бути відновлена до того стану, що відповідає HEAD-коміту гілки.

05 Нічого ніколи не губиться

Що ж трапляється з помилковими комітами? Виявляється, що коміти все ще знаходяться в репозиторії, ми все ще можемо на них посилатися. Пам'ятаєте, на початку цього уроку ми створили для скасованого коміту тег oops? Подивімось на всі коміти.

Виконайте

git log --all

Результат

$ git log --all
b7614c1 2023-11-28 | Added HTML header (HEAD -> main, tag: v1) [Alexander Shvets]
86364a1 2023-11-28 | Revert "Oops, we didn't want this commit" (tag: oops) [Alexander Shvets]
46afaff 2023-11-28 | Added standard HTML page tags (tag: v1-beta) [Alexander Shvets]
6a44bec 2023-11-28 | Oops, we didn't want this commit [Alexander Shvets]
78433de 2023-11-28 | Added h1 tag [Alexander Shvets]
5836970 2023-11-28 | Initial commit [Alexander Shvets]

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

06 Небезпека відкочування

Відкочування в локальних гілках, як правило, безпечне. Наслідки будь-який «аварії», як правило, можна відновити простим відкочуванням до потрібного коміту.

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