Як я можу відновити втрачену комісію в Git?


258

По-перше, отримано "ваша філія випереджає походження / майстер на 3 коміти", потім моя програма повернулася до більш раннього часу з більш ранніми змінами.

Як я можу отримати те, що я витратив останні 11 годин, роблячи назад?


Відповіді:


586

git reflogтвій друг. Знайдіть комісію, на якій ви хочете бути у цьому списку, і зможете скинути його (наприклад:git reset --hard e870e41 :).

(Якщо ви не здійснили своїх змін ... у вас можуть виникнути проблеми - дотримуйтесь завчасно та виконайте часто!)


5
Погляньте git log HEAD@{1}. Якщо це виглядає як правильний ряд зобов’язань, тоді ви можете git reset HEAD@{1}.
Бурштин

4
Тільки якщо коди ставляться поетапно (за допомогою git add), вони зберігаються в git і їх можна легко знайти назад, використовуючи такі команди, як git fsck --lost-found.
Лендіс

2
Випадково відмовився від комітету, який я мав би зберегти під час перезавантаження. Це повністю врятувало мене від повторної роботи, котра мала години.
Йосефтінг

27
Це врятувало мені життя.
Lutaaya Huzaifah Idris

6
Це врятувало мою розсудливість: D
Френк Фахардо

117

Перш ніж відповісти, давайте додамо деяку інформацію, пояснивши, що це 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 --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 2.7 ) ви також можете використовувати git rebase --no-autostashтакож.

git revert <sha-1>

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

# Add a 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.

Введіть тут опис зображення


2
Ти герой, сер
dylanh724

4
Це просто врятувало мені багато годин роботи. Я використовував "git reflog --date = iso", щоб побачити дату / час для кожного запису, оскільки не міг точно сказати без позначки часу.
MetalMikester

1
для мене, в git reset --hard <commit_id>, видалення HEADпрацював! +1 для графічного зображення !!.
reverie_ss

Зазначимо лише: якщо ви знаєте назву гілки: git reflog <branchname>може бути дуже корисною, оскільки ви бачите зміни лише однієї гілки.
Маркус Шрайбер

35

Ще один спосіб дістатися до видаленої фіксації - за допомогою git fsckкоманди.

git fsck --lost-found

Це виведе щось на кшталт останнього рядка:

dangling commit xyz

Ми можемо перевірити, чи це той самий фільтр, reflogяк запропоновано в інших відповідях. Тепер ми можемо зробитиgit merge

git merge xyz

Примітка.
Ми не можемо повернути фіксацію, fsckякщо ми вже виконали git gcкоманду, яка видалить посилання на звисаючий коміт.


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