Gitリポジトリーで削除されたファイルを見つけて復元する


2802

私がGitリポジトリにいるとしましょう。ファイルを削除して、その変更をコミットします。私は仕事を続け、さらにいくつかのコミットを行います。次に、そのファイルを復元する必要があります。

を使用してファイルをチェックアウトできることgit checkout HEAD^ foo.barはわかっていますが、そのファイルがいつ削除されたかはわかりません。

  1. 特定のファイル名を削除したコミットを見つける最も速い方法は何でしょうか?
  2. そのファイルを作業コピーに戻す最も簡単な方法は何ですか?

ログを手動で参照し、特定のSHAのプロジェクト全体をチェックアウトし、そのファイルを元のプロジェクトのチェックアウトに手動でコピーする必要がないことを願っています。


39
前のコメントは、本文ではなくタイトルの質問に回答することに注意してください。これには、ファイルがいつ削除されたかを確認することが含まれます。
avdgaag 2011

8
:ファイルがで削除されたコミットを見つけるためにgit log --diff-filter=D -- path/to/file
titaniumdecoy



54
@hhh git checkout deletedFileは、削除deletedFileされたがその削除がまだステージングまたはコミットされていない場合、削除を取り消します。これは、ここでの質問が求めていることではありません。この質問は、削除が多くのコミット前にコミットされたファイルを復元する方法についてです。
Mark Amery 2017

回答:


3150

指定されたパスに影響を与えた最後のコミットを見つけます。ファイルはHEADコミットに含まれていないため、このコミットによって削除された必要があります。

git rev-list -n 1 HEAD -- <file_path>

次に、キャレット(^)記号を使用して、以前のコミット時にバージョンをチェックアウトします。

git checkout <deleting_commit>^ -- <file_path>

または、1つのコマンドで、$file問題のファイルである場合。

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

zshを使用していて、EXTENDED_GLOBオプションが有効になっている場合、キャレット記号は機能しません。~1代わりに使用できます。

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

94
トリッキーなビットは、^サフィックスを使用して、BEFOREの前にコミットをチェックアウトすることです。ありがとう。
クリスチャンオダード

4
何らかの理由で、これはzshでは機能しません。 ± git checkout $(git rev-list -n 1 HEAD "spec/Sporkfile_example.rb")^ -- "spec/Sporkfile_example.rb" zsh: no matches found: b71c152d8f38dcd23ad7600a93f261a7252c59e9^ 私はbashに切り替えましたが、うまくいきました。
zoras

20
Windowsコマンドラインからエラーが発生しました。error: pathspec <filename> did not match any file(s) known to git.。解決策はgit bashを使用することでした。
ドンターナー2012

56
@zoras zshには '^'の独自の拡張がありますが、 '〜1'の代替構文を使用git checkout <deleting-commit>~1 -- <file-path> できます: 〜Xでは、指定したコミットの前にXコミットを指定できるため、〜1は前のコミット、〜2です前の2つのコミットなど
Nils Luxton 2012

22
Windows cmdプロンプトでは、^文字はエスケープ文字です!したがって、cmdでは^^、単一のリテラル^が必要であること、およびその後に何かをエスケープしないことをcmdに指示するために入力する必要があります。多くの人に起こっていること^は、その後にスペースが続くことです。したがって、cmdは、スペースをエスケープしていると見なします-これは、単にスペース文字を生成します。したがって、gitがcli引数を取得するまでには、gitは認識しSHA1、認識しません SHA1^。それは本当に迷惑です。~はエスケープ文字ではないので、それでも機能します。(PS。グーグルがこの情報を必要とする場合は、このコメントに賛成投票してください)
Alexander Bird

875
  1. git log --diff-filter=D --summaryファイルを削除したすべてのコミットとファイルを削除するために使用します。
  2. git checkout $commit~1 path/to/file.ext削除したファイルを復元するために使用します。

$commitステップ1で見つけたcommitの値はどこにありますか。e4cf499627


10
好奇心が強い、〜1は何を指しているのですか?
tommy chheng

7
@tommy-チルダ仕様は、名前付きコミットのn番目の孫を提供します。詳細については、book.git-scm.com / 4_git_treeishes.htmlをご覧ください。
ロバート・ムンテアヌ2011

