Gitでファイルが削除された日時を確認する


1035

n個のコミットがあるGitリポジトリがあります。

必要なファイルがあり、そのファイルは以前はリポジトリにありました。突然「Oh!あのファイルはどこに行きますか?」

「ファイルnevery_needed.txtはコミットn-13で削除された」と私に知らせる(一連の)Gitコマンドはありますか?

言い換えると、個々のコミットをすべて確認せず、Gitリポジトリにすべてのファイルのすべての変更があることを知らなくても、そのファイルを含む最後のコミットをすばやく見つけて、それを取り戻すことができますか?



2
Pedroによって共有されたリンクは、私の質問に対する答えを持っています:パスを覚えていないときに削除されたファイルを見つける方法。
Gordon Bean

回答:


1127

git log --full-history -- [file path] ファイルの変更を表示し、ファイルが削除された場合でも機能します。

例:

git log --full-history  -- myfile

ファイルを削除した最後のコミットのみを表示したい場合は、さらに-1を使用します。たとえば、 git log --full-history -1 -- [file path]

参照ファイルを削除し、どのコミット


16
パターンを検索することは可能ですか?私はファイルの完全な名前を忘れました=(多分すべての削除のログを取得することは可能ですか?
wutzebaer

6
ここでそれを見つけた:stackoverflow.com/questions/6017987/...
wutzebaer

6
PowerShellを使用している場合は、ハイフンをエスケープする必要があることに注意してください:git log '-' [ファイルパス]。うまくいけば、これは他の誰かと同じように歯をむくことができます。
A.ウィルソン

68
git log -- */<<filename>>.<<file extension>>ファイルパス全体がわからない場合でも検索できました。
トムハワード

2
@MERose角括弧は、実際のファイルパスのプレースホルダーとして存在します。
Emile Bergeron、2016年

229

簡潔な答え:

git log --full-history -- your_file

に触れたマージコミットを含む、リポジトリの履歴内のすべてのコミットが表示されますyour_file。最後の(上)は、ファイルを削除したものです。

いくつかの説明:

--full-historyここの旗は重要です。これがないと、Gitはファイルのログを要求するときに「履歴の単純化」を実行します。ドキュメントはこれが正確にどのように機能するかについての詳細については軽く、私はソースコードからそれを理解しようとするために必要なグリットと勇気に欠けていますが、git-logドキュメントにはこれだけのことを言っています:

デフォルトモード

履歴を単純化して、ツリーの最終状態を説明する最も単純な履歴にします。最終結果が同じである場合(つまり、同じ内容のブランチをマージする場合)は、いくつかのサイドブランチを枝刈りするため、最も単純です。

これは、その歴史を私たちが望むファイルがされている場合については明らかで削除された削除されたファイルの最終状態を説明する最も簡単な歴史がないので、何の歴史。ファイルが作成されたことがgit logない--full-historyと単純に主張するリスクはありますか?残念ながらそうです。ここにデモンストレーションがあります:

mark@lunchbox:~/example$ git init
Initialised empty Git repository in /home/mark/example/.git/
mark@lunchbox:~/example$ touch foo && git add foo && git commit -m "Added foo"
[master (root-commit) ddff7a7] Added foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
mark@lunchbox:~/example$ git checkout -b newbranch
Switched to a new branch 'newbranch'
mark@lunchbox:~/example$ touch bar && git add bar && git commit -m "Added bar"
[newbranch 7f9299a] Added bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git rm foo && git commit -m "Deleted foo"
rm 'foo'
[master 7740344] Deleted foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 foo
mark@lunchbox:~/example$ git checkout newbranch
Switched to branch 'newbranch'
mark@lunchbox:~/example$ git rm bar && git commit -m "Deleted bar"
rm 'bar'
[newbranch 873ed35] Deleted bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git merge newbranch
Already up-to-date!
Merge made by the 'recursive' strategy.
mark@lunchbox:~/example$ git log -- foo
commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log -- bar
mark@lunchbox:~/example$ git log --full-history -- foo
commit 2463e56a21e8ee529a59b63f2c6fcc9914a2b37c
Merge: 7740344 873ed35
Author: Mark Amery 
Date:   Tue Jan 12 22:51:36 2016 +0000

    Merge branch 'newbranch'

commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log --full-history -- bar
commit 873ed352c5e0f296b26d1582b3b0b2d99e40d37c
Author: Mark Amery 
Date:   Tue Jan 12 22:51:29 2016 +0000

    Deleted bar

commit 7f9299a80cc9114bf9f415e1e9a849f5d02f94ec
Author: Mark Amery 
Date:   Tue Jan 12 22:50:38 2016 +0000

    Added bar

git log -- bar上記のターミナルダンプでは、文字どおり出力されないことに注意してください。Gitは、歴史を、bar存在しなかったフィクションに「簡略化」しています。git log --full-history -- bar一方、作成barしたコミットと削除したコミットが表示されます。

明確にするために:この問題は単なる理論的なものではありません。削除されたファイルを追跡しようとした実際のリポジトリで失敗していた--full-historyため、ドキュメントを調べただけでフラグを発見git log -- some_fileしました。履歴の簡略化は、現在存在するファイルがどのようにして現在の状態になったかを理解しようとするときに役立つ場合がありますが、ファイルの削除を追跡しようとすると、関心のあるコミットを表示にすることで失敗する可能性が高くなります。--full-historyこの使用例では常にフラグを使用してください。


4
これは現在のブランチに関連する履歴のみを検索することに注意してください(「レポ全体の履歴」ではありません)...つまり、ファイルが現在のブランチでまだ削除されておらず、別のブランチにある場合、削除コミットは見つかりません。ファイルがすでに削除されているブランチにいる必要があります。考えてみると当たり前かもしれませんが、最初は戸惑いました。
エントロピー2018

1
この答えは機能します。しかし、git log出力自体からは、最後のコミットによってファイルが削除されたことはまったく明らかではありません。私も試してみましたgit log --name-status --full-history -- file_namegit log -p --stat --full-history -- file_name、しかし、最新のコミット中にも明示的にファイルが削除されたことを示しています。これはバグのようです。
Martin_W 2018

@Martin_ATS mkdir somedir && cd somedir && git init && touch foo && git add foo && git commit -m "Added foo" && git checkout -b newbranch && touch bar && git add bar && git commit -m "Added bar" && git checkout master && git rm foo && git commit -m "Deleted foo" && git checkout newbranch && git rm bar && git commit -m "Deleted bar" && git checkout master && git merge newbranch && git log --name-status --full-history -- barD barA barGit 2.12.2のログ出力に含まれています。これらの行が出力に表示されませんか?どのバージョンがありますか?
マークアメリー2018

git version 2.15.1はい、コマンドシーケンスはとを報告D barA barます。おそらく、私の問題は私のファイルの履歴に固有のものです。私は.htaccessgitignoreされて削除されたファイルの履歴を追跡していました。私は最終的にそれを理解し、ファイルを追加し直しました。コマンドに含める--name-statusと、git log2つのA .htaccessエントリが表示されます(最新のコミットで追加したため)が表示されませんD .htaccess。そのため、ファイルがリポジトリから削除されていてもgit log、明示的なD file_nameエントリが表示されない場合があります。
Martin_W

@Martin_ATS好奇心が強い。おそらく.htaccessコミットXに追加されたが、マスターXをもたらしたマージコミットに含まれていないのだろうか?ファイルが追加されていて削除されておらず、まだ存在していないように見えるべきだと私が考える可能性があると私が考えることができる唯一のことです。MCVEを試してみて、それがGitバグかどうかを判断し、そうでない場合は、私の答えを微調整してケースを処理することが可能かどうかを判断するのは興味深いでしょう。
Mark Amery

84

Gitログですが、パスの前に --

例えば:

dan-mac:test dani$ git log file1.txt
fatal: ambiguous argument 'file1.txt': unknown revision or path not in the working tree.

dan-mac:test dani$ git log -- file1.txt
 commit 0f7c4e1c36e0b39225d10b26f3dea40ad128b976
 Author: Daniel Palacio <danpal@gmail.com>
 Date:   Tue Jul 26 23:32:20 2011 -0500

 foo

31

regexpを使用して削除されたファイルのコミットを見つけるためのソリューションをここに追加しました(gitにリポジトリ内のすべての削除されたファイルを一覧表示する方法はありますか?)

git log --diff-filter=D --summary | sed -n '/^commit/h;/\/some_dir\//{G;s/\ncommit \(.*\)/ \1/gp}'

some_dir(cascading)という名前のディレクトリ内で削除されたすべてを返します。そこにあるsed正規表現\/some_dir\/はどこにでもあります。

OSX(@tripleeおよび@keifに感謝)

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }

1
いいね。OS Xのbashにおけるいくつかの不一致:sed: 1: "/^commit/h;/\/some_dir\ ...": bad flag in substitute command: '}'
Brent Faust

@BrentFoustそれは私がテストすることはできません...末尾にスペースを追加してみてください(中括弧の後、単一引用符の前)、オンラインのmanページはそれについて明確ではありません...
estani

いい提案です。ただし、単一引用符の前にスペースを追加しても効果がありませんでした。閉じ括弧の前にもスペースはありませんでした。
ブレントファウスト

1
BSD / OSX sedは、コマンドの区切り文字としてセミコロンを使用すると常に良いとは限りません。それらを改行に変更するか、次のように変更してみてくださいsed -n -e '/^commit/h' -e '\:/some_dir/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
tripleee

1
私はそれをテストし、git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }OSXで動作しました。
keif

21

次のようにして、ファイルを削除した最後のコミットを見つけることができます。

git rev-list -n 1 HEAD -- [file_path]

詳細については、こちらをご覧ください


11
主な賛成の解決策は私にはうまくいきませんでしたが、これはうまくいきました。
ニック・ハイナー

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