当一个";“由我们删除”;文件已在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
可以说已被我们删除