Відновити після скидання git - твердо?


457

Чи є спосіб відновити незапущені зміни в робочому каталозі з git reset --hard HEAD?


49
Я б рекомендував відучитися git reset. Вам не потрібна ця команда, і вона небезпечна, тому не використовуйте її. Щоб повернути гілку до попередньої фіксації, git rebase -iвідпустіть комісії, які ви не хочете, або git checkout(відкреслює голову) з подальшим git branch -Mпереміщенням кінчика гілки. Перший відмовиться від запуску з локальними змінами, а пізніше запуститься лише в тому випадку, якщо локально модифіковані файли не відрізняються між версіями.
Ян Худек

11
@Jan Я в це не вірю. Існують цілком законні причини використовувати скидання.
spaaarky21

4
@ spaaarky21: Так, є. Але git reset --hard somewhereце одна з небагатьох дійсно небезпечних команд git.
Ян Гудець

5
@Jan Я погоджуюся, але це небезпечно, це не означає, що ви не повинні його використовувати. Просто знайте, що ви робите, і будьте обережні. :)
spaaarky21

3
Не пов’язане із скасуванням скидання git --hard HEAD ~ 1 , оскільки тут оригінальний плакат намагається відновити незапущені зміни.

Відповіді:


474

Загалом ви не можете отримати непогашені зміни.

Раніше поетапні зміни ( git add) повинні бути відновлені з об’єктів індексу, тому, якщо ви це зробили, використовуйте git fsck --lost-foundдля пошуку об'єктів, пов'язаних з цим. (Це записує об'єкти в.git/lost-found/ каталог; звідти ви можете git show <filename>переглянути вміст кожного файлу.)

Якщо ні, то відповідь тут була б: подивіться на свою резервну копію. Можливо, ваш редактор / IDE зберігає тимчасові копії під / tmp або C: \ TEMP тощо. [1]

git reset HEAD@{1}

Це відновить до попереднього HEAD

[1] vim, наприклад, необов'язково зберігає стійкі скасування, затемнення IDE зберігає локальну історію ; такі функції можуть зберегти ваш **


18
Краєзнавство Eclipse - і крім того, оскільки деякі зміни були старшими на 6 днів, я створив резервну копію локальної історії Eclipse! Чомусь резервна копія папки, керованої git Time Time, не містила моїх попередніх змін.
Крістіанбродбек

2
Ви серйозно рятуєте життя від підказки! У TextWrangler була резервна копія файлів. Дякую
Vivek Sampara

6
IDE (IntelliJ) зберігав зміни локально, які врятували день. Дякую за пораду!
progonkpa

1
Ух, це дивовижно. Це працює, навіть якщо ви ніколи не брали на себе зобов’язання.
Boudewijn Aasman

2
Дійсно, краєзнавство в Eclipse (Intellij в моєму випадку) заощаджує мій день для відновлення змін, що не вказуються, док тут для Intellij: blog.jetbrains.com/idea/2008/01/…
Річард

448

відповідь з цього ТА

$ git reflog show
93567ad HEAD@{0}: reset: moving to HEAD@{6}    
203e84e HEAD@{1}: reset: moving to HEAD@{1}    
9937a76 HEAD@{2}: reset: moving to HEAD@{2}
203e84e HEAD@{3}: checkout: moving from master to master
203e84e HEAD@{4}: reset: moving to HEAD~1
9937a76 HEAD@{5}: reset: moving to HEAD~1
d5bb59f HEAD@{6}: reset: moving to HEAD~1
9300f9d HEAD@{7}: commit: fix-bug

# said the commit to be recovered back is on 9300f9d (with commit message fix-bug)
$ git reset HEAD@{7}

Ви отримали свій день назад! :)


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

9
Чудово - але в моєму випадку файли зникли повністю. Використання git checkout HEAD@{19}дозволило мені перевірити втрачені файли у відокремленому стані. Потім використовується git checkout -b new-branch-nameдля того, щоб додати їх до репо в стані "приєднаного".
NightOwl888

@ NightOwl888: Git newbie тут, і у мене була така ж проблема, що мої файли ще не було. Чи могли б ви пояснити більш детально, як ви відновили свої файли у "прикріпленому" стані (чи могли б ви пояснити, що це насправді означає)? Дуже дякую!
OhDaeSu

