次のコマンドによる変更を元に戻すことはできますか?もしそうなら、どうですか?
git reset --hard HEAD~1
--hard
コミットされていない変更を破棄します。これらはgitによって追跡されないため、gitを介して復元する方法はありません。
次のコマンドによる変更を元に戻すことはできますか?もしそうなら、どうですか?
git reset --hard HEAD~1
--hard
コミットされていない変更を破棄します。これらはgitによって追跡されないため、gitを介して復元する方法はありません。
回答:
パットノッツは正しいです。数日以内であれば、コミットを取り戻すことができます。新しいブロブを削除するように明示的に指示しない限り、約1か月ほど後に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
この例では、ハードリセットの結果としてfile2が削除されましたが、reflogを介してリセットすると、file2は元の場所に戻されました。
git log -g
は、reflogを表示するよりも少し良い方法ですgit reflog
。
git reflog
、git log -g
単純に私は好みません。はるかに読みやすい。
答えは上の詳細な応答に隠されています、あなたは単に行うことができます:
$> git reset --hard HEAD@{1}
(git reflog showの出力を参照してください)
Gitがまだガベージコレクションを実行していない場合は、回復することができます。
未解決のコミットの概要を取得するにはfsck
:
$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
リベースで未解決のコミットを回復します。
$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
私のように本当に運が良ければ、テキストエディターに戻って[元に戻す]を押すことができます。
私はそれが適切な答えではないことを知っていますが、それは私が半日の仕事を節約したので、うまくいけば他の誰かのために同じことをするでしょう!
$ 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
このリストで「元に戻す」操作を見つけます。上記の例では、「reset:HEAD〜に移動しています」という最初の行になります。次に、その操作の前(下)にコミットの表現をコピーします。私たちの場合、それはmaster@{1}
(または3ae5027
、両方とも同じコミットを表しgit reset --hard <commit>
ます)、現在のブランチをそのコミットにリセットするために実行されます。
git add
でステージングしましたが、コミットしませんでした。これで私の変更はなくなりました!これから回復するには少し注意が必要です。gitには追加したファイルのコピーがありますが、これらのコピーは特定のコミットに関連付けられていないため、変更を一度に復元することはできません。代わりに、gitのデータベースで個々のファイルを見つけて、手動で復元する必要があります。あなたはこれを行うことができますgit fsck
。
これについて詳しくは、ステージング領域でコミットされていないファイルを元に戻すgit reset --hardをご覧ください。
git add
こともコミットしたこともない作業ディレクトリ内のファイルに変更を加えました。これで私の変更はなくなりました!ええとああ。言いたくないのですが、運が悪いでしょう。gitのは、あなたが追加したり、それにコミットしていないことの変更を保存し、かつに従っていないのドキュメントgit reset
:
- ハード
インデックスと作業ツリーをリセットします。以降の作業ツリーで追跡されているファイルへの変更
<commit>
は破棄されます。
それはあなたがいる可能性があります可能性があるディスク回復ユーティリティやプロのデータ復旧サービスのいくつかの並べ替えを使用して、変更を回復することができますが、おそらくそれの価値よりも多くのトラブルだこの時点で。
リポジトリのガベージコレクションをまだ行っていない場合(git repack -d
またはを使用しますgit gc
が、ガベージコレクションも自動的に発生する可能性があることに注意してください)、コミットはまだそこにあり、HEADからは到達できません。
あなたはあなたのコミットを見つけることを試みることができます git fsck --lost-found
。
新しいバージョンのGitには「reflog」と呼ばれるものがあります。これは、(リポジトリのコンテンツに対して行われた変更ではなく)refに対して行われたすべての変更のログです。したがって、たとえば、HEADを切り替えるたび(つまり、git checkout
ブランチを切り替えるために行うたび)にログに記録されます。そしてもちろん、あなたgit reset
もHEADを操作したため、ログも記録されました。次のよう@
に、の代わりに記号を使用して、リポジトリの古い状態にアクセスできるのと同様の方法で、参照の古い状態にアクセスできます。~
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
。
First of all what is HEAD?
HEAD
現在のブランチの現在のコミット(最新)への参照です。
常に1つしか存在できませんHEAD
。(除くgit worktree
)
の内容HEAD
は内部に格納され.git/HEAD
、現在のコミットの40バイトのSHA-1が含まれています。
detached HEAD
あなたが最新のコミットをしていない場合-これHEAD
は、履歴内の以前のコミットを指していることを意味しdetached HEAD
ます。
コマンドラインではHEAD
、は現在のブランチの先端を指していないため、ブランチ名ではなく、SHA-1のようになります。
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
れ、目的のreflogエントリをチェックアウトすると、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で左上から左下に何かを移動すると、ファイルのコンテンツはblobに保存され、ファイルコンテンツはそのblobから復元できます。
そのため、コミットされていなくても追加されているファイルであっても、ファイルを回復することができます。
git init
echo hello >> test.txt
git add test.txt
これでblobが作成されましたが、インデックスによって参照されているため、リセットするまで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
が役立ちます。
間違ったプロジェクトでハードリセットを実行しました。私の命を救ったのは、Eclipseのローカルな歴史です。IntelliJ Ideaにも1つあると言われています。編集者もそうだと思います。チェックする価値があります。
私の問題はほとんど同じです。入力する前にコミットされていないファイルがありますgit reset --hard
。
ありがたいことに。これらのリソースをすべてスキップすることができました。元に戻すことができることに気付いた後(ctrl-z
)。aboveこれを上記のすべての回答に追加したいだけです。
注意。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
動作を完全に理解していない場合は絶対に使用しないでください。使用しないことをお勧めします。