5
これは、最も簡単で直感的なアプローチです。git log -- *PartOfMyFileName*。ありがとうございました$commit~1
bgs

3
git checkout $commit~1 filename構文は、個々のファイルのための完璧な作品、また、ディレクトリ全体のために働きます。すなわち:SHA 12345から./images内のすべての削除した画像を復元しますgit checkout 12345~1 images。この回答をありがとう!
noinput

34
@Alexar $commit~1は、コミットの名前を追加する必要があることを意味します。1d0c9ef6eb4e39488490543570c31c2ff594426cどこに$commitあるようなもの。
ユージーン

319

削除されたファイルをすべてフォルダーに復元するには、次のコマンドを入力します。

git ls-files -d | xargs git checkout --

1
ファイルはどこにパイプされますか?変化はありません。
ウィリアムグランド

21
これはおそらく最も簡単な方法です。その変態gitは、最も単純な作業でさえどれほど難しいかを変容させました。
jww 2013年

git checkout-[file]は[file]の変更を元に戻します。パイプは[file]を削除されたファイルの名前に置き換えます。
Manu

6
ls-filesサブコマンドは便利ですが、で削除されたファイルのために動作するようには思えないgit rmつまりはOPが尋ねある、おろかコミットし、上演しました。
MarkHu 2017年

これは削除されたファイルを復元するのに役立ちましたが、変更されたM myChangedFile後に表示されるファイルをどのように更新できます git checkoutか?
libby

124

削除したばかりのファイルを復元するためにこの質問に行きましたが、まだ変更をコミットしていませんでした。この状況に陥った場合に備えて、必要なことは次のとおりです。

git checkout HEAD -- path/to/file.ext


93

正気でない場合は、を使用してくださいgit-bisect。ここでは何をすべきかです:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

次に、自動テストを実行します。シェルコマンド'[ -e foo.bar ]'は、foo.bar存在する場合は0を返し、存在しない場合は1 を返します。の「実行」コマンドは、git-bisectバイナリ検索を使用して、テストが失敗した最初のコミットを自動的に見つけます。これは、指定された範囲の途中から(良好から不良まで)開始し、指定されたテストの結果に基づいて半分にカットします。

git bisect run '[ -e foo.bar ]'

今、あなたはそれを削除したコミットにいます。ここから、未来に戻ってgit-revert変更を元に戻すことができます。

git bisect reset
git revert <the offending commit>

または、1つのコミットに戻って、損傷を手動で検査することもできます。

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

2
詳しく説明してもらえますgit bisect run '[ -e foo.bar ]'か?
avdgaag 2009年

自動的にチェックできない場合は、手動で善と悪を使用することもできます。bisectのmanページを参照してください。
ジョシュリー