3
@ user3385759 - У Git, коли ви використовуєте команду оформлення замовлення на будь-що, що не є гілкою, вона перейде в спеціальний режим "відірвана голова". Це означає, що ви насправді не вказуєте на гілку, але ви можете переглянути те, що було зареєстровано у штаті суб'єкта господарювання (у цьому випадку запис про відкладення). З цього стану ви можете перетворити його на "справжню" гілку, до якої ви можете знову повернутися, використовуючи git checkout -b new-branch-name. Книга Прагматичний контроль версій за допомогою Git добре пояснює Git простими термінами.
NightOwl888

2
Так, що сказали NomNomCameron та Джессі Адельман. Я помилково вважав, що скидання зміниться до мого останнього зобов'язання. Ні. Це витерло все. Ця відповідь врятувала мене від дня чи двох відновлювати свою роботу.
VeteranCoder

308

Я випадково натрапив git reset --hardна своє репо і сьогодні, не маючи змін і сьогодні. Щоб повернути його, я побіг git fsck --lost-found, на який записав усі невирішені краплі <path to repo>/.git/lost-found/. Оскільки файли були видалені, я знайшов їх у otherкаталозі в межах <path to repo>/.git/lost-found/. Звідти я можу бачити незапущені файли за допомогою git show <filename>, копіювати краплі та перейменувати їх.

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


4
Я отримав лише файли з посиланнями на коміти в lost-found. Але я міг би потім зробити git showвміст.
Мітар

6
Тільки щоб врятувати комусь час#!/bin/bash cd PATH_TO_PROJECT/.git/lost-found/other FILES=* COUNTER = 0 for f in $FILES do echo "Processing $f file..." git show $f > "PATH_TO_RECOVERY_DIRECTORY/$COUNTER.m" let COUNTER=COUNTER+1 done
rwolst

209

Так, ВИ МОЖЕТЕ ВІДНОВИТИ з жорсткого скидання в git.

Використання:

git reflog

щоб отримати ідентифікатор вашого зобов’язання. Потім використовуйте:

git reset --hard <commit-id-retrieved-using-reflog>

Цей трюк врятував мені життя кілька разів.

Ви можете знайти документацію рефлогу ТУТ .


9
Поки що я думаю, що це найкраща і найкоротша відповідь. Може здатися протилежним інтуїтивно git reset --hardзрозуміти відновлення після використання іншого, git reset --hardале якщо ви не користуєтесь --hardкомутатором, у вашій робочій області залишиться запис, який би ефективно повернув роботу, яку ви тільки що відновили.
Райан Х.

2
Працює як шарм! Попередня відповідь ( stackoverflow.com/questions/5788037/recover-from-git-reset-hard/… ) не працювала для мене.
кодемакс

3
Ця відповідь не правильна. Цей підхід відновлює лише раніше здійснені зміни. Він не зможе відновити неспроможні зміни (про що йдеться у цьому питанні).
Олдерат

2
Це рішення працює для мене. Я зробив жорсткий скидання, і тоді, коли я використовую, git logя не бачив ідентифікатора комітету. З git reflogя міг побачити ID посвідчення
dboscanv

2
це працює для мене. Дякую!!!!!!
RedEyed

60

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

Я побіг git reset --hard origin/master: P

Потім усі мої локальні файли видалено, оскільки репо було порожнім. Я думав, що все пропало.

Це врятувало мені життя:

git reflog show
git reset HEAD@{1} 
git push 

Сподіваюся, це врятує інше життя.


Для мене це було git reset HEAD@\{27\} , Дякую!
жовтня

1
У мене є 7 зобов’язань щодо скидання, я використовую git reflog showдля перевірки і з цього першого введення я використовуюgit reset HEAD@{number}
Vishwas Nahar

38

Якщо ви використовуєте щось на зразок IntelliJ:

У контекстному меню виберіть "Місцева історія" та натисніть Показати історію в підменю:

Місцевий перегляд проекту чи папки показує вам усе, що ви робили за останні кілька днів. У стовпці Дія в нижній частині діалогового вікна виберіть дію, яку потрібно відкотити. [...] Таким чином, у верхній частині діалогового вікна відображається перегляд дерева змінених файлів. Якщо ви хочете відновити лише видалений файл, незалежно від інших змін, що відбулися з тих пір, ви можете вибрати файл Lost.txt у вигляді дерева та натиснути кнопку Повернути.

http://blog.jetbrains.com/idea/2008/01/using-local-history-to-restore-deleted-files/

Це просто витягнуло мою дупу з вогню!


