当一个";“由我们删除”;文件已在git中删除

当一个";“由我们删除”;文件已在git中删除,git,delete-file,git-merge-conflict,Git,Delete File,Git Merge Conflict,我有两个分支:master,和一个长期运行的特性分支,称为feature。我不断地从master合并到feature 我的合并冲突之一是: Unmerged paths: (use "git add/rm <file>..." as appropriate to mark resolution) deleted by us: foo.file 我的解释是,该文件在master上更新,但在feature上删除。我想看看哪个功能提交删除了它。接下来,我试着: $ git

我有两个分支:
master
,和一个长期运行的特性分支,称为
feature
。我不断地从
master
合并到
feature

我的合并冲突之一是:

Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)
    deleted by us:   foo.file
我的解释是,该文件在
master
上更新,但在
feature
上删除。我想看看哪个
功能
提交删除了它。接下来,我试着:

$ git log --oneline --name-status --full-history -- foo.file
0e051cd636 (feature) Merge from master
ee5c4f1ccc (feature) Merge from master
c200d5d8b2 (master) Add foo.file
A   foo.file
我希望看到
--name status
中的
D foo.file
行,但我没有看到。当我在两个合并提交上显示时,我得到了空输出:

$ git show 0e051cd636 -- foo.file
$ git show ee5c4f1ccc -- foo.file
$ 
$ git log --diff-filter=D --summary foo.file
$
此命令还提供空输出:

$ git show 0e051cd636 -- foo.file
$ git show ee5c4f1ccc -- foo.file
$ 
$ git log --diff-filter=D --summary foo.file
$
我还尝试了链接问题中建议的
rev list
,但它的输出也是空的:

$ git rev-list -n 1 HEAD -- foo.file
$

那么,我如何确定该文件是何时被删除的呢?

如何列出从git存储库中删除的所有文件:

git log--diff filter=D--summary

因此,您将看到所有已删除的文件,其中包含删除文件的提交哈希


TL;DR:将
-m
添加到
git日志
命令中

在这里,
git log
命令有一个令人讨厌的小习惯/缺陷:当它遇到合并提交时,默认情况下,它不需要在这些提交上运行
git diff
。这适用于
git log-p
(“show me a diff”变量)和
git log--foo.file
。您(正确地)插入了
--完整历史记录
,以克服
git log
的另一个坏习惯,即在与文件名一起使用时启用历史简化。有时这是可以的,但在您关心的情况下不是这样,但它仍然懒于合并提交

这里的大锤,相当于
--完整历史
,在让
git log
完成所有工作方面,是使用
-m
。这告诉Git(实际上)拆分每个合并。基本问题是:

  • 每次提交(包括合并提交)都会存储所有文件的快照。1
  • 但我们通常希望看到更改的文件中发生了什么变化(
    git log-p
对于普通的非合并提交,这很简单:Git只需将父级和子级提交提取到一个临时区域(内存中和快捷方式中),并比较两个快照。对于每个相同的文件,它什么也不做。对于任何不同的文件,包括“在子文件中新建,在父文件中不存在”或“从子文件中删除,在父文件中存在,但已删除”-Git现在可以比较文件的内容并生成差异,或使用
--名称状态
–只需告诉我们文件已根据需要进行修改、添加或删除

但根据定义,合并提交至少有两个父级。Git应该提取并比较哪一个?如果我们将子对象与其第一个父对象进行比较,我们将得到一组文件和更改;如果我们将子项与其第二个父项进行比较,我们会得到一组不同的文件和更改。2应该
git log
显示哪一个

git log的默认作弊答案是:不要麻烦

也就是说,
git log
只是对自己说:哦,嘿,合并提交。。。那些太难了!我只是不想做任何事,希望没人注意到

如果该文件由于合并而被删除,并且
git log
没有任何说明,那么您永远不会看到该文件被删除

-m
标志告诉
git log
:当您遇到一个合并提交时—一个有n个≥ 2个父对象对每个子对象执行一个单独的
git diff
,就好像有n个单独的单亲提交一样。这是很容易做到的:不再存在“我们该如何处理多个父母”的问题。因此,这是一个普通的差异,并将显示删除,如果有删除

您还可以使用其他标志强制
git log
更加努力地工作,但它们不一定对这种特殊情况有帮助。由于
-m
是一把大锤子,它总是能工作;它可能会产生比你需要的更多的输出。如果你是Git忍者,你可以使用
-c
-cc
和/或
-第一父母
和/或选择性病史简化进行外科手术。但是,
-m——完整的历史记录
起到了作用


1更准确地说,每次提交都会存储该提交中所有文件的快照。这样说听起来是多余的:commit存储它存储的文件。不过,这里的想法是区分这些重要情况:提交是存储与以前提交的差异,还是存储快照?答案是它存储了一个快照。如果我们没有合并提交,这可能无关紧要,但我们确实有合并提交,因此它确实很重要

(即使如此,如果Git总是存储与前一个第一个父级的差异,而不是存储快照,我们可以构建我们需要的。因此,我们回到了“也许没关系”。但事实上,Git字面上存储快照,因此我们不妨描述它是如何工作的,而不是理论上的等价物。:-)


2如果两个父级是不同的提交,但两个父级都有相同的快照,那么我们将从两个比较中得到相同的更改集。但是这是非常罕见的。

-m
添加到
git日志中--一行--名称状态--完整历史--foo.file
命令。否则,
git log
不会说明文件在合并提交中被删除的位置,假设合并提交是文件被删除的位置。(您可能还想禁用重命名检测,使用
--无重命名
,尽管这在这里可能是不必要的,因为您没有使用
--follow
)注意,但是,当实际问题是涉及f的高级冲突时,冲突合并中的
git status
可以说已被我们删除