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

НАЗВА

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

СИНОПСИС

git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
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 виконує одну з таких дій:

  1. Команда git reset [<режим>] <коміт> змінює коміт, на який вказує HEAD. Це дозволяє скасувати різні операції Git, наприклад, фіксацію, злиття, перебазування та витяг даних.

  2. Якщо ви вказуєте файли або теки або передаєте аргумент --patch, команда git reset оновлює версію вказаних файлів, що знаходиться у стадії підготовки до злиття.

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

    Встановлення вершини поточної гілки (HEAD) так, щоб вона вказувала на <commit>. Залежно від <mode>, також оновлюються робоча тека та/або індекс відповідно до вмісту <commit>. Зазвичай <commit> дорівнює HEAD. Перед виконанням операції ORIG_HEAD встановлюється на вершину поточної гілки.

    Значення <mode> повинно бути одним з наступних (стандартно — --mixed):

    --mixed

    Залишати робочу теку без змін. Оновити індекс відповідно до нового HEAD, щоб нічого не потрапило до стадії підготовки до коміту.

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

    --soft

    Не змінювати файли робочого дерева та індекс. Наприклад, якщо у вас немає змін, що знаходяться у стадії підготовки до фіксації, ви можете скористатися командою git reset --soft HEAD~5; git commit, щоб об’єднати останні 5 комітів в один. Це працює навіть у разі наявності змін у робочому дереві, яке залишається незмінним, але таке використання може спричинити плутанину.

    --hard

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

    --merge

    Скинути індекс та оновити файли в робочому дереві, які мають відмінності між <commit> та HEAD, але залишити ті, що відрізняються між індексом та робочим деревом (тобто ті, зміни до яких ще не додано). В основному використовується для скидання не обʼєднаних записів індексу, таких як ті, що залишаються після виконання команд git am -3 або git switch -m у певних ситуаціях. Якщо файл, який має відмінності між <commit> та індексом, містить зміни, що не додані до stage, скидання буде перервано.

    --keep

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

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

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

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

    Для всіх вказаних файлів або тек, встановити версію в stage, на версію з вказаного коміту або дерева (як правило, це HEAD).

    Це означає, що команда git reset <pathspec> є протилежністю команди git add <pathspec>: вона прибирає всі зміни зі stage для вказаних файлів або тек. Це еквівалентно команді git restore --staged <pathspec>....

    У цьому режимі команда git reset оновлює лише індекс (не оновлюючи HEAD та файли робочого дерева). Якщо ви хочете оновити як файли, так і записи індексу, скористайтеся командою git-restore[1].

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

    Інтерактивно обирає зміни з різниці між індексом та вказаним комітом або деревом (як правило, це HEAD). Індекс змінюється з урахуванням обраних змін.

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

Дивіться розділ «Скидання, відновлення та повернення до початкового стану» в 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>

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

--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]