1
@avdgaag git bisect run語コマンドが返す必要があります。「RUN」は、次のコマンドを実行して二分を自動化するためのGitを伝える0ためにgood(参照バージョンgit help bisect詳細を)。'[ -e foo.bar ]'ファイルがあればテストするための標準的な表現であるfoo.barが存在する(実装はファイル内に通常あるん/usr/bin/[通常にハードリンクされている/usr/bin/test)と単一quationマークは、単一のコマンドライン引数として、すべてのことを置くために使用されています。
Mikko Rantalainen 2013年

いい案。私はこのアプローチを試しましたが、削除前にコミットを特定しましたが、実際にファイルを削除したコミットは特定しませんでした。そして別のテストでは、削除の前に2つのコミットを特定しました。
Michael Osofsky

めちゃくちゃ?多分。しかし、バイセクトは、バグが発生した場所を見つけるのに役立つ優れた方法であるため、とにかく学ぶことは貴重なスキルです。したがって、ここでは「正しい」または「最も正しい」方法ではないかもしれませんが、それでもそれは良いアイデアであり、間違いなく+1の価値があります。
Pryftan

77

私の新しいお気に入りのエイリアスに基づいてbonyiiiさんの回答(upvoted)、および"についての私自身の答え Gitエイリアスコマンドに引数を渡す

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

数回前のコミットで誤ってファイルを削除してしまいましたか?
クイック:

git restore my_deleted_file

危機は回避されました。

警告、Git 2.23(2019年第3四半期)には、(!)という実験的なコマンドが付属していgit restoreます。
したがって、このエイリアスの名前を以下のように変更します。


Robert Daileyコメントで次のエイリアスを提案しています

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

そして、ジーガンコメントに追加します

コマンドラインからエイリアスを設定するために、次のコマンドを使用しました。

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

7
これにより、要求されたファイルだけでなく、コミット全体が復元されます。
ダニエル・バン

5
ここに私のエイリアスは、ある素晴らしく動作します:restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
void.pointer

1
@RobertDaileyいいですね!わかりやすくするため、回答にあなたのエイリアスを含めました。
VonC 2014年

1
:コマンドラインからエイリアスを設定するために、私は、このコマンドを使用git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
jegan

2
Expansion of alias 'restore' failed; '!git' is not a git command
Karl Morrison

55

ファイル名がわかっている場合、これは基本的なコマンドを使用した簡単な方法です。

そのファイルのすべてのコミットをリストします。

git log -- path/to/file

最後のコミット(最上位)は、ファイルを削除したコミットです。したがって、最後から2番目のコミットを復元する必要があります。

git checkout {second to last commit} -- path/to/file

このソリューションを使用しただけで、削除のコミットはありませんでした。しかし、最新のコミットIDを使用してファイルを復元できました。
アダム

最後から2番目のコミット(削除に対する以前のコミット)には、削除されたファイルの最新バージョンが含まれていませんか?最後から2番目(以前の削除へのコミットの前のコミット)は、絶望的に時代遅れになる可能性があります。
Suncat2000 2018年

1
これは私が見た最初の解決策であり、十分に単純で、次回ここに戻ってそれを見つける必要はありません。多分。
Eloff、2018

@ Suncat2000の「最後から2番目」は「削除への以前のコミット」を意味し、「最後から2番目」と同じです。en.wiktionary.org/wiki/penultimate#Synonyms
wisbucky

この回答をありがとうございました!!!!!!
Rakesh Bk

29

削除およびコミットされたファイルを復元するには:

git reset HEAD some/path
git checkout -- some/path

Gitバージョン1.7.5.4でテストされています。


1
それは私にはうまくいきませんでした。チェックアウト後、error: pathspec 'foo' did not match any file(s) known to git.ファイル名が正しいことを確認しました。Gitバージョン2.7.0
wisbucky 2016

-1; これは間違っています。これらのコマンドは、削除取り消します、まだコミットされていない(最初のものは、それの段階的な場合は、削除をunstages、およびファイルへの二番目の破棄unstaged変更を)、しかし、あなたは彼らが復元だろうとここで主張しているコミットをファイルの削除。これは単に真実ではなく、上記の@wisbuckyのコメントのようなエラーで失敗します。
Mark Amery 2017

@MarkAmery確かに、このコマンドは、で削除されたファイルをコミットするための明示的なステージングを行わなかった開発者にとってうまく機能したと思いgit add -Aますが、復元されたファイルはまだコミットされていない段階でした。
Fedir RYKHTIK 2017

25

変更を加えてファイルを削除したが、コミットはしなかったが、変更を破棄した場合

git checkout -- .

ただし、削除したファイルが返されなかった場合は、次のコマンドを実行するだけです。

git checkout <file_path>

そしてプレスト、あなたのファイルが戻ってきました。


24

私はこの解決策を持っています

  1. 以下のいずれかの方法を使用して、ファイルが削除されたコミットのIDを取得します。

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* #何も覚えていない場合にお勧め
  2. あなたは次のようなものを得るはずです:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7作成者:Alexander Orlov日付:Thu May 12 23:44:27 2011 +0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

コミット3ea4e3af253ac6fd1691ff6bb89c964f54802302作成者:Alexander Orlov日付:Thu May 12 22:10:22 2011 +0200

。コミットID bfe68bd117e1091c96d2976c99b3bcc8310bebe7を使用してください。

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

コミットIDはファイルがすでに削除されているコミットを参照するため、bfe68bの直前にコミットを参照する必要があります^1。これは、を追加することで実行できます。つまり、bfe68bの直前にコミットしてください。


これは受け入れられた回答と同じアプローチですが、削除するコミットを見つけるいくつかの方法があります。私は今でも受け入れられた回答で採用されているアプローチが好きですが、これらは良い代替案です。ありがとう!
avdgaag 2012年

削除されたファイルを最初にチェックアウトし、次に(それを変更せずに)コミットしても、ファイルのコピーは作成されないと思います。正しい?(私は画像でこれを行う必要があり、そしてコピーはリポジトリが大きくなるだろう)
Stonecrusher


12

git undelete path/to/file.ext

  1. これをあなたの.bash_profile(またはコマンドシェルを開いたときにロードされる他の関連ファイル)に入れてください:

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  2. 次に使用します:

    git undelete path/to/file.ext
    

このエイリアスは、最初にこのファイルが存在する最後のコミットを確認してから、このファイルが存在する最後のコミットからそのファイルパスのGitチェックアウトを実行します。ソース


11

多くの場合、Gitと組み合わせてcoreutils(grep、sedなど)を使用すると便利です。私はこれらのツールをすでに十分に知っていますが、Gitはそうではありません。削除されたファイルを検索したい場合は、次のようにします。

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

リビジョン/コミットを見つけたら:

git checkout <rev>^ -- path/to/refound/deleted_file.c

他の人が私の前に言ったように。

これで、ファイルは削除前の状態に復元されます。維持したい場合は、作業ツリーに再度コミットすることを忘れないでください。


7

特定のコミットから削除された一連のファイルを復元する必要があり、2つのコマンドで管理しました。

git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- 
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD 

(各コマンドの最後の末尾のスペースに注意してください。)

ファイルは.gitignoreファイルに追加され、でクリアされましたgit rm。ファイルを復元する必要がありましたが、ステージングを解除しました。私は何百ものファイルを復元する必要があり、他の例のようにファイルごとに手動で入力するのは遅すぎました。


7

実際、この質問は直接Gitに関するものですが、私のような誰かがWebStorm VCSなどのGUIツールを使用しています Git CLIコマンドについて知る以外にます。

削除したファイルを含むパスを右クリックし、Gitに移動して、[ 履歴の表示 ]をクリックします。

ここに画像の説明を入力してください

VCSツールはすべてのリビジョントレインを表示し、それぞれのすべてのコミットと変更を確認できます。

ここに画像の説明を入力してください

次に、友達がPostAd.jsファイルを削除するコミットを選択します。以下をご覧ください:

ここに画像の説明を入力してください

そして今、私は私の欲求が削除されたファイルを見ることができます。ファイル名をダブルクリックするだけで回復します。

ここに画像の説明を入力してください

私の答えはGitコマンドではないことはわかっていますが、初心者やプロの開発者にとっては高速で信頼性が高く、簡単です。WebStorm VCSツールは、Gitでの作業に最適であり、他のプラグインやツールを必要としません。


1
これはすごい!ありがとうございました。JetBrainsのIDEのいずれかを使用するユーザーにとって、間違いなく簡単なソリューションです。
Fabiano Arruda

イメージの場合、ファイルをどのように復元しますか?
Nodirabegimxonoyim

@FabianoArruda様、JetBrains IDEは開発のための強力なツールです。あなたの素敵なコメントをありがとう。
AmerllicA

@PeterMortensenの編集に感謝します。
AmerllicA

6

同じ質問がありました。それを知らずに、ぶら下がりコミットを作成しました

ダングリングコミットの一覧表示

git fsck --lost-found

ぶら下がっている各コミットを検査する

git reset --hard <commit id>

ぶら下がりコミットに移動すると、ファイルが再表示されました。

git status その理由のために:

“HEAD detached from <commit id where it detached>”


2
どうもありがとうございました。何千行ものコードを復元するのを手伝ってくれました。
ルーベン

5
user@bsd:~/work/git$ rm slides.tex
user@bsd:~/work/git$ git pull 
Already up-to-date.
user@bsd:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory

削除したファイルを復元します。

user@bsd:~/work/git$ git checkout
D       .slides.tex.swp
D       slides.tex
user@bsd:~/work/git$ git checkout slides.tex 
user@bsd:~/work/git$ ls slides.tex
slides.tex

2
問題は、ファイルが削除されて変更がコミットされた後のファイルの復元に関するものでした。この答えは、作業ディレクトリでのみ削除されたファイルを復元することです。
akaihola 2013

それは本当です、そしてそれが私が探していたものでした。
Hola Soy Edu Feliz Navidad 14

4

ファイルを削除したコミットがわかっている場合<SHA1_deletion>は、次のコマンドを実行します。ファイルを削除したコミットは次のとおりです。

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

パイプの前の部分には、コミットで削除されたすべてのファイルがリストされます。それらはすべて、それらを復元するための前回のコミットからのチェックアウトです。


4

ファイルを削除したコミットを見つけます。

git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '

出力例:

4711174

Git 2.23以降、実際にはrestoreコマンドがあります。それはまだ実験あなたが入力することはできますが、(この場合は4711174)コミットで削除何かを復元するために:

git restore --source=4711174^ path/to/file

前にコミットから何かを復元したいので、コミットIDの後の^に注意してくださいファイルを削除の。

--source引数は伝えますrestoreどこ復元するファイル(複数可)を探しにコマンドをし、それがどのコミットしても、指標となります。

参照:git 2.23.0のgit-restoreドキュメント


4

私たちのケースでは、コミットで誤ってファイルを削除しましたが、後でいくつかのコミットで間違いに気付き、変更されたファイルではなく、削除されたすべてのファイルを取り戻したいと考えました。

チャールズベイリーの優れた答えに基づいて、これが私のワンライナーです:

git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)

