Питання Як скасувати останні дії в Git?


Я випадково здійснив помилкові файли Гіт, але я ще не підштовхнув зобов'язання на сервер.

Як я можу скасувати ці копії з локального сховища?


17822
2017-07-28 22:22


походження


Попередження: ви повинні робити це лише у тому випадку, якщо ви ще не підштовхнули фіксацію до віддаленого пристрою, інакше ви зіпсуватимете історію інших, хто вже витягнув фікс із пульта дистанційного керування! - thSoft
Ось дуже чіткий і ретельний пост про знищення речей в гіт, прямо з Гітуба. - Nobita
Див. Цей посібник для Git, який зобов'язується відмовитися від Local, Public і Git Branch Як відмінити Git Commits, як pro - Luzan Baral
Перш ніж публікувати нову відповідь, вважають, що на це питання вже є 65 і більше відповідей. Переконайтеся, що ваша відповідь сприяє тому, що не є серед наявних відповідей. - Sazzad Hissain Khan
Ви знаєте, що вам потрібно? git undo, Це воно. Тоді гурт репутації для зняття помилок, зроблених нами простими смертними, зникає. Впровадьте, натискаючи поточний стан на стекі git до виконання будь-якого gitкоманда Це вплине на продуктивність, тому краще додавати прапорець config як включити його. - Yimin Rong


Відповіді:


Скасувати здійснення та переробку

$ git commit -m "Something terribly misguided"             # (1)
$ git reset HEAD~                                          # (2)
<< edit files as necessary >>                              # (3)
$ git add ...                                              # (4)
$ git commit -c ORIG_HEAD                                  # (5)
  1. Це те, що потрібно скасувати
  2. Це залишає ваше робоче дерево (стан ваших файлів на диску) незмінним, але скасовує фіксацію та залишає внесені вами зміни без встановлення (таким чином, вони відображатимуться як "Зміни не встановлені для здійснення" у git status, і вам потрібно буде додати їх ще раз, перш ніж здійснювати). Якщо ви тільки хотіти додати більше змін до попередньої фіксації або змінити повідомлення про порушення1, можна використовувати git reset --soft HEAD~ замість того, що схоже git reset HEAD~ (де HEAD~ такий же, як і HEAD~1), але залишає власні внесені зміни.
  3. Зробіть виправлення для робочих файлів дерева.
  4. git add все, що ви хочете включити в свій новий внесок.
  5. Прийняти зміни, повторно використати старе повідомлення. reset скопіював стару голову до .git/ORIG_HEAD; commit з -c ORIG_HEAD відкриє редактор, який спочатку містить повідомлення журналу зі старих команд і дозволяє редагувати його. Якщо вам не потрібно редагувати повідомлення, можна скористатись -C варіант

Однак, будьте обережні, якщо ви додали будь-які нові зміни до індексу, використовуючи commit --amend додасть їх до вашого попереднього зобов'язання.

Якщо код вже натиснуто на ваш сервер, і у вас є дозволи на перезапис історії (rebase), то:

git push origin master --force

Ви також можете подивитися на цю відповідь:

Як перевести HEAD назад у попереднє місце? (Відокремлена голова)

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


1 Зауважте, однак, що вам не потрібно скидати попередню помилку, якщо ви тільки що зробили помилку у вашому вчинити повідомлення. Простіший варіант - це git reset (щоб внести зміни, які ви зробили з тих пір), а потім git commit --amend, який відкриє ваш редактор повідомлень за замовчуванням, попередньо заповнений останнім повідомленим кореспондентом.


19284
2018-06-16 17:27



