Git
Chapters ▾ 2nd Edition

2.4 Основи Git - Скасування речей

Скасування речей

У будь-який момент, ви можете забажати щось скасувати. Тут, ми розглянемо декілька базових утиліт для скасування змін, що ви зробили. Будьте обережними, адже ви не завжди в змозі скасувати деякі з цих скасувань. Це одна з не багатьох ділянок, де Git може втратити вашу працю, якщо ви помилитесь.

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

$ git commit --amend

Ця команда бере ваш індекс та використовує його для коміту. Якщо ви нічого не змінили з останнього коміту (наприклад, ви виконуєте цю команду відразу після попереднього коміту), то ваш знімок буди виглядати так само, та все що ви можете зробити — це змінити повідомлення коміту.

З’явиться вже знайомий редактор повідомлення коміту, проте в ньому вже міститься повідомлення вашого попереднього коміту. Ви можете відредагувати повідомлення як завжди, тільки воно перепише ваш попередній коміт.

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

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

У підсумку ви отримаєте єдиний коміт — другий коміт замінить результати першого.

Note

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

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

Вилучання файла з індексу

Наступні дві секції покажуть, що робити зі зміни в індексі та робочій теці. Гарно те, що команда, яку ви використовуєте для визначення статусу цих двох областей, також нагадує вам, як скасувати зміни в них. Наприклад, припустімо, що ви змінили два файли та хочете зберегти їх у двох окремих змінах, проте випадково набрали git add * та проіндексували їх обох. Як ви можете вилучити один з них? Команда git status нагадує вам:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

Прямо під текстом “Changes to be committed” (зміни, що буде збережено), написано "use git reset HEAD <file>... to unstage" (скористайтесь git reset HEAD <file>... щоб вилучити) Отже, скористаймося цією порадою, щоб вилучити файл CONTRIBUTING.md:

$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M	CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Команда трохи дивна, проте працює. Файл CONTRIBUTING.md змінений але неіндексований.

Note

Команда git reset і справді може бути небезпечною, особливо разом з опцією --hard. Втім, в описаному вище випадку, файл у робочій теці не змінюється жодним чином, тож вона відносно безпечна.

Поки що цей магічний виклик це все, що вам треба знати про команду git reset. Ми розповімо набагато докладніше про reset та як його використовувати щоб робити дійсно цікаві речі у Усвідомлення скидання (reset).

Скасування змін у зміненому файлі

Раптом ви вирішили, що всі зміни до файлу CONTRIBUTIG.md — зайві? Як їх легко скасувати — повернути файл до стану, в якому він був під час вашого останнього коміту (або не вашого, байдуже як ви його отримали)? На щастя, git status розповідає вам і про це. У виводі останнього прикладу, неіндексована область виглядає так:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Тут чітко розповідають, як скасувати ваші зміни. (третій рядок перекладається (використайте "git checkout -- <file>..." щоб скасувати зміни у вашій робочій директорії)) Так і зробимо:

$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Як ви бачите, ваших змін більше нема.

Important

Памʼятайте, команда git checkout -- <файл> небезпечна. Будь-які зроблені зміни зникли — Git просто скопіював інший файл поверх них. Ніколи не використовуйте цю команду, якщо у вас нема абсолютної впевненості, що цей файл вам не потрібен.

Якщо ви бажаєте зберегти зроблені зміни до файлу, проте вам необхідно їх тимчасово прибрати, ми розповімо про ховання та гілки в Галуження в git; це зазвичай кращі засоби.

Пам’ятайте, все збережене в комітах Git майже завжди може бути відновлено. Навіть коміти у видалених гілках чи коміти, переписані за допомогою --amend, можуть бути відновлені (дивіться Відновлення даних задля відновлення даних). Однак, будь-що втрачене до коміту ви навряд чи колись ще раз побачите.