我试图列出分支历史记录中任何一点存在但随后被删除且不存在于该分支的最新提交中的所有文件的名称。
其他类似(但不相同)问题的答案表明:
git log --all --pretty=format: --name-only --diff-filter=D
但这列出了分支历史记录中所有提交的所有单个文件删除操作,而不考虑文件是否被重新添加。
我经常使用 git ,这很危险,而且我的术语可能有点偏差,所以这里是我想要做的一个具体例子:
git init
:: add three files
echo aaa > aaa.txt
echo bbb > bbb.txt
echo ccc > ccc.txt
git add --all
git commit -m "initial commit"
:: delete aaa.txt, bbb.txt
del aaa.txt
del bbb.txt
git add --all
git commit -m "delete aaa.txt, bbb.txt"
:: re-add aaa.txt
echo zzz > aaa.txt
git add --all
git commit -m "re-add aaa.txt"
我正在尝试弄清楚我需要列出什么命令bbb.txt
- 我不在乎它aaa.txt
在某个时候被删除,因为它后来被重新添加,所以它当前存在于分支的尖端。
我也不关心文件的内容,只关心“丢失”文件的名称/路径。
具体来说,我希望这个假设命令的输出为:
bbb.txt
如果输出还可以列出“丢失”文件被删除的最新提交,这是一个额外的好处,但不是必需的。
假设是 Unix shell 环境,您可以使用
comm
fromcoreutils
将已删除文件列表与当前版本中的文件列表进行比较:分解一下:
该
comm
命令逐行比较两个排序的文件。传递-23
导致它只打印第一个文件中包含的行,而不打印第二个文件中包含的行。传递到的两个“文件”
comm
是进程替换(<(...)
)。第一个进程替换是问题中已删除文件命令的修改版本。传递输出
sort | uniq
以获得唯一文件路径的排序列表。输出也会被传递grep -v '^$'
以删除讨厌的空行。第二个进程替换用于
git ls-files
获取当前版本中所有文件的名称。这些都是sort
为了保持comm
快乐而排序的。结果是历史记录中某个时刻已删除且也不包含在当前版本中的所有文件的列表。
奖励:获取删除每个已删除文件的最新提交
获得已删除文件的路径后,您可以使用以下命令确定它们被删除的提交
因此,要获取所有已删除的文件以及它们被删除的提交,您可以使用类似的东西
如果您不幸遇到需要处理文件名中的
-z
换行符的情况,我已经验证如果您通过传递到comm
、git log
、sort
、uniq
和 来在各处使用 NUL 分隔行,这种方法仍然有效grep
。我不想将其他答案与特定的语言/平台联系起来,但我专门使用 PowerShell (Core) 7.3(在 Windows和Linux上执行) - 我已经改编了@Brian61354270 的答案,只是在此处发布回馈一些东西...
“在
git log
带有哈希标头的名称状态输出中,如果只有一个字段,则它是提交 id,因此请记住它,否则如果我们在这之前没有看到文件名,那么这是我们所做的最后一件事它,如果是删除,我们想要这一行,我们知道它们都是删除,所以只需将其替换D
为提交 ID 即可。”