українська мова ▾ Topics ▾ Latest version ▾ git-reset last updated in 2.53.0

НАЗВА

git-reset — Скидання поточного HEAD до вказаного стану

СИНОПСИС

git reset [-q] [<tree-ish>] [--] <pathspec>…​
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…​]
git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]

ОПИС

У перших трьох формах копіює записи з <tree-ish> до індексу. В останній формі встановіть поточну вершину гілки (HEAD) на <commit>, за бажанням змінюючи індекс та робоче дерево відповідно. <tree-ish>/<commit> зазвичай має значення HEAD у всіх формах.

git reset [-q] [<tree-ish>] [--] <pathspec>...
git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]

Ці форми скидають записи індексу для всіх шляхів, що відповідають <pathspec >, до їхнього стану в <tree-ish>. (Це не впливає на робоче дерево чи поточну гілку.)

Це означає, що git reset <pathspec> є протилежністю git add <pathspec>. Ця команда еквівалентна git restore [--source=<tree-ish>] --staged <pathspec>....

Після запуску git reset <pathspec> для оновлення запису індексу, ви можете скористатися git-restore[1] для перевірки вмісту індексу до робочого дерева. Або ж, використовуючи git-restore[1] та вказавши коміт з --source, ви можете скопіювати вміст шляху з коміту до індексу та до робочого дерева одночасно.

git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>...]

Інтерактивно обирає фрагменти в відмінності між індексом та <tree-ish> (зазвичай HEAD). Вибрані фрагменти застосовуються до індексу у зворотному порядку.

Це означає, що git reset -p є протилежністю git add -p, тобто ви можете використовувати його для вибіркового скидання фрагментів. Дивіться розділ "Інтерактивний режим" у git-add[1], щоб дізнатися, як працювати з режимом --patch.

git reset [<mode>] [<commit>]

Ця форма скидає поточну вершину гілки до <commit> та, можливо, оновлює індекс (скидаючи його до дерева <commit>) та робочого дерева залежно від <mode>. Перед операцією ORIG_HEAD встановлюється на вершину поточної гілки. Якщо <mode> пропущено, стандартно використовується значення --mixed. <mode> має бути одним із наступних:

--soft

Цей режим взагалі не впливає на файл індексу та робоче дерево (але, як і всі інші режими, встановлює вершину на <commit>). У результаті всі змінені файли залишаються у стані «Зміни, що підлягають фіксації», як це відображає команда git status.

--mixed

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

Якщо вказано -N, видалені шляхи позначаються як такі, що мають бути додані (див. git-add[1]).

--hard

Скидає індекс та робоче дерево. Усі зміни у відстежуваних файлах у робочому дереві, внесені після <commit>, будуть відкинуті. Усі невідстежувані файли чи теки, що заважають запису відстежуваних файлів, просто видаляються.

--merge

Скидає індекс та оновлює файли в робочому дереві, які відрізняються між <commit> та HEAD, але зберігає ті, що відрізняються між індексом та робочим деревом (тобто ті, зміни до яких ще не додано). Якщо файл, який відрізняється між <commit> та індексом, містить неіндексовані зміни, скидання переривається.

Іншими словами, опція --merge виконує дію, схожу на команду git read-tree -u -m <commit>, але при цьому зберігає необʼєднані записи індексу.

--keep

Скидає записи індексу та оновлює файли в робочому дереві, які відрізняються між <commit> та HEAD. Якщо файл, що відрізняється між <commit> та HEAD, містить локальні зміни, операція скидання переривається.

--recurse-submodules
--no-recurse-submodules

Під час оновлення робочого дерева використання параметра --recurse-submodules також призведе до рекурсивного скидання робочого дерева всіх активних субмодулів відповідно до коміту, записаного в суперпроєкті, а також до встановлення HEAD субмодулів у стан відʼєднаного на рівні цього коміту.

Дивіться розділ «Скидання, відновлення та повернення до початкового стану» в git[1], щоб ознайомитися з відмінностями між цими трьома командами.

ОПЦІЇ

-q
--quiet

Тихий режим, виводяться повідомлення тільки про помилки.

--refresh
--no-refresh

Оновлює індекс після змішаного скидання. Стандартно увімкнено.

--pathspec-from-file=<файл>

Специфікатор шляху передається у <файл> замість аргументів командного рядка. Якщо <файл> дорівнює -, то використовується стандартний ввід. Елементи специфікатора шляху розділяються символами LF або CR/LF. Елементи специфікатора шляху можна брати в лапки, як це пояснено для змінної конфігурації core.quotePath (див. git-config[1]). Див. також --pathspec-file-nul та глобальну змінну --literal-pathspecs.

