プロジェクトのコミット履歴で削除されたファイルを見つける方法は?


1275

むかしむかし、自分のプロジェクトに取得したいファイルがありました。

問題は、いつ削除したか、どのパスにあったかがわからないことです。

このファイルが存在するときに、このファイルのコミットを見つけるにはどうすればよいですか?


ここでは、同様の質問:stackoverflow.com/questions/7093602/...は
eckes


13
ここでの回答は、重複した回答よりも私にとって有用です。
フェリペアルバレス2017年

5
同意しました...重複に関係なく... Google検索で表示されませんでした...これはそうでした...重複後に追跡する時間を無駄にしないことを願っています...時間とGoogleのアルゴリズムのみがどの質問が一番良いか教えてください。
Tim Boland、2018

回答:


1601

使用できる正確なパスがわからない場合

git log --all --full-history -- "**/thefile.*"

ファイルのパスがわかっている場合は、次のようにできます。

git log --all --full-history -- <path-to-file>

これにより、そのファイルを操作したすべてのブランチのコミットのリストが表示されます。次に、必要なファイルのバージョンを見つけて表示することができます...

git show <SHA> -- <path-to-file>

または、次のコマンドで作業コピーに復元します。

git checkout <SHA>^ -- <path-to-file>

^チェックアウトを取得するキャレット記号()に注意してください特定されたものより前<SHA>ます。コミットの時点でファイルが削除されているため、削除されたファイルの内容を取得するには、以前のコミットを調べる必要があります。


2
絶対パスではなく相対パスを使用してみてください(まだの場合)。
アンバー

63
正確なパスがわからない場合はどうなりますか?あなたが知っているのはファイル名だけですか?
priestc

17
@PedroMorteRolo git log -- <path>は、ファイルが存在しなかったブランチにいる場合、何も出力しません。git log --all -- <path>他のブランチで発生した変更を見逃さないように、常にを使用する必要があります。このコマンドgit log -- <path>は、複数のブランチがあり、パスやブランチ(私のように)を忘れがちな場合は非常に危険な場合があり、他の開発者と作業する場合も危険です。
ホブ2014

4
@アンバー、他のブランチの変更やファイルを見逃さないように、回答に--allフィリップのおかげで)追加することを検討してくださいgit log。それは私のような忘れっぽい人々を多くの悲しみから救うでしょう。
ホブ、2014

3
以下の回答で述べたように、ファイルの復元はgit checkout <SHA>^ -- <path-to-file>(^記号に注意)する必要があります。<SHA>コミットの時点でファイルが削除されているため、削除されたファイルのコンテンツを取得するには、以前のコミットを確認する必要があります
kipelovets

393

削除されたファイルのリストを取得し、削除されたファイルの完全なパスをコピーします

git log --diff-filter=D --summary | grep delete

次のコマンドを実行して、そのコミットのコミットIDを見つけ、そのコミットIDをコピーします

git log --all -- FILEPATH

削除されたファイルの差分を表示

git show COMMIT_ID -- FILE_PATH

覚えておいてください、あなたが使用してファイルに出力を書き込むことができます>ように

git show COMMIT_ID -- FILE_PATH > deleted.diff

1
最初のステップでパスを見つけましたが、2番目のステップで次のエラーがスローされますunknown revision or path not in the working tree
jvannistelrooy 14

6
削除と一緒にハッシュをコミット表示するには、行うことができますgit log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
クリス・ミドルトン

1
ステップ2は何も返しません。なぜそれが起こり得るのかについての考えはありますか?私のファイル名は正しいです。
Denis Kniazhev 2015

2
3 1に機能を兼ね備え見つけるには、あなたの.bashrcや.zshrcにこれを追加します。git-grep-latest(){ result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk '{print $4;}'); latest_commit=$(git log --all -- $result_path | head -1 | awk '{print $2;}'); git show $latest_commit -- $result_path; }そして今、あなただけ行うことができます:git-grep-latest some_text
randomor

1
@TylerJonesは、パイプを使用してLinuxで何にでもフィードlinux pipesできます-グーグル..あなたはそれが好きでしょう。
ジョンハント

37

受け入れられた応答を編集できなかったため、ここに回答として追加し、

gitでファイルを復元するには、次を使用します(SHAの直後の '^'記号に注意してください)