І якщо злочин був для неправильної гілки, ви можете git checkout theRightBranch з усіма етапами зміни. Як я просто повинен був зробити. - Frank Shearar
Якщо ви працюєте в DOS, замість git reset --soft HEAD^ вам потрібно буде використовувати git reset --soft HEAD~1. ^ - це символ продовження в DOS, щоб він не працював належним чином. Крім того, --soft це за замовчуванням, тому ви можете пропустити його, якщо хочете, і просто скажете git reset HEAD~1. - Ryan Lundy
Крім того, у zsh вам слід навести ^, так git reset --soft 'HEAD^'... принаймні я зробив - jberryman
(Виправлення до того, що я написав вище; --mixed це за замовчуванням. --mixed означає зберігати змінені файли, але не зберігати їх у індексі. --soft буде зберігати змінені файли і зберігати їх в індексі, як вони були безпосередньо перед зміною зобов'язання. Вибачте за непорозуміння.) - Ryan Lundy
zsh користувачі можуть отримати: zsh: no matches found: HEAD^ - ви повинні бігти ^ тобто git reset --soft HEAD\^ - tnajdek


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

Скажімо, у вас є це, де C - ваша голова, а (F) - стан ваших файлів.

   (F)
A-B-C
    ↑
  master

Ти хочеш nuke commit C і ніколи не побачити це знову. Ви робите це:

git reset --hard HEAD~1

Результат:

 (F)
A-B
  ↑
master

Тепер B є головою. Тому що ви використовували --hard, ваші файли скидаються до їхнього стану при здійсненні B

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

   (F)
A-B-C
    ↑
  master

Ви можете зробити це, залишивши --hard:

git reset HEAD~1

У цьому випадку результат:

   (F)
A-B-C
  ↑
master

У обох випадках HEAD - це лише покажчик на останню фіксацію. Коли ти робиш git reset HEAD~1, ви скажете Gіt, щоб перемістити покажчик HEAD назад на одну фіксацію. Але (якщо ви не використовуєте --hard) ви залишаєте свої файли так, як вони були. Так що тепер git status показує зміни, які ви перевірили на C. Ви не втратили нічого!

Для легкого дотику ви можете навіть скасувати вашу помилку, але залиште свої файли і ваш індекс:

git reset --soft HEAD~1

Це не тільки залишає ваші файли самостійно, він навіть залишає ваш індекс поодинці Коли ти робиш git status, ви побачите, що ті самі файли знаходяться в індексі, як і раніше. Фактично, відразу після цієї команди ви могли зробити це git commit і ти будеш повторювати ті самі зобов'язання, які ти мав.

Ще одне: Припустімо, ви знищите фіксацію як і в першому прикладі але потім знайдете, що вам це потрібно? Тяжкий успіх, чи не так?

Ні, там досі спосіб повернути його. Тип git reflog і ви побачите список (часткових) команд shas, ​​в яких ви переїхали. Знайдіть, що ви зашкодили, і виконайте такі дії:

git checkout -b someNewBranchName shaYouDestroyed

Тепер ви воскресили цю фікцію. Зобов'язання фактично не знищуються в Git протягом 90 днів, тому ви, як правило, можете повернутися і врятувати одного, якого ви не мали на увазі, щоб позбутися.


9733
2018-05-29 18:16



@ dma_k, так. Або ви могли б зробити git reset --hard HEAD^^ один раз Я використовую позначення тильди (~), оскільки нотатка (^) не працює в DOS. - Ryan Lundy
Інший приємний підказ: ви можете знову приєднати гілку до фіксації, що ви його видалили з git branch -f <branch> <commit-id>. Зберігає, що потрібно повторно створити обіцяє! - naught101
Для git beginner незрозуміло, яка різниця між останніми двома варіантами (--soft і над ним). Згадування індексу не допомагає, ми насправді не знаємо, що це ще має значення. Зв'язок @ nessur між мягким і Ctrl-Z дійсно допоміг! Але я все ще не зовсім розумію різницю між двома варіантами. - Stomp
Набагато краще сказати "чому" щось працює, ніж просто сказати відповідь. Кудо до цього опису - це допомогло "отримати" гіт. - Chris Nash
Відсутність важливого пункту: якщо зазначена угода була раніше "натиснута" на пульт, будь-яка операція "відмінити", незалежно від того, наскільки проста вона, призведе до величезних страждань та страждань іншим користувачам, які мають цю компроміс у своїй локальній копії, коли вони роблять 'git тягнути' в майбутньому. Отже, якщо фіксація вже була "штовхана", робіть це замість: git revert <bad-commit-sha1-id> git push origin: - FractalSpace


Це займе деякий час, щоб зрозуміти, так що, можливо, це допоможе комусь ...

Існує два способи "скасувати" ваш останній внесок, залежно від того, чи ви вже зробили вашу публічну публікацію (відправлено до вашого віддаленого сховища):

Як відмінити місцевий внесок

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

git log
    commit 101: bad commit    # latest commit, this would be called 'HEAD'
    commit 100: good commit   # second to last commit, this is the one we want

Щоб відновити все назад, як це було до останнього зобов'язання, ми повинні це зробити reset до вчинення раніше HEAD:

git reset --soft HEAD^     # use --soft if you want to keep your changes
git reset --hard HEAD^     # use --hard if you don't care about keeping the changes you made

Зараз git log покаже, що наше останнє зобов'язання було вилучено.

Як скасувати публічну фіксацію

Якщо ви вже зробили свої зобов'язання загальнодоступними, ви хочете створити нове зобов'язання, яке буде "повертати" зміни, внесені вами у попередній причетності (поточна HEAD).

git revert HEAD

Ваші зміни тепер будуть відновлені та готові для вас:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

Щоб дізнатися більше, ознайомтеся Основи Git - відмінити речі


1750
2018-05-29 18:13



Я знайшов цю відповідь чіткіше. git revert HEAD^ це не попереднє, це попереднє попереднє. Я зробив : git revert HEAD а потім знову натиснути і це працювало :) - nacho4d
@riezebosch: ваше попередження знаходиться в неправильному місці. Ця відповідь не збиває речі, тому вона правильно створює нову помилку 102: "відновлення файлу, який я видаляв у випадку нещасного випадку" - rubo77
Це найкраща відповідь, оскільки вона не перешкоджає вашій історії git - Lukas


