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中重命名?
既然SO上没有人显然知道关于git status
的主要问题的答案,我最后也在官方Git邮件列表上提问:[1]:
关于git status
没有检测到文件副本(文档实际上是错误的,它根本不检测副本):
自2005年中期以来,git-status一直使用重命名。提及副本的文档很晚以及短格式和瓷格式都添加了。该代码处理diff引擎抛出的任何内容。我认为当时没有人考虑到你实际上不能激发寻找副本的状态这一事实。
关于git diff -C
没有检测到文件副本(你还需要传递--find-copies-harder
):
默认情况下,-C仅在同一提交中修改源文件时才查找副本。由于您没有在将其复制到copied.txt的同一提交中修改hello.txt,因此不会考虑它。
如果你传递-C -C(两次),或者使用--find-copies-harder,Git会考虑存储库中的所有文件。请注意,这可能会更慢,这就是它不是默认值的原因。
在将更改添加到索引之前,是否可以在工作目录中使用git status或git diff检测副本并重命名?
不,如“Git changing repo directory and files directory”中所述。 Git将检测完整(已提交)树上的重命名,而不是添加到索引的部分。
提交后,diff应检测移动/重命名:
git diff -M -C --summary @~
(用@表示HEAD)
关于副本,考虑到复制的文件未在该提交中修改,您必须使用“--find-copies-harder
”选项:
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%)
与
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日)
通过使用'
A
'标志添加文件,可以从'git status --porcelain
'获得输出'--intend-to-add
'。 通过在文档表中添加模式来明确这一点。
这是不正确的。我误解了这个问题。
简单的答案就是之后
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
。