--pathspec-file-nul

Має сенс лише з --pathspec-from-file. Елементи Pathspec розділяються символом NUL, а всі інші символи (включно з символами нового рядка та лапками) сприймаються буквально.

-U<n>
--unified=<n>

Створює файли відмінностей (diff) з <n> рядками контексту. Стандартно використовується diff.context або 3, якщо параметр конфігурації не встановлено.

--inter-hunk-context=<n>

Показує контекст між фрагментами відмінностей (diff hunks), до вказаної <кількості> рядків, таким чином обʼєднуючи фрагменти, що знаходяться близько один до одного. Стандартно використовується значення diff.interHunkContext або 0, якщо параметр конфігурації не встановлено.

--

Не інтерпретує жодних додаткових аргументів як опції.

<pathspec>...

Обмежує шляхи, на які впливає операція.

Для отримання додаткової інформації див. елемент «pathspec» у gitglossary[7].

ПРИКЛАДИ

Скасування додавання
$ edit                                     (1)
$ git add frotz.c filfre.c
$ mailx                                    (2)
$ git reset                                (3)
$ git pull git://info.example.com/ nitfol  (4)
  1. Ви із задоволенням працюєте над чимось і бачите, що зміни в цих файлах в порядку. Ви не хочете бачити їх під час виконання команди git diff, оскільки плануєте працювати над іншими файлами, а зміни в цих файлах відвертають вашу увагу.

  2. Хтось просить вас зробити pull, і зміни виглядають таким що гідні обʼєднання.

  3. Однак, ви вже забруднили індекс (тобто ваш індекс не відповідає коміту HEAD). Але ви знаєте, що вилучення, яке ви збираєтеся зробити, не впливає на frotz.c або filfre.c, тому ви скасуєте зміни індексу для цих двох файлів. Ваші зміни в робочому дереві залишаються.

  4. Тоді ви можете виконати pull і merge, залишивши зміни frotz.c та filfre.c у робочому дереві.

Скасувати коміт та повторити
$ git commit ...
$ git reset --soft HEAD^      (1)
$ edit                        (2)
$ git commit -a -c ORIG_HEAD  (3)
  1. Зазвичай це роблять, коли ви згадали, що щойно зафіксований коміт є неповним, або ви помилилися у написанні повідомлення про коміт, або й те, й інше. Робоче дерево залишається таким, яким воно було до виконання команди «reset».

  2. Внесіть виправлення у файли робочого дерева.

  3. Команда «reset» копіює стару вершину в .git/ORIG_HEAD; повторіть коміт, починаючи з його повідомлення в журналі. Якщо вам не потрібно додатково редагувати повідомлення, ви можете замість цього вказати опцію -C.

    Дивіться також опцію --amend для git-commit[1].

Скасувати коміт, зробивши його тематичною гілкою
$ git branch topic/wip          (1)
$ git reset --hard HEAD~3       (2)
$ git switch topic/wip          (3)
  1. Ви зробили кілька комітів, але зрозуміли, що їх передчасно помістити в гілку master. Ви хочете продовжити їх доопрацювання в тематичній гілці, тому створіть гілку topic/wip з поточної гілки HEAD.

  2. Відкотіть гілку master назад, щоб позбутися цих трьох комітів.

  3. Перейдіть до гілки topic/wip та продовжуйте роботу.

Скасувати коміти назавжди
$ git commit ...
$ git reset --hard HEAD~3   (1)
  1. Останні три коміти (HEAD, HEAD^ та HEAD~2) були поганими, і ви не хочете їх більше ніколи бачити. Не робіть цього, якщо ви вже передали ці коміти комусь іншому. (Див. розділ "ВІДНОВЛЕННЯ З ВИСХІДНОГО ПЕРЕБАЗУВАННЯ" в git-rebase[1], щоб дізнатися про наслідки цього.)

Скасування merge або pull
$ git pull                         (1)
Автоматичне об'єднання нітфолів
КОНФЛІКТ (контент): Конфлікт злиття в nitfol
Автоматичне злиття не вдалося; виправте конфлікти та зафіксуйте результат.
$ git reset --hard                 (2)
$ git pull . topic/branch          (3)
Оновлення з 41223... до 13134...
Перемотка вперед
$ git reset --hard ORIG_HEAD       (4)
  1. Спроба оновлення з основної платформи призвела до численних конфліктів; ви не були готові витрачати багато часу на злиття зараз, тому вирішили зробити це пізніше.

  2. Команда «pull» не створила коміту злиття, тому git reset --hard (що є синонімом git reset --hard HEAD) очищає індексний файл і робоче дерево від зайвих даних.

  3. Втягування змін з тематичної гілки в поточну гілку, що призводить по переходу вперед [fast-forward].

  4. Але ви вирішили, що тематична гілка ще не готова для публічного використання. «pull» або «merge» завжди залишає оригінальну вершину поточної гілки в ORIG_HEAD, тому жорстке скидання до неї повертає ваш індексний файл і робоче дерево до того стану та скидає вершину гілки до того коміту.

