У чому різниця між 'git reset --hard HEAD ~ 1' та 'git reset --soft HEAD ~ 1'?


Відповіді:


184

git resetзнає п’ять «режимів»: м’який, змішаний, жорсткий, злиття та збереження. Я почну з перших трьох, оскільки саме такі режими ви зазвичай зустрічаєте. Після цього ви знайдете приємний маленький бонус, тому стежте за оновленнями.

м'який

Під час використання git reset --soft HEAD~1ви видалите останню фіксацію з поточної гілки, але зміни у файлі залишатимуться у вашому робочому дереві . Крім того, зміни залишатимуться у вашому індексі, тому наступні дії з а git commitстворить коміт із точно такими ж змінами, як і коміт, який ви "видаляли" раніше.

змішані

Це режим за замовчуванням і дуже схожий на м’який. При "видаленні" коміту з git reset HEAD~1вами ви все одно збережете зміни у вашому робочому дереві, але не в індексі; так що якщо ви хочете "повторити" git addкоміт , вам доведеться додати зміни ( ) перед комітуванням.

важко

Під час використання git reset --hard HEAD~1ви втратите всі незавершені зміни на додаток до змін, введених в останньому коміті. Зміни не залишаться у вашому робочому дереві, тому виконання git statusкоманди покаже вам, що у вас немає змін у вашому сховищі.

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

Бонус

тримати

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

Цей режим особливо корисний, коли у вас є купа змін і ви хочете перейти на іншу гілку, не втрачаючи ці зміни - наприклад, коли ви почали працювати над неправильною гілкою.


Ви можете прочитати більше про це в документації до git reset .

Примітка.
Виконуючи git resetвидалення коміту, коміт насправді не втрачений, просто немає посилання, що вказує на нього або будь-яке з його дочірніх елементів. Ви все ще можете відновити коміт, який було "видалено" git reset, знайшовши його ключ SHA-1, наприклад за допомогою такої команди, як git reflog.


1
Я не згоден з тим, що ці 3 ми зазвичай маємо використовувати. Вони були трьома, які були вперше доступні, тому люди говорять про них ще 3, але --hardмайже ніколи не є правильним, оскільки --keepце набагато безпечніше і стосується більшості сенаторів, де --hardпрацює. Навчання пальців користуванню --keepможе вас врятувати, одного дня ...
Матьє Мой,

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

Щоб додати трохи більше деталей, після скидання git --soft HEAD ~ 1, використовуючи git commit --reuse-message = HEAD @ {1} для повторного використання останнього коміту зі збереженим старим індексом, як показано тут stackoverflow.com/a/ 25930432/2883282
englealuze

3
@MatthieuMoy, запізнення на три роки, але я додав розділ про keep. ;)
Саша Вольф

Як я можу скасувати останню коміт? Будь ласка, допоможіть. Якщо я використовую git reset --soft HEAD ~ 1, я отримую: fatal: неоднозначний аргумент 'HEAD ~ 1': невідома редакція або шлях не в робочому дереві. Використовуйте '-', щоб відокремити шляхи від версій, наприклад: 'git <command> [<revision> ...] - [<file> ...]'
elvis

8

Git reset має 5 основних режимів: м’який, змішаний, об’єднаний, жорсткий, тримати . Різниця між ними полягає в тому, щоб змінити чи не змінити голову, етап (індекс), робочий каталог .

Git reset --hard змінить заголовок, індекс та робочий каталог.
Git reset --soft змінить лише головку. Без змін індексу, робочого каталогу.

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

За допомогою --hard ви повністю отримуєте чистий аркуш у своєму проекті. Наче з останнього коміту не відбулося жодних змін. Якщо ви впевнені, що це те, що ви хочете, рухайтеся вперед. Але як тільки ви зробите це, ви повністю втратите останню коміту. (Примітка: є ще способи відновити втрачений коміт).


5

Це корисна стаття, яка наочно демонструє пояснення команди скидання.

https://git-scm.com/docs/git-reset

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

Що стосується дерева джерел, то я не знаю, як скасувати коміти. Швидше за все, він все одно використовував би скидання під ковдрами


+1 за посилання на офіційну документацію. Я б також згадав, git reset --helpщо цілком добре пояснює (на мій погляд) п’ять режимів або, принаймні, два режими, задані ОП.
ThanksForAllTheFish

1
Посилання порушено. Ймовірно, це поточна версія: git-scm.com/docs/git-reset
Кікі Джуелл

1

Це основна різниця між use git reset --hard та git reset --soft:

--soft

Не торкається файлу індексу або робочого дерева взагалі (але скидає головку до, як і всі режими). Це залишає всі ваші змінені файли "Зміни, які потрібно здійснити", як висловлюється git status.

--hard

Скидає індекс і робоче дерево. Будь-які зміни до відстежуваних файлів у робочому дереві відкидаються.


1
Це те, що я шукав. Короткий і точний.
Касім
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.