Как да отмените локален git комит

Проблемът ми е, че промених файл, напр.: README, добавих нов ред „това за моя тестов ред“ и записах файла, след което издадох следните команди

git status

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")


git add README

git commit -a -m 'To add new line to readme'

Не изпратих кода в github, сега искам да отменя този ангажимент.

За това използвах

git reset --hard HEAD~1

Но загубих новодобавения ред „това за моя тестов ред“ от файла README. Това не трябва да се случва. Имам нужда съдържанието да е там. Има ли начин да запазя съдържанието и да анулирам локалния си ангажимент?


person Amal Kumar S    schedule 31.01.2011    source източник
comment
Изглежда, че определено не питате за git revert, което създава нов ангажимент с обратната разлика на върнатия комит. Нулирането просто насочва текущия ви клон към различен ангажимент, в този случай този преди ангажимента, който искате да забравите.   -  person Cascabel    schedule 31.01.2011
comment
NB: Може би си струва да се спомене, че git-commit може да прекъсне, ако оставите съобщението празно, така че ако всъщност не сте завършили ангажимента, това може да бъде полезно.   -  person GKFX    schedule 24.02.2014


Отговори (6)


Просто използвайте git reset без флага --hard:

git reset HEAD~1

PS: В базирани на Unix системи можете да използвате HEAD^, което е равно на HEAD~1. В Windows HEAD^ няма да работи, защото ^ сигнализира за продължение на реда. Така че вашият команден ред просто ще ви попита More?.

person Koraktor    schedule 31.01.2011
comment
Между другото, това се нарича --mixed в ръководство. - person Josh Lee; 31.01.2011
comment
По-новите версии на Git дори позволяват @^ като стенограма за HEAD^. - person Koraktor; 16.09.2014
comment
Не знам какво направи това, но много файлове се появиха в моя списък с промени, файлове, които не докоснах - person frankelot; 05.02.2015
comment
@feresr Ако наистина не сте докоснали тези файлове в последния комит или в работното дърво, това е причинено от други несъответствия в работното ви дърво, напр. Вие сте на Windows и окончанията на файловете не съвпадат. - person Koraktor; 06.02.2015
comment
Имам 10 чакащи ангажимента там поради проблем с размера... и вашето решение е изолираната буря през сухо лято... ^_^ - person RYO ENG Lian Hu; 28.04.2016
comment
да! тази линия избегна кметска катастрофа... добър, пазач! - person Pedro Emilio Borrego Rached; 05.09.2019
comment
възможно ли е да нулирате всички ангажименти от една страна? - person Webwoman; 08.09.2019

Използвайте --soft вместо --hard флаг:

git reset --soft HEAD^
person TpED    schedule 10.08.2012
comment
можете ли да обясните разликата между 2 флага? - person John Giotta; 05.05.2015
comment
Ако отворите Package Manager Console и стартирате този git reset --soft HEAD^, той прави това, което искате (и това, от което имах нужда). - person David Cornelson; 03.12.2015
comment
@JohnGiotta - git reset --soft HEAD^ ще премахне последния локален (неизпратен) ангажимент, но ще запази промените, които сте направили - person fider; 25.04.2016
comment
@fider Спасител! Не съм сигурен дали приетият отговор все още работи, но това трябва да е точният отговор, необходим на OP. - person Babu; 27.12.2017
comment
git reset --soft HEAD~ на windows - person Jack0fshad0ws; 14.05.2020

Ако сте в средата на ангажимент (т.е. вече сте във вашия редактор), можете да го отмените, като изтриете всички редове над първия #. Това ще прекрати ангажирането.

Така че можете да изтриете всички редове, така че съобщението за ангажиране да е празно, след което да запишете файла:

—

След това ще получите съобщение, което казва Aborting commit due to empty commit message..

person inostia    schedule 09.03.2017
comment
Това е точно това, което търсих! Този отговор се нуждае от повече гласове за :) - person jdunk; 11.06.2017
comment
За информация, това също работи, ако се опитвате да прекъснете rebase -i mybranchname - person inostia; 30.04.2018
comment
това наистина трябва да е отговорът. - person Xaxxus; 07.01.2021

Първото нещо, което трябва да направите, е да определите дали искате да запазите локалните промени, преди да изтриете съобщението за ангажиране.

Използвайте git log, за да покажете текущите съобщения за ангажимент, след това намерете commit_id преди ангажимента, който искате да изтриете, а не ангажимента, който искате да изтриете.

Ако искате да запазите локално променените файлове и просто да изтриете съобщението за ангажиране:

git reset --soft commit_id

Ако искате да изтриете всички локално променени файлове и съобщението за ангажимент:

git reset --hard commit_id

Това е разликата между мека и твърда

person mistdon    schedule 02.09.2018
comment
Мисля, че е точно обратното. - person Ruff9; 10.09.2018

Можете да кажете на Git какво да прави с вашия индекс (набор от файлове, които ще станат следващият комит) и работна директория, когато извършвате git reset, като използвате един от параметрите:

--soft: Само ангажиментите ще бъдат нулирани, докато индексът и работната директория не се променят.

--mixed: Това ще нулира индекса, за да съответства на HEAD, докато работната директория няма да бъде докосната. Всички промени ще останат в работната директория и ще се появят като променени.

--hard: Нулира всичко (комити, индекс, работна директория), за да съответства на HEAD.

Във вашия случай бих използвал git reset --soft, за да запазя вашите променени промени в индекса и работната директория. Не забравяйте да проверите това за по-подробно обяснение.

person Nesha Zoric    schedule 29.05.2018

Използвайте командата по-долу:

$ git reset HEAD~1

След това можете също да видите файлове, които се връщат обратно като отговора по-долу.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
person Omkar    schedule 14.05.2018