Скасувати злиття або витягування всередині забрудненого робочого дерева
$ git pull                         (1)
Автоматичне об'єднання nitfol
Об'єднання, виконане рекурсивним способом.
 nitfol                |   20 +++++----
 ...
$ git reset --merge ORIG_HEAD      (2)
  1. Навіть якщо у вашому робочому дереві є локальні зміни, ви можете сміливо виконати git pull, коли знаєте, що зміни в іншій гілці не перетинаються з ними.

  2. Після перевірки результату злиття ви можете виявити, що зміни в іншій гілці незадовільні. Виконання команди git reset --hard ORIG_HEAD дозволить вам повернутися до попереднього стану, але призведе до відкидання ваших локальних змін, чого ви не хочете. Команда git reset --merge залишає ваші локальні зміни.

Перерваний робочий процес

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

$ git switch feature  ;# ви працювали в гілці "feature" і
$ work work work      ;# вас перервали
$ git commit -a -m "snapshot WIP"                 (1)
$ git switch master
$ fix fix fix
$ git commit ;# коміт з реальним логом
$ git switch feature
$ git reset --soft HEAD^ ;# повернення до WIP     (2)
$ git reset                                       (3)
  1. Цей коміт буде видалено, тому повідомлення журналу про викидання буде прийнятним.

  2. Ця операція видаляє коміт WIP з історії комітів і повертає робоче дерево до стану, що передував створенню цього знімка.

  3. На цьому етапі індексний файл все ще містить усі зміни WIP, які ви зафіксували як snapshot WIP. Ця операція оновлює індекс, щоб файли WIP відображалися як незафіксовані.

    Див. також git-stash[1].

Скинути один файл в індексі

Припустимо, ви додали файл до свого індексу, але пізніше вирішили, що не хочете додавати його до свого коміту. Ви можете видалити файл з індексу, зберігаючи зміни, за допомогою команди git reset.

$ git reset -- frotz.c                      (1)
$ git commit -m "Зафіксувати файли в індексі"     (2)
$ git add frotz.c                           (3)
  1. Видаляє файл з індексу, залишаючи його в робочій теці.

  2. Зберігає всі інші зміни в індексі.

  3. Знову додає файл до індексу.

Зберегти зміни в робочому дереві, відкинувши деякі попередні коміти

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

$ git tag start
$ git switch -c branch1
$ edit
$ git commit ...                            (1)
$ edit
$ git switch -c branch2                     (2)
$ git reset --keep start                    (3)
  1. Фіксує ваші перші редагування в гілці branch1.

  2. В ідеальному випадку ви могли б зрозуміти, що попередній коміт не належав до нової теми, коли створювали гілку branch2 і переходили до неї (тобто за допомогою команди git switch -c branch2 start), але ніхто не ідеальний.

  3. Але ви можете скористатися reset --keep, щоб видалити небажаний коміт після переходу на branch2.

Розділити коміт на послідовність комітів

Припустимо, що ви створили багато логічно незалежних змін і зафіксували їх в одному коміті. Згодом ви вирішили, що було б краще, якби кожен логічний блок був пов’язаний із власним комітом. Ви можете скористатися командою git reset, щоб повернути історію назад, не змінюючи вміст локальних файлів, а потім послідовно використовувати git add -p для інтерактивного вибору фрагментів, які слід включити до кожного коміту, та git commit -c для попереднього заповнення повідомлення про коміт.