Додавайте / видаляйте файли, щоб отримати потрібні речі:

git rm classdir
git add sourcedir

Потім внесіть зміни:

git commit --amend

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

Зауважте, що вам слід це зробити, лише якщо ви ще не натиснули. Якщо ви натиснули, то вам доведеться просто виконати виправлення нормально.


1624
2017-07-31 09:39



Чи працює це, коли я зробив це git commit --amend і те, що я насправді мав намір зробити, це а git commit? - dbm
@ dbm, якщо ви випадково внесли зміни, скористайтеся git reset --soft <oldref>, де oldref - ідентифікатор коду до внесення змін. Ви можете використовувати git reflog щоб ідентифікувати старий ідентифікатор. Це призведе до скасування наслідків внесення змін, але залишити зміни в порядку. Тоді просто робіть git commit здійснювати як регулярне виконання. - bdonlan
@ Dennis, git commit --amend перетворює поточне дерево (тобто поетапні зміни) в commit, перезаписуючи поточну HEAD. Після цього вони більше не вважаються встановленими, оскільки вони є частиною здійснення (тобто git diff --cached порожній), але вони не "видалені" або "втрачені". - bdonlan


git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

або

git reset --hard HEAD~1

Попередження: наведене вище команда буде назавжди видалити зміни до .java файли (і будь-які інші файли), які ви хотіли зробити.

The hard reset до HEAD-1 буде встановити вашу робочу копію в стан здійснення, перш ніж ваша неправильна фіксація.


877
2018-05-25 16:04



"-" "буде позбавитися модифікованих .java-файлів у робочому каталозі, який він хотів здійснити. - Esko Luontola
Ви можете "працювати зі змінними" git stash save ", виконати жорсткий скидання, а потім" git stash pop ", щоб повернути їх, хоча я вважаю, що м'який скидання буде простішим. - Asad R.
git commit -a -m "" або git commit -am "" природно! :] - trejder
Ще одне "ярлик" - використання стискання; якщо ви хочете не вживати все (скасувати додавання git), просто git stash, потім git stash pop - seanriordan08


Змінити останню фіксацію

Замініть файли в індексі:

git rm --cached *.class
git add *.java

Тоді, якщо це приватна філія, змінити вчинення:

git commit --amend

Або, якщо це спільна гілка, внесіть нове зобов'язання:

git commit -m 'Replace .class files with .java files'


(змінити попередню передачу, використовуйте дивовижний інтерактивний ребаз)


ProTip: Додати *.class до a гітігнорувати щоб зупинити це знову.


Щоб відновити здійснення

Зміна коректування є ідеальним рішенням, якщо вам потрібно змінити останню фіксацію, але більш загальне рішення reset.

Ви можете скинути налаштування git на будь-яке зобов'язання з:

git reset @~N

Де N це кількість зобов'язань раніше HEAD, і @~ скидає попередню фіксацію.