Це, безумовно, найкраща відповідь для користувачів IntelliJ! Дякую тобі, це спрацювало чудово. Я спробував будь-яке інше рішення, і жодне з них не працювало добре. git reflogне працювало, тому що я не вчинив змін. git fsck --lost-foundпрацювали над поетапними файлами, але не всі вони були інсценовані. Місцева історія IntelliJ чудово відновила мої збережені файли, я дуже вдячний за цю функцію
Денес Папп,

30

Я щойно зробив git reset --hardі втратив усі свої неспроможні зміни. На щастя, я використовую редактор (IntelliJ), і мені вдалося відновити зміни з локальної історії. Затемнення повинно дозволяти вам робити те саме.


20

За визначенням, git reset --hard Git видалить незапущені зміни без жодного способу відновити їх (ваша система резервного копіювання може допомогти, але не Git).

Насправді дуже мало випадків, коли git reset --hardце гарна ідея. У більшості випадків є більш безпечна команда зробити те саме:

  • Якщо ви хочете викинути свої неспроможні зміни, тоді скористайтеся git stash. Це збереже резервну копію цих змін, які закінчуються через деякий час, якщо ви запустите git gc. Якщо ви на 99,9% впевнені, що вам ніколи не знадобляться ці зміни, то git stashвсе-таки ваш друг у справі 0,1%. Якщо ви на 100% впевнені, то git stashвсе-таки ваш друг, оскільки ці 100% мають помилку вимірювання ;-).

  • Якщо ви хочете перемістити свою HEADта кінчику поточної гілки в історії, то git reset --keepваш друг. Це зробить те ж саме git reset --hard, що й не скасувати ваші локальні зміни.

  • Якщо ви хочете зробити те і інше, то git stash && git reset --keepваш друг.

Навчіть пальці не користуватися git reset --hard, це окупиться за один день.


Так що, якщо хтось зробить git stash && git reset --hardце, вилучив би будь-який захований вміст, це правильно?
jxramos

1
Ні, git reset --hardне відкидає приховування. git stashце заміна git reset --hardв тому сенсі, що він видаляє невмілі зміни зі свого робочого дерева, за винятком того, що він зберігає їх у безпеці, а не відкидає їх назавжди.
Матьє Мой

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

11

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

git reflog show
git reset HEAD@{2} // i.e where HEAD used to be two moves ago - may be different for your case

припускаючи, що HEAD@{2}це стан, у який ви хочете повернутися


для мене це спрацювало ідеально, якщо ви робите це на PowerShell, переконайтеся, що це записується так, як це скидання git 'HEAD @ {2}', інакше не буде працювати в powerhell
VectorX

10

Це те, що я зазвичай роблю, якщо втрачаю деякі зміни.

git reflog
git checkout <commit id> // now you are in where you want but you cannot push from detached branch to master
manually copy and paste changes from detached branch to master or working branch
git reset --hard HEAD // if needed
git add ... > git commit ... > git push ...

щоб повернути покажчик назад до попередніх зобов’язань, але зберігаючи внесені вами зміни до останнього оформлення замовлень git reset --soft dadada


8

Інформація втрачається.

Оскільки ви не зробили зобов’язання, ваш .git ніколи не зберігав цю інформацію. Отже, в основномуgit ви не можете відновити його за вас.

Але, якщо ви щойно це зробили git diff, є спосіб відновити, використовуючи термінальний вихід, виконавши наступні 3 простих кроки.

  1. прокрутіть термінал і шукайте o / p git diff. Збережіть o / p у файлі під назвою diff.patch
  2. Знайдіть і замініть всі 7 пробілів та 8 пробілів символом tab (\ t) та збережіть зміни.
  3. Зайдіть у своє сховище git. Застосувати diff.patch ( patch -p1 < diff.patch)

Ви врятовані! :)

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


7

Я зіткнувся з тією ж проблемою, і я майже збожеволів .... спочатку я здійснив проект і злився .. пізніше, коли я намагаюся запустити, git push --set-upstream origin master я отримував цю помилку

  fatal: refusing to merge unrelated histories

тому я побіг, git reset --hard HEADі він видалив проект на 3 тижні, але ці кілька команд нижче врятують день:

git reset HEAD@{1}         //this command unstage changes after reset
git fsck --lost-found      //I got the dangling commit fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b
git show <dangling commit something like-> fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b>
git rebase fc3b6bee2bca5d8a7e16b6adaca6a76e620eca4b