$ git reset -N HEAD^                        (1)
$ git add -p                                (2)
$ git diff --cached                         (3)
$ git commit -c HEAD@{1}                    (4)
...                                         (5)
$ git add ...                               (6)
$ git diff --cached                         (7)
$ git commit ...                            (8)
  1. Спочатку скиньте історію на один коміт назад, щоб видалити початковий коміт, але залишити робоче дерево з усіма змінами. Параметр -N гарантує, що всі нові файли, додані до HEAD, залишаться позначеними, щоб команда git add -p змогла їх знайти.

  2. Далі ми інтерактивно вибираємо фрагменти diff для додавання за допомогою команди git add -p. Git по черзі запитає вас про кожен фрагмент diff, і ви зможете використовувати прості команди, такі як «так, включити це», «ні, не включати це» або навіть дуже потужну функцію «редагування».

  3. Коли ви будете задоволені фрагментами, які хочете включити, слід перевірити, що було підготовлено для першого коміту, за допомогою git diff --cached. Це покаже всі зміни, які були переміщені в індекс і мають бути зафіксовані.

  4. Далі зафіксуйте зміни, що зберігаються в індексі. Опція -c вказує на попереднє заповнення повідомлення коміту з оригінального повідомлення, з якого ви почали у першому коміті. Це допомагає уникнути повторного набору тексту. HEAD@{1} — це спеціальна нотація для коміту, на якому перебував HEAD до оригінального коміту скидання (1 зміна тому). Дивіться git-reflog[1] для детальнішої інформації. Ви також можете використовувати будь-яке інше дійсне посилання на коміт.

  5. Ви можете повторити кроки 2-4 кілька разів, щоб розбити вихідний код на будь-яку кількість комітів.

  6. Тепер ви розділили багато змін на окремі коміти та, можливо, більше не використовуєте режим patch команди git add для вибору всіх незбережених змін.

  7. Ще раз перевірте, чи ви включили те, що хотіли. Ви також можете переконатися, що git diff не показує жодних змін, які залишилися для подальшої фіксації.

  8. І нарешті створіть фінальний коміт.

ОБГОВОРЕННЯ

У таблицях нижче показано, що відбувається під час роботи:

git reset --option target

щоб скинути значення HEAD до іншого коміту (target) з різними параметрами скидання залежно від стану файлів.

У цих таблицях A, B, C та D — це різні стани файлу. Наприклад, перший рядок першої таблиці означає, що якщо файл знаходиться у стані A у робочому дереві, у стані B в індексі, у стані C в HEAD та у стані D у цілі, то git reset --soft target залишить файл у робочому дереві у стані A, а в індексі — у стані B. Команда скидає (тобто переміщує) HEAD (тобто вершину поточної гілки, якщо ви на ній перебуваєте) до target (що має файл у стані D).

робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 A       B     C    D     --soft   A       B     D
			  --mixed  A       D     D
			  --hard   D       D     D
			  --merge (заборонено)
			  --keep  (заборонено)
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 A       B     C    C     --soft   A       B     C
			  --mixed  A       C     C
			  --hard   C       C     C
			  --merge (заборонено)
			  --keep   A       C     C
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 B       B     C    D     --soft   B       B     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge  D       D     D
			  --keep  (заборонено)
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 B       B     C    C     --soft   B       B     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  C       C     C
			  --keep   B       C     C
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 B       C     C    D     --soft   B       C     D
			  --mixed  B       D     D
			  --hard   D       D     D
			  --merge (заборонено)
			  --keep  (заборонено)
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 B       C     C    C     --soft   B       C     C
			  --mixed  B       C     C
			  --hard   C       C     C
			  --merge  B       C     C
			  --keep   B       C     C

Команда git reset --merge призначена для скидання стану після злиття, що призвело до конфлікту. Будь-яка операція злиття гарантує, що файл у робочому дереві, який бере участь у злитті, не містить локальних змін відносно індексу до початку операції, а також що результат записується у робоче дерево. Отже, якщо ми бачимо деякі відмінності між індексом і цільовим об’єктом, а також між індексом і робочим деревом, це означає, що ми не скидаємо стан, який залишився після операції злиття, що завершилася невдачею через конфлікт. Ось чому ми забороняємо використання опції --merge у цьому випадку.

Команда git reset --keep призначена для видалення деяких останніх комітів у поточній гілці з одночасним збереженням змін у робочому дереві. Якщо між змінами у коміті, який ми хочемо видалити, та змінами у робочому дереві, які ми хочемо зберегти, можуть виникнути конфлікти, виконання команди reset заборонено. Ось чому це заборонено, якщо є зміни як між робочим деревом і HEAD, так і між HEAD і ціллю. Для безпеки це також заборонено, коли є не обʼєднані записи.

У наступних таблицях показано, що відбувається, коли є не обʼєднані записи:

робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 X       U     A    B     --soft  (заборонено)
			  --mixed  X       B     B
			  --hard   B       B     B
			  --merge  B       B     B
			  --keep  (заборонено)
робочий індекс HEAD цільовий робочий індекс HEAD
----------------------------------------------------
 X       U     A    A     --soft  (заборонено)
			  --mixed  X       A     A
			  --hard   A       A     A
			  --merge  A       A     A
			  --keep  (заборонено)

X означає будь-який стан, а U означає необʼєднаний індекс.

GIT

Частина набору git[1]