Таким чином, замість внесення змін у копію можна використовувати:

git reset @~
git add *.java
git commit -m "Add .java files"

Перевірити git help reset, зокрема розділи про --soft  --mixed і --hard, щоб краще зрозуміти, що це робить.

Reflog

Якщо ви зіпсуватимете, ви завжди можете використати reflog, щоб знайти знищені копії:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started



678
2018-01-31 07:06



Для тих, хто читає в майбутньому - будь ласка, зауважте, що git revert це окрема команда, яка в основному "скидає" один комміт. - BKSpurgeon


Використовуйте git revert commit-id

Щоб отримати ідентифікатор, просто використовуйте git log


548
2017-12-13 10:18



Якщо ви віддані справі неправильної гілки: після повернення, перейдіть на правильну гілку і вірніше виділіть фіш. - Kris
Що це означає, черешня вибрати фіксацію? У моєму випадку, коли я редагував файл, я був у неправильному розділі. Я зробив це тоді зрозумів, що я був у неправильній галузі. Використання "git reset --soft HEAD ~ 1" повернуло мене безпосередньо перед здійсненням, але тепер, якщо я перевіряю правильну гілку, я можу відмінити зміни до файлу у неправильній гілці, а замість того, щоб зробити їх (у тому ж імені файл) у правильній гілці? - astronomerdave
Я просто використала git revert commit-id працював як чарівність. Звичайно, тоді вам доведеться внести зміни. - Casey Robinson
Я вірю, що це буде git cherry-pick <<erroneous-commit-sha>> @ astronomerdave. Від, містер майже-2-х років-пізно-до-партії. - Tom Howard


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

git reset --hard HEAD^1

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

git reset --soft HEAD^1

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

git reset HEAD

Тепер виконувані файли надходять із поетапної області в нестабілізовану область. Тепер файли готові редагувати, так що все, що ви зміните, ви хочете піти редагувати, додати його та зробити новий / новий фікс.

Більше


441
2018-04-06 13:58



@SMR, У вашому прикладі всі вказують на поточну HEAD тільки. HEAD ^ = HEAD ^ 1. Також HEAD ^ 1 = HEAD ~ 1. Коли ви використовуєте HEAD ~ 2, існує різниця між ~ та ^ символами. Якщо ви використовуєте ~ 2, це означає "перший батько першого батька" або "бабуся чи дідусь". - Madhan Ayyasamy
зрозуміло і легко зрозуміти, врятуй мою ніч! - Vladimir Ch
Очевидно, я випадково придумав цю відповідь, і для мене це було надто пізно, щоб не зменшити його. Вибачте. - Matt


Якщо у вас є Git Extras встановлено, можна запустити git undo скасувати останню фіксацію. git undo 3 скасуватиме останні 3 зобов'язання.


431
2017-10-25 03:41





Я хотів скасувати останні 5 команд у нашому спільному сховищі. Я подивився ідентифікатор перегляду, який хотів відмовитися. Потім я набрала наступне.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To git@bitbucket.org:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>

399



Переписування історії в спільному сховищі, як правило, дуже погана ідея. Я припускаю, що ви знаєте, що ви робите, я просто сподіваюсь, що майбутні читачі теж. - Brad Koch
Так відкат небезпечний. Перш ніж натиснути, переконайтеся, що ваша робоча копія знаходиться в потрібному стані. Після натискання небажані зобов'язання видаляються назавжди. - neoneye
"Точно так само, як у реальному світі, якщо ви хочете переписати історію, то вам потрібна змова: всі повинні бути" в "на змову (принаймні кожен, хто знає про історію, тобто кожен, хто колись витягує з гілки) " Джерело: stackoverflow.com/a/2046748/334451 - Mikko Rantalainen
фантастичний Це працювало як чарівність. Там повинен бути параметр git для самостійно працюючих розробників - де можна використовувати GitX, або кнопку видалити поруч із фіксацією, і підтвердження - так цей процес не такий загадковий :) - zero_cool


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

Виберіть, скільки завдань ви хочете перерахувати, а потім викликати подібне (для зарахування останніх трьох)

git rebase -i HEAD~3

Список вибірки

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

Тоді git видалить commit для будь-якої лінії, яку ви видаляєте.


381