сподіваюся, що це допомагає


6

Ви можете отримати зобов’язання, виконавши команду reset --hard HEAD .

Використовуйте " git reflog", щоб перевірити історіюHEAD в галузі.

Тут ви побачите свою фіксацію та її ідентифікатор.

Зробіть a

git reset {commit Id of the commit you want to bring back}

5

Якщо вам, на щастя, були відкриті ті самі файли в іншому редакторі (наприклад, Sublime Text), спробуйте ctrl-z для них. Це просто врятувало мене ..


3

Я з’ясував важкий спосіб, що будь-які непослані файли перед тим, як git reset --hard <commit>видаляється з історії git. Однак мені пощастило, що я тримав сесію редактора коду відкритою протягом усього часу, коли я витягував волосся, і я виявив, що простий control + zу кожному з цих файлів повертає стан файлу до версії до Git. обов'язково скиньте все, чого я конкретно не просив.Hooray!!


3

Якщо ви намагаєтеся використовувати код нижче:

git reflog show
# head to recover to
git reset HEAD@{1} 

і чомусь отримуєте:

помилка: невідомий перемикач `e '

потім спробуйте обгортати HEAD@{1}лапки

git reset 'HEAD@{1}'

3
 git reset HEAD@{4}

4 - це зміни до 4 кроків тому. якщо вибрати правильний крок, він повинен відображати список файлів, які ви видалили з жорсткого. тоді зробіть:

$ git reflog show

це покаже вам історію місцевих комісій, яку ми вже створили. тепер зробіть:

$ git reset --hard 8c4d112

8c4d112 - це код, який потрібно скинути. давайте подивимось на https://www.theserverside.com/video/How-to-use-the-git-reset-hard-command-to-change-a-commit-history, щоб отримати більше інформації.


Велике спасибі @mohammad, це мене врятувало. Я не міг бачити свої вихідні файли раніше, але, виконавши вищезазначені дії, я зміг відновити всі свої вихідні файли.
Гаурав Бансал

2

Правильні відповіді. Гаразд, зараз мені подобається git. :-) Ось простіший рецепт.

git log HEAD@{2}
git reset --hard  HEAD@{2}

Де "2" - це кількість повернень туди, де ви здійснили свої зміни. У моєму випадку, перерваний колегою та начальником, щоб допомогти налагодити якусь проблему складання; значить, зробив скидання - важко двічі; так, HEAD і HEAD @ {1} були надмірними записами. Вау, втратив би наш важку працю.


2

я зробив git reset --hard неправильний проект помилково (я знаю ...). Я щойно працював над одним файлом, і він все ще був відкритий під час і після запуску команди.

Незважаючи на те, що я цього не зробив, я зміг отримати старий файл простим COMMAND + Z.


0

Довідкова відповідь з цього ПЕ,

Після запуску програми git reflog show скажіть, що ви хочете скористатися 9300f9d

після запуску git скинути 9300f9d

ви можете отримати статус git, і тоді вам може знадобитися перевірити свої файли, щоб відновити зміни

git checkout - filepath / name


0

Якщо ви розробляєте Netbeans, перегляньте між вкладками файлів та областю редагування файлів. Є "Джерело" та "Історія". У розділі "Історія" ви побачите зміни, внесені за допомогою контролю версій (git / other), а також зміни, внесені локально. У цьому випадку локальні зміни можуть врятувати вас.


0

( відповідь підходить для підмножини користувачів )

Якщо ви перебуваєте на (будь-якому недавньому) macOS, і навіть якщо ви далеко від диска Time Machine, ОС збереже погодинні резервні копії, які називаються локальними знімками .

Введіть машину часу та перейдіть до файла, який ви втратили. Після цього ОС запитає вас:

The location to which you're restoring "file.ext" already contains an
item with the same name. Do you want to replace it with the one you're
restoring?

Ви повинні мати можливість відновити загублені файли.


0

Якщо у вас було відкрито IDE з тим самим кодом, спробуйте зробити ctrl + z для кожного окремого файлу, в який ви внесли зміни. Це допомогло мені відновити свої невмілі зміни після скидання git - твердий.


-3

Коли ми робимо скидання git - тверді та всі локальні незмінні зміни видаляються. Щоб відновити зміни - в IDE натисніть на файл, порівняйте файл з локальною історією, яка перелічить зміни за датою, і ми зможемо відновити дані. Ваш день збережений!


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