web-dev-qa-db-ja.com

Gitで、コミットする前に元に戻されたステージングされたファイルを復元するにはどうすればよいですか?

GitTowerを使用してリポジトリに変更をプルしようとしていました。そうすると、コンフリクトが発生し、誤ってすべてのステージに到達しました(コンフリクトを解決した後でコミットしたかったため)。私がそうするとき、対立は解決されたとそれ自身をマークしました。

変更を手動で解決したかったので、[マージの中止]をクリックしましたが、これを実行すると、すべての変更がロールバックされました。それらを取り戻す方法はありますか?

35
David

Gitにステージングされたものがあれば、おそらくそれを取り戻すことができるはずです。 (作業コピーを変更したばかりの場合、それを復元することはできません。)

まず第一に:do not run git gc。先に進む前に、リポジトリと作業コピーをバックアップしてください。 (必ず.gitディレクトリをバックアップしてください。)また、これが発生したターミナルを閉じたり、再起動したりしないでください。すべてが失敗した場合は、履歴/メモリにあるものを見つける可能性があります。

とにかく、最初に試すことは次のとおりです。

 git fsck --lost-found 

それは次のようなものを印刷します

オブジェクトディレクトリの確認:100%(256/256)、完了。
オブジェクトの確認:100%(30165/30165)、完了。
ぶら下がりblob 8f72c7d79f964b8279da93ca8c05bd685e892756 
ぶら下がりコミット4993502a6394491190d3f4d6fb3d1e14019c2e9b 

ステージングされたファイルを失い、コミットを実行しなかったため、dangling blobエントリに関心があります。

それぞれに対してgit show <sha>を実行します—それらのいくつかはあなたのファイルであるはずです。

59

より簡単な代替手段でAlexanderの答えを拡張するには:はい、変更をステージングした場合は、おそらくファイルを元に戻すことができます。 git addを実行すると、ファイルは実際にGitのオブジェクトデータベースに追加されます。あなたがそうする瞬間に、gitはファイルをインデックスに入れます:

% git add bar.txt
% git ls-files --stage
100644 ce013625030ba8dba906f756967f9e9ca394464a 0   bar.txt
100644 6af0abcdfc7822d5f87315af1bb3367484ee3c0c 0   foo.txt

Bar.txtのエントリには、ファイルのオブジェクトIDが含まれていることに注意してください。 Gitは実際にファイルをオブジェクトデータベースに追加しました。この場合、Gitはそれをルーズオブジェクトとしてリポジトリに追加しました。

% ls -Flas .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a
4 -r--r--r--  1 ethomson  staff  21 14 Jun 23:58 .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a

これらのファイルは最終的にガベージコレクションされます(したがって、実際には、明示的にgit gcを実行しないでください)。ありがたいことに、デフォルトでは、これは数日ではなくか月の問題で発生します。これらのファイルがガベージコレクションされるまで、それらを回復できます。

これを行う最も簡単な方法は、 git-recoverプログラムをダウンロードしてインストールする インタラクティブモードで行うことです。

% git recover -i
Recoverable orphaned git blobs:

61c2562a7b851b69596f0bcad1d8f54c400be977  (Thu 15 Jun 2017 12:20:22 CEST)
> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
> tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
> veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
> commodo consequat. Duis aute irure dolor in reprehenderit in voluptate

Recover this file? [y,n,v,f,q,?]: 

git-recoverは、コミットされていない(またはインデックス内の)オブジェクトデータベース内のファイルを検索します。 git-recoverの詳細については、 それを発表しているブログ投稿 を参照してください。

13
Edward Thomson

どのblobを回復する必要があるかをすばやく把握できるようにすることで、回復を単純化できる(他の回答と比較して)非常に遅い回答:

git fsck --full --no-reflogs --unreachable --lost-found | grep blob | cut -d\  -f3 | while read in; do printf "blob: $in\n"; git cat-file -p $in; printf "\n--------------------------------\n"; done > recover.txt

このコマンドは、回復できるすべてのBLOBのハッシュとコンテンツを含むファイルを作成します。

そうすれば、このファイルを簡単に検索して、指定されたハッシュを使用して(コマンドgit cat-file -p 8f72c7d79f964b8279da93ca8c05bd685e892756 > myFile.txtを使用して)必要なblobを回復できます。

免責事項:到達不能なBLOBが多数ある場合、このファイルは巨大になり、作成に時間がかかる可能性があります。

6
Philippe