git status
[1]的文档意味着它应该能够检测重命名和副本(具有C
状态)或者无论git diff -C
应该做什么,但都不能似乎工作:
mkdir test
cd test/
git init
echo 'Hello World!' > hello.txt
echo 'Goodbye World!' > goodbye.txt
git add -A
git commit -m "Initial commit"
cp hello.txt copied.txt
mv goodbye.txt moved.txt
git add -A
$ git status --short
A copied.txt <------------ NO COPY DETECTED
R goodbye.txt -> moved.txt
$ git diff -M -C --summary --cached
create mode 100644 copied.txt <------------ NO COPY DETECTED
rename goodbye.txt => moved.txt (100%)
$ git commit -m Test
$ git diff -M -C --summary HEAD~
create mode 100644 copied.txt <------------ NO COPY DETECTED
rename goodbye.txt => moved.txt (100%)
与话题相关的问题:在将更改添加到索引之前,是否可以让git status
或git diff
检测副本并在workdir中重命名?
答案 0 :(得分:4)
由于SO上的任何人显然都不知道关于git status
的主要问题的答案,我最后也在官方Git邮件列表上提出了问题[1]:
关于git status
未检测到文件副本(文档实际上是错误的,它根本不会检测副本):
git-status自2005年中期以来一直使用重命名。提及副本的文档很晚才添加, 以及短版和瓷版。该代码处理diff引擎抛出的任何内容。我不认为当时有人认为你实际上不能激发寻找副本的状态。
关于git diff -C
未检测到文件副本(您还需要传递--find-copies-harder
):
默认情况下,-C仅在同一次提交中修改源文件时才查找副本。由于您没有在将其复制到copied.txt的同一提交中修改hello.txt,因此不会考虑它。
如果你传递-C -C(两次),或者使用--find-copies-harder,Git会考虑存储库中的所有文件。请注意,这可能会更慢,这就是它不是默认值的原因。
答案 1 :(得分:1)
是否可以在将更改添加到索引之前让git status或git diff检测副本并在workdir中重命名?
不,如&#34; Git changing repo directory and files directory&#34;中所述 Git将检测完整(已提交)树上的重命名,而不是添加到索引的部分。
提交后,差异应检测移动/重命名:
git diff -M -C --summary @~
(用@表示HEAD)
关于副本,考虑到在该提交中修改的文件没有被修改,您必须使用&#34; --find-copies-harder
&#34;选项:
C:\Users\vonc\prog\git\test\mv\test>git diff -M -C --summary --cached
create mode 100644 copied.txt
rename goodbye.txt => moved.txt (100%)
VS
C:\Users\vonc\prog\git\test\mv\test>git diff -M -C --find-copies-harder --summary --cached
copy hello.txt => copied.txt (100%)
rename goodbye.txt => moved.txt (100%)
那是:
--find-copies-harder
出于性能原因,默认情况下,
-C
选项仅在副本的原始文件在同一变更集中修改时才会找到副本。
此标志使命令检查未修改的文件作为副本源的候选者 对于大型项目来说,这是一项非常昂贵的操作,因此请谨慎使用 提供多个-C
选项具有相同的效果。
请注意,使用Git 2.17(2018年第二季度),git status
输出现在更精确。
commit e4e5da2见Stefan Beller (stefanbeller
)(2018年2月15日)
(由Junio C Hamano -- gitster
--合并于commit 7676b86,2018年2月28日)
可以输出&#39;
A
&#39;来自&#39;git status --porcelain
&#39; 使用&#39;--intend-to-add
&#39;添加文件标志。
通过在文档表中添加模式来明确这一点。
答案 2 :(得分:0)
这是不正确的。我误解了这个问题。
简单的答案是在
cp hello.txt copied.txt
mv goodbye.txt moved.txt
git add -A
$ git status --short
A copied.txt <------------ NO COPY DETECTED
R goodbye.txt -> moved.txt
Git尚未了解 copied.txt
的内容。请注意,git status
会将其列为untracked
。