Чи можливо скасувати зміни, викликані наступною командою? Якщо так, то як?
git reset --hard HEAD~1
--hard
відкидає невідомі зміни. Оскільки вони не відслідковуються за допомогою git, немає можливості відновити їх через git.
Чи можливо скасувати зміни, викликані наступною командою? Якщо так, то як?
git reset --hard HEAD~1
--hard
відкидає невідомі зміни. Оскільки вони не відслідковуються за допомогою git, немає можливості відновити їх через git.
Відповіді:
Пат Нотц прав. Ви можете повернути зобов’язання, якщо це пройшло протягом кількох днів. git збирає лише сміття приблизно через місяць або близько того, якщо ви прямо не скажете йому прибрати нові краплі.
$ git init
Initialized empty Git repository in .git/
$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 file1
$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 file2
$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1
$ cat file2
cat: file2: No such file or directory
$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2
$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2
$ cat file2
added new file
На прикладі ви бачите, що файл2 було видалено в результаті жорсткого скидання, але його було встановлено на місці, коли я скидався через рефлог.
git log -g
може бути трохи приємнішим способом перегляду рефлогу, ніж git reflog
.
git reflog
за краще git log -g
просто тому, що ви отримуєте всю інформацію в одному рядку з sha1, інформацією HEAD і виконуючи повідомлення, всі вишикувані. Набагато простіше читати.
Що ви хочете зробити, це вказати sha1 комісії, до якого ви хочете відновити. Ви можете отримати sha1, вивчивши reflog ( git reflog
), а потім зробивши
git reset --hard <sha1 of desired commit>
Але не чекайте занадто довго ... через кілька тижнів git зрештою побачить цю фіксацію як невстановлену та видалить усі краплі.
Відповідь прихована в детальній відповіді вище, ви можете просто зробити:
$> git reset --hard HEAD@{1}
(Див. Вихід git reflog show )
Його можна відновити, якщо Git ще не зібрав сміття.
Ознайомтесь із звинувачуваними зобов'язаннями за допомогою fsck
:
$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
Відновлення висячого комітету за допомогою rebase:
$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
Якщо вам справді пощастило, як я, ви можете повернутися до свого текстового редактора і натиснути «скасувати».
Я знаю, що це насправді не є правильною відповіддю, але це врятувало мені південної роботи, тому, сподіваюся, це зробить те ж саме для когось іншого!
наскільки я знаю, --hard
буде відкинуто неспроможні зміни. Оскільки вони не відслідковуються git. але ви можете скасувати discarded commit
.
$ git reflog
буде список:
b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....
де 4bac331
знаходитьсяdiscarded commit
.
Тепер просто перемістіть голову до цього комітету:
$ git reset --hard 4bac331
$ git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a <- it's this one
$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a
commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date: Wed Aug 15 08:41:30 2012 +0200
*MY COMMIT MESSAGE IS DISPLAYED HERE*
diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*
$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a
First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.
Залежно від стану, у якому знаходилось ваше сховище, коли ви виконували команду, ефекти параметра git reset --hard
можуть бути від тривіальної до скасування, до принципово неможливої.
Нижче я перерахував низку різних можливих сценаріїв, і як ви можете їх відновити.
Зазвичай ця ситуація виникає при запуску git reset
з аргументом, як в git reset --hard HEAD~
. Не хвилюйтесь, від цього легко відновитись!
Якщо ти просто біг git reset
і з цього часу не робили нічого іншого, ви можете повернутися туди, де ви були з цим одноклассником:
git reset --hard @{1}
Це скидає вашу поточну гілку в будь-який стан, в якому вона була до останнього зміни (у вашому випадку, остання зміна гілки буде жорстким скиданням, яке ви намагаєтесь скасувати).
Якщо ви все ж внесли інші зміни до своєї філії з моменту скидання, однолінійка вище не працюватиме. Натомість вам слід запустити, щоб побачити список усіх останніх змін, внесених у вашу філію (включаючи скидання). Цей список буде виглядати приблизно так:git reflog
<branchname>
7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit
Знайдіть операцію в цьому списку, яку ви хочете "скасувати". У наведеному вище прикладі це буде перший рядок, той, що говорить "скидання: перехід до HEAD ~". Потім скопіюйте представлення комісії перед (нижче) цією операцією. У нашому випадку це було б master@{1}
(або3ae5027
вони обидва представляють одне і те ж зобов’язання) і виконуєтьсяgit reset --hard <commit>
щоб повернути поточну гілку до цього коміту.
git add
, але ніколи не вчиняв їх. Тепер мої зміни пропали!Це трохи складніше, щоб відновитись після. мерзотник дійсно є копії файлів , доданих вами, але так як ці копії не були прив'язані до якої - небудь конкретної фіксації ви не можете відновити зміни відразу. Натомість вам потрібно знайти окремі файли в базі даних git та відновити їх вручну. Це можна зробити за допомогою git fsck
.
Докладніше про це див. У Скасуванні git reset - твердий з непосланими файлами в області постановки .
git add
і ніколи не робив. Тепер мої зміни пропали!Ой-ой. Я ненавиджу вам це казати, але вам, мабуть, не пощастило. git не зберігає зміни, які ви не додаєте або не здійснюєте, а відповідно до документації дляgit reset
:
- твердий
Скидає індекс і робоче дерево. Будь-які зміни відсліджених файлів у робочому дереві, оскільки
<commit>
вони відкидаються.
Цілком можливо , що ви могли б бути в змозі відновити ваші зміни з яким - то утилітою відновлення диска або професійної послуги по відновленню даних, але в цей момент, ймовірно , більше проблем , ніж це коштує.
Якщо ви ще не зібрали сміття зі свого сховища (наприклад, використовуючи git repack -d
абоgit gc
, але зауважте, що збирання сміття також може відбуватися автоматично), то ваше зобов’язання все ще є - воно просто більше не доступне через HEAD.
Ви можете спробувати знайти свою комісію, переглянувши вихідний файл git fsck --lost-found
.
Новіші версії Git мають назву "reflog", що представляє собою журнал усіх змін, які вносяться до refs (на відміну від змін, що вносяться до вмісту сховища). Так, наприклад, щоразу, коли ви перемикаєте HEAD (тобто кожен раз, коли ви git checkout
перемикаєте гілки), який буде реєструватися. І, звичайно, ваш git reset
також маніпулював ГОЛОВОЮ, тому він також був зареєстрований. Ви можете отримати доступ до старих станів ваших записів аналогічно тому, що ви можете отримати доступ до старих станів вашого сховища, використовуючи @
знак замість а ~
, як git reset HEAD@{1}
.
Мені знадобилось певний час, щоб зрозуміти, в чому різниця між HEAD @ {1} та HEAD ~ 1, тому ось невелике пояснення:
git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog
Отже, HEAD~1
означає "перейти до комісії перед фіксацією, на яку зараз вказує HEAD"HEAD@{1}
означає "перейти до зобов'язання, на яке HEAD вказував, перш ніж вказувати, де воно в даний момент вказує".
Це легко дозволить вам знайти втрачене зобов'язання і відновити його.
Перш ніж відповісти, давайте додати деяку інформацію, пояснивши, що це HEAD
?
First of all what is HEAD?
HEAD
це просто посилання на поточний комітет (останній) у поточній галузі.
У HEAD
будь-який момент може бути лише сингл . (виключаючиgit worktree
)
Вміст HEAD
зберігається всередині, .git/HEAD
і він містить 40 байт SHA-1 поточної комісії.
detached HEAD
Якщо ви не перебуваєте на останньому комітеті - це означає, що HEAD
вказує на попереднє вчинення в історії, його називають detached HEAD
.
У командному рядку це виглядатиме так - SHA-1 замість назви гілки, оскільки значення HEAD
не вказує на кінчик поточної гілки
git checkout
git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back
Це дозволить перевірити нову гілку, яка вказує на бажану комісію.
Ця команда перевірятиме дану комісію.
У цей момент ви можете створити відділення і почати працювати з цього моменту.
# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>
# create a new branch forked to the given commit
git checkout -b <branch name>
git reflog
Ви завжди можете використовувати reflog
також.
git reflog
відобразиться будь-яка зміна, яка оновила, HEAD
і перевірка потрібного запису відмикання HEAD
повернеться до цього зобов'язання.
Кожен раз, коли зміниться HEAD, буде новий запис у reflog
git reflog
git checkout HEAD@{...}
Це поверне вас до бажаного завдання
git reset HEAD --hard <commit_id>
"Перемістіть" голову назад до потрібної фіксації.
# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
git rebase --no-autostash
також.git revert <sha-1>
"Скасувати" заданий діапазон фіксації чи фіксації.
Команда скидання "скасує" будь-які зміни, внесені в дану комісію.
Новий фіксатор з виправленням патча буде здійснено, тоді як оригінальний запис також залишиться в історії.
# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>
Ця схема ілюструє, яка команда робить що.
Як ви бачите, там можна reset && checkout
змінити HEAD
.
git reset HEAD --hard <commit_id>
приклад взятий із stackoverflow.com/questions/4114095/… - Якщо це так, чи можете ви редагувати в атрибуції?
git reflog
git cherry-pick <the sha>
Я знаю, що це стара тема ... але, оскільки багато людей шукають способи скасувати речі в Git, я все ще думаю, що це може бути хорошою ідеєю продовжувати давати поради тут.
Коли ви робите "git add" або переміщуєте що-небудь вгорі ліворуч донизу ліворуч у git gui, вміст файлу зберігається у крапці, а вміст файлу можливо відновити з цього крапка.
Таким чином, можна відновити файл, навіть якщо він не був зроблений, але він повинен бути доданий.
git init
echo hello >> test.txt
git add test.txt
Тепер блоб створений, але на нього посилається індекс, тому він не буде перерахований з git fsck, поки ми не скинемо його. Тож ми скидаємо ...
git reset --hard
git fsck
ви отримаєте звисаючу крапку ce013625030ba8dba906f756967f9e9ca394464a
git show ce01362
поверне вам вміст файлу "привіт"
Щоб знайти невирішені комісії, я десь підказав підказку.
gitk --all $(git log -g --pretty=format:%h)
У мене він є інструментом у git gui, і це дуже зручно.
git fsck --lost-found
може допомогти.
Якщо ви використовуєте ID-програму JetBrains IDE (все, що базується на IntelliJ), ви можете відновити навіть невмілі зміни, скориставшись їх функцією "Місцева історія".
Клацніть правою кнопкою миші на директорії верхнього рівня у вашому дереві файлів, у контекстному меню знайдіть "Місцева історія" та виберіть "Показати історію". Це відкриє подання, де можна знайти ваші останні зміни, і як тільки ви знайдете редакцію, до якої хочете повернутися, клацніть правою кнопкою миші та натисніть «Повернути».
Я щойно зробив жорсткий перезавантаження на неправильному проекті. Що врятувало мені життя - це краєзнавство Eclipse. У IntelliJ Idea, як кажуть, є і її, і, можливо, ваш редактор, варто перевірити:
Зробив крихітний сценарій, щоб трохи легше було знайти фіксацію, яку шукає:
git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'
Так, це може бути значно красивіше з awk або чимось подібним, але це просто, і я просто потребував цього. Ви можете заощадити когось ще 30 секунд.
Моя проблема майже схожа. Я не видав файли до входуgit reset --hard
.
Вдячно Мені вдалося пропустити всі ці ресурси. Після того як я помітив, що можу просто скасувати (ctrl-z
). 😊 Я просто хочу додати це до всіх відповідей вище.
Примітка. Неможливо ctrl-z
відкрити файли.
Це врятувало мені життя:
https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c
В основному вам потрібно запустити:
for blob in $(git fsck --lost-found | awk ‘$2 == “blob” { print $3 }’); do git cat-file -p $blob > $blob.txt; done
Потім вручну переживайте біль, щоб переорганізувати файли у потрібну структуру.
Винос: Ніколи не використовуйте, git reset --hard
якщо ви повністю не розумієте, як це працює, краще не використовувати його.