Git重命名检测差异问询:文件名冲突时无法识别交换的原因及解决方法
背景
提交F中的文件结构
文件A内容:
a
文件B内容:
b
目录结构:
. ├── a └── b
交换两个文件的名称(提交F → G)
在提交G中执行文件名交换操作:
# 在提交F上执行 git mv a c git mv b a git mv c a git commit -m "G"
此时git diff无法检测到重命名:
git diff HEAD^
输出结果:
diff --git a/a b/a index 7898192..6178079 100644 --- a/a +++ b/a @@ -1 +1 @@ -a +b diff --git a/b b/b index 6178079..7898192 100644 --- a/b +++ b/b @@ -1 +1 @@ -b +a
由于文件内容未发生变化,我预期Git能够检测到此次重命名,但在git-diff的手册页中未找到仅针对文件名交换场景的相关解释
不复用现有名称重命名文件(提交F → H)
# 在提交F上执行 git mv a c git mv b d git commit -m "H"
此时git diff可以检测到重命名:
git diff HEAD^
输出结果:
diff --git a/a b/c similarity index 100% rename from a rename to c diff --git a/b b/d similarity index 100% rename from b rename to d
问题
为何Git在新名称不与现有文件名冲突时能检测重命名,而名称冲突时却无法检测?
补充问题:当文件经常交换名称时,如何忽略文件名,仅检测两个目录间的内容变化(即使用git diff --no-index dir1 dir2)?起初我认为Git完全适用于此场景,但实际并非如此……
编辑说明:
我注意到评论中普遍提到Git在提交中不跟踪文件重命名或其他文件系统元数据,我对此已有了解,但这并未解答我的核心问题——为何在生成diff时,Git在名称复用与名称唯一的场景下表现不同:
考虑仓库外的场景(无提交):
目录结构:
1 ├── a └── b 2 ├── a └── b
文件1/a内容:
a
文件1/b内容:
b
文件2/a内容:
b
文件2/b内容:
a
由于内容未发生变化,diff结果应为空白(或显示重命名):
git diff --no-index 1 2
但实际输出为:
diff --git a/1/a b/2/a index 7898192..6178079 100644 --- a/1/a +++ b/2/a @@ -1 +1 @@ -a +b diff --git a/1/b b/2/b index 6178079..7898192 100644 --- a/1/b +++ b/2/b @@ -1 +1 @@ -b +a
然而,若目录结构如下:
1 ├── a └── b 2 ├── c └── d
文件2/c内容:
a
文件2/d内容:
b
此时diff仅显示重命名:
git diff --no-index 1 2
输出结果:
diff --git a/1/b b/2/c similarity index 100% rename from 1/b rename to 2/c diff --git a/1/a b/2/d similarity index 100% rename from 1/a rename to 2/d
内容的提问来源于stack exchange,提问作者d.j.yotta
相关产品推荐
相关产品推荐