git checkout <SHA>^ -- /path/to/file

^が必要な理由がわかりません。ファイルはそのSHAでのコミットにあります...そこから別のコミットに戻る必要があるのはなぜですか?
Tony K.

19
これは、そのshaが「削除済み」としてコミットされているため、まだ存在しません。実際にそれを取り戻すには、その前にコミットに移動する必要があります。
tandrewnichols 2013

6
@tandrewnicholsは、間違ったコミットSHAを使用していることを意味します-必要なバージョンのファイルのコミットが必要です ...これはおそらくファイルが削除されたバージョンではありません。
アンバー

6
@アンバーとあなたが望むコミットはそれが削除される前の最新のものである可能性が高いので、この答えです。
サムホルダー

1
@AlexR:<SHA>~1引用符で囲む必要なしに同じように動作するはずです。
CodeManX

37

と呼ばれるファイルを回復したいとします MyFileが、そのパス(またはその拡張子については)が不明であるとします。

予備:git rootにステップして混乱を避ける

重要なプロジェクトには、類似または同一の名前を持つ複数のディレクトリがある場合があります。

> cd <project-root>
  1. 完全なパスを見つける

    git log --diff-filter = D --summary | grep削除| grep MyFile

    delete mode 100644 full/path/to/MyFile.js

full/path/to/MyFile.js 探しているパスとファイルです。

  1. そのファイルに影響を与えたすべてのコミットを特定する

    git log --oneline --follow-full / path / to / MyFile.js

    bd8374c Some helpful commit message

    ba8d20e Another prior commit message affecting that file

    cfea812 The first message for a commit in which that file appeared.

  2. ファイルをチェックアウトする

最初にリストされたコミット(年代順では最後、ここではbd8374c)を選択すると、そのコミットで削除されたため、ファイルは見つかりません。

> git checkout bd8374c -- full/path/to/MyFile.js

`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`

前の(キャレットを追加する)コミットを選択するだけです。

> git checkout bd8374c^ -- full/path/to/MyFile.js

3
これは、受け入れられた回答よりもはるかに明確です
Pouyan Khodabakhsh

:Windowsコンソール(CMD)のために、使用は、ステップ2で代わりのgrepの見つけgit log --diff-filter=D --summary | find "delete" | find "MyFile"ハッシュを囲む引用符に注意してください、そしてSTEP3:git checkout "bd8374c^" -- full/path/to/MyFile.js
user5542121

30

@アンバーが正解しました!もう1つ追加してください。ファイルの正確なパスがわからない場合は、ワイルドカードを使用できます。これでうまくいきました。

git log --all -- **/thefile.*

4
@PedroMorteRoloうーん。既存の回答を上位投票の回答にコピーすることについてどのように感じているのかわかりません:/この回答はそれ自体でも役に立ちました。賛成票で十分だったのでしょうか?
クレメント2016年

1
ファイルがプロジェクトルート(Cygwinでテスト済み)にある場合、ファイルは見つかりません。
wortwart 2017年

19

以下は、devまたはgitユーザーがリポジトリのルートディレクトリから削除されたファイル名を渡して履歴を取得できる簡単なコマンドです。

git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all -- 

誰かがコマンドを改善できる場合は、実行してください。


1
素晴らしいです、ありがとう!私のファイルはまったく存在しなかったように見えますが、それは別の非常に

ファイルが「欠落」しているように見える場合は、リポジトリのルートディレクトリからこれを実行してください
samaspin

ありがとう@samaspinが回答を更新しました。
Jason

18

ビューアを使用してみてください。たとえばgitk、履歴を参照して、覚えている半分のファイルを見つけることができます。(gitk --allすべてのブランチで必要に応じて使用)


4
その--allオプションは、あなたの答えと受け入れられた答えの両方にとって重要です。
ホブ2014

3
ほとんどのプロジェクトでは、履歴を参照するのに非常に時間がかかります。
mikemaccana

5

概要:

  1. ステップ1

削除されたファイルの履歴でファイルのフルパスを検索します git log --diff-filter=D --summary | grep filename

  1. ステップ2

削除される前にコミットからファイルを復元した

restore () {
  filepath="$@"
  last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')
  echo "Restoring file from commit before $last_commit"
  git checkout $last_commit^ -- $filepath
}

restore my/file_path

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