2

シンプルで正確な

まず第一に、あなたがそのファイルを持っている最新の安定したコミットを取得します-

git log 

$ commitid 1234567 ...を見つけたとします。

git checkout <$commitid> $fileName

これにより、そのコミットにあったファイルバージョンが復元されます。


1

それを行う最良の方法については、それを試してください。


まず、ファイルを削除したコミットのコミットIDを見つけます。ファイルを削除したコミットの概要が表示されます。

git log --diff-filter = D --summary

git checkout 84sdhfddbdddf〜1

注:84sdhfddbdddあなたのcommit id

これにより、削除されたすべてのファイルを簡単に復元できます。


1

git revertファイルを削除したコミットはいつでもできます。(これは、削除がコミットの唯一の変更であると想定しています。

> git log
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:11:06 2019 -0700

    deleted readme.md

作業を続け、後でその削除コミットをコミットしたくないことに気付いた場合は、次のコマンドを使用して元に戻すことができます。

> git revert 2994bd

git log示しています:

> git log
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:17:41 2019 -0700

    Revert "deleted readme"

    This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.

そしてreadme.md、リポジトリに復元されました。


質問は、ファイルが削除された後に多くのコミットが行われたことを想定しているため、後続のコミットが不要であるという兆候がないため、上記の状況でOPを支援する可能性は低いと思われます。
ジョナサンレフラー

1
うん!後続のコミットを行っても、削除コミットを元に戻すことができます。したがって、コミット111がファイルを削除し、コミット
222、333、444で

0

以下のコードを使用して以前のファイルをローカルディレクトリに取得するこの問題もあります。

git checkout <file path with name>

以下の例は私のために働いています:

git checkout resources/views/usaSchools.blade.php


何が問題なのか説明してください
Akbor

削除はすでにコミットされています。この場合、復元元のコミットを指定する必要があります。
sba


-1

削除がコミットされていない場合、以下のコマンドは削除されたファイルを作業ツリーに復元します。

$ git checkout -- <file>

以下のコマンドを使用して、作業ツリーで削除されたすべてのファイルのリストを取得できます。

$ git ls-files --deleted

削除がコミットされている場合は、削除が行われた場所を見つけ、このコミットからファイルを回復します。

$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>

回復するファイルのパスを探している場合、次のコマンドを実行すると、削除されたすべてのファイルの概要が表示されます。

$ git log --diff-filter=D --summary

-1

削除されたすべてのファイルをGitで復元するには、次の操作も実行できます。

git checkout $(git ls-files --deleted)

Where git ls-files --deletedは、削除されたすべてのファイルをgit checkout $(git command)一覧表示し、パラメータのファイルの一覧を復元します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.