n個のコミットがあるGitリポジトリがあります。
必要なファイルがあり、そのファイルは以前はリポジトリにありました。突然「Oh!あのファイルはどこに行きますか?」
「ファイルnevery_needed.txtはコミットn-13で削除された」と私に知らせる(一連の)Gitコマンドはありますか?
言い換えると、個々のコミットをすべて確認せず、Gitリポジトリにすべてのファイルのすべての変更があることを知らなくても、そのファイルを含む最後のコミットをすばやく見つけて、それを取り戻すことができますか?
n個のコミットがあるGitリポジトリがあります。
必要なファイルがあり、そのファイルは以前はリポジトリにありました。突然「Oh!あのファイルはどこに行きますか?」
「ファイルnevery_needed.txtはコミットn-13で削除された」と私に知らせる(一連の)Gitコマンドはありますか?
言い換えると、個々のコミットをすべて確認せず、Gitリポジトリにすべてのファイルのすべての変更があることを知らなくても、そのファイルを含む最後のコミットをすばやく見つけて、それを取り戻すことができますか?
回答:
git log --full-history -- [file path] ファイルの変更を表示し、ファイルが削除された場合でも機能します。
例:
git log --full-history -- myfile
ファイルを削除した最後のコミットのみを表示したい場合は、さらに-1を使用します。たとえば、 git log --full-history -1 -- [file path]
git log -- */<<filename>>.<<file extension>>ファイルパス全体がわからない場合でも検索できました。
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この使用例では常にフラグを使用してください。
git log出力自体からは、最後のコミットによってファイルが削除されたことはまったく明らかではありません。私も試してみましたgit log --name-status --full-history -- file_nameとgit log -p --stat --full-history -- file_name、しかし、最新のコミット中にも明示的にファイルが削除されたことを示しています。これはバグのようです。
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 -- barはD bar、A barGit 2.12.2のログ出力に含まれています。これらの行が出力に表示されませんか?どのバージョンがありますか?
git version 2.15.1はい、コマンドシーケンスはとを報告D barしA barます。おそらく、私の問題は私のファイルの履歴に固有のものです。私は.htaccessgitignoreされて削除されたファイルの履歴を追跡していました。私は最終的にそれを理解し、ファイルを追加し直しました。コマンドに含める--name-statusと、git log2つのA .htaccessエントリが表示されます(最新のコミットで追加したため)が表示されませんD .htaccess。そのため、ファイルがリポジトリから削除されていてもgit log、明示的なD file_nameエントリが表示されない場合があります。
.htaccessコミットXに追加されたが、マスターXをもたらしたマージコミットに含まれていないのだろうか?ファイルが追加されていて削除されておらず、まだ存在していないように見えるべきだと私が考える可能性があると私が考えることができる唯一のことです。MCVEを試してみて、それがGitバグかどうかを判断し、そうでない場合は、私の答えを微調整してケースを処理することが可能かどうかを判断するのは興味深いでしょう。
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
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 }
sed: 1: "/^commit/h;/\/some_dir\ ...": bad flag in substitute command: '}'
sedは、コマンドの区切り文字としてセミコロンを使用すると常に良いとは限りません。それらを改行に変更するか、次のように変更してみてくださいsed -n -e '/^commit/h' -e '\:/some_dir/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }OSXで動作しました。
試してください:
git log --stat | grep file