"git diff" 中同一行的两个版本
Two versions of same line in "git diff"
我在切换 b运行ches 后遇到了 st运行ge 行为。我执行了 git checkout master
,我立即将一个文件标记为已修改。我运行git reset --hard
把它改掉了,但是没有效果。 git diff
给了我这样的输出:
diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Warn(message);
+ Logger.Info(message);
但是当我手动改回它时,我得到:
diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Info(message);
+ Logger.Warn(message);
所以 git 无法确定是哪一个。为了让它更有趣,如果我把它改成完全不同的东西,我会得到:
diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Warn(message);
+ Logger.Error(message);
diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Info(message);
+ Logger.Error(message);
当我 运行 git ls-tree -r master | Select-String "myclass.cs"
我得到这个:
100644 blob 4f8405e28faa09981a3f76775b1693db31b0bdad Project/MYClass.cs
100644 blob cb8ca4c60f10f959422ecc2cbdb91d0e693ea380 Project/MyClass.cs
我看到并明白有些地方不对劲,但我不知道它是怎么发生的。
我知道如何以残酷的方式修复它,删除我的本地并从远程获取所有内容,但我想知道是什么原因造成的,以及如何正确修复它。
Git 认为您在 Project
目录/文件夹中有两个不同的文件:
MYClass.cs
(大写M
、大写Y
、大写C
、小写lass.cs
)
MyClass.cs
(大写M
,小写y
,大写C
,小写lass.cs
)
Git 分别打开每个文件名,写出该文件的内容,然后关闭它。
由于您在 Windows 上,它拒绝制作两个不同的文件,其名称仅在 case 中不同,您的 OS 用另一个文件覆盖 两个文件之一,只留下两个外壳中的一个。您的 OS 不会让 Git 在工作树中有两个文件。 Git 可以(并且确实)在索引中有两个文件,因为Git的索引实际上是一个数据文件,而不是目录/文件夹。由于 Git 从索引中提交,Git 可以进行新的提交,继续包含两个不同的文件,其名称仅在大小写上有所不同。
你必须更新你的索引,让它只包含一个这样的名字,否则你注定要在Windows(和MacOS)上永远与这个问题作斗争。简单的方法是在 Linux 或 Unix 系统上进行修复,其中索引和工作树保持同步,因为 OS 可以并且确实创建两个不同的文件,其名称仅在大小写上有所不同。
困难的方法是使用git rm --cached
:给它一个你真正想要的名字。 Git 将从索引中删除该文件,而不会影响工作树。现在索引具有正确的大小写,您可以修复工作树中的大小写以匹配,但是在 Windows 上这样做——在其他系统上,通常的技巧是:
mv NameWithCASEISSUE x # change the whole name a lot, using a safe name
mv x NameWithCaseIssue # change it back, using the correct case this time
现在您可以将索引版本与工作树版本进行比较,并进行可能需要的任何调整。由于只有一个索引版本可以匹配工作树文件,无论大小写问题如何(现在没有任何问题,因为您已经仔细地使文件名大小写匹配),您可以完成工作。
真正不幸的情况(如果我可以使用那个词的话:-))发生在你真的确实想要两个文件名的时候,只是大小写不同,在索引和未来的承诺。没有很好的工具来处理这个问题。理论上可以围绕 git update-index
和 git checkout-index
命令构建此类工具,但目前还不存在。
托瑞克!你为什么偷我的答案? :-P
正如 Torek 所解释的(比我要详细得多),问题是你有两个不同的文件用于 git.... 但是当 git 使用 Windows FS API,他们都在 FS 上击中同一个文件..... 这解释了整个问题。你是怎么解决的?如果您不介意继续解决问题,请保留您想要的真实文件和您想要的内容,并使用 git rm
删除另一个并提交。如果您想及时修复它,请查看第二个文件出现的位置,通过删除它来修改该修订版并在其上重写历史记录。
我在切换 b运行ches 后遇到了 st运行ge 行为。我执行了 git checkout master
,我立即将一个文件标记为已修改。我运行git reset --hard
把它改掉了,但是没有效果。 git diff
给了我这样的输出:
diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Warn(message);
+ Logger.Info(message);
但是当我手动改回它时,我得到:
diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Info(message);
+ Logger.Warn(message);
所以 git 无法确定是哪一个。为了让它更有趣,如果我把它改成完全不同的东西,我会得到:
diff --git a/Project/MYClass.cs b/Project/MYClass.cs
index 4f8405e..cb8ca4c 100644
--- a/Project/MYClass.cs
+++ b/Project/MYClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Warn(message);
+ Logger.Error(message);
diff --git a/Project/MyClass.cs b/Project/MyClass.cs
index cb8ca4c..4f8405e 100644
--- a/Project/MyClass.cs
+++ b/Project/MyClass.cs
@@ -170,7 +170,7 @@ namespace Project
- Logger.Info(message);
+ Logger.Error(message);
当我 运行 git ls-tree -r master | Select-String "myclass.cs"
我得到这个:
100644 blob 4f8405e28faa09981a3f76775b1693db31b0bdad Project/MYClass.cs
100644 blob cb8ca4c60f10f959422ecc2cbdb91d0e693ea380 Project/MyClass.cs
我看到并明白有些地方不对劲,但我不知道它是怎么发生的。
我知道如何以残酷的方式修复它,删除我的本地并从远程获取所有内容,但我想知道是什么原因造成的,以及如何正确修复它。
Git 认为您在 Project
目录/文件夹中有两个不同的文件:
MYClass.cs
(大写M
、大写Y
、大写C
、小写lass.cs
)MyClass.cs
(大写M
,小写y
,大写C
,小写lass.cs
)
Git 分别打开每个文件名,写出该文件的内容,然后关闭它。
由于您在 Windows 上,它拒绝制作两个不同的文件,其名称仅在 case 中不同,您的 OS 用另一个文件覆盖 两个文件之一,只留下两个外壳中的一个。您的 OS 不会让 Git 在工作树中有两个文件。 Git 可以(并且确实)在索引中有两个文件,因为Git的索引实际上是一个数据文件,而不是目录/文件夹。由于 Git 从索引中提交,Git 可以进行新的提交,继续包含两个不同的文件,其名称仅在大小写上有所不同。
你必须更新你的索引,让它只包含一个这样的名字,否则你注定要在Windows(和MacOS)上永远与这个问题作斗争。简单的方法是在 Linux 或 Unix 系统上进行修复,其中索引和工作树保持同步,因为 OS 可以并且确实创建两个不同的文件,其名称仅在大小写上有所不同。
困难的方法是使用git rm --cached
:给它一个你真正想要的名字。 Git 将从索引中删除该文件,而不会影响工作树。现在索引具有正确的大小写,您可以修复工作树中的大小写以匹配,但是在 Windows 上这样做——在其他系统上,通常的技巧是:
mv NameWithCASEISSUE x # change the whole name a lot, using a safe name
mv x NameWithCaseIssue # change it back, using the correct case this time
现在您可以将索引版本与工作树版本进行比较,并进行可能需要的任何调整。由于只有一个索引版本可以匹配工作树文件,无论大小写问题如何(现在没有任何问题,因为您已经仔细地使文件名大小写匹配),您可以完成工作。
真正不幸的情况(如果我可以使用那个词的话:-))发生在你真的确实想要两个文件名的时候,只是大小写不同,在索引和未来的承诺。没有很好的工具来处理这个问题。理论上可以围绕 git update-index
和 git checkout-index
命令构建此类工具,但目前还不存在。
托瑞克!你为什么偷我的答案? :-P
正如 Torek 所解释的(比我要详细得多),问题是你有两个不同的文件用于 git.... 但是当 git 使用 Windows FS API,他们都在 FS 上击中同一个文件..... 这解释了整个问题。你是怎么解决的?如果您不介意继续解决问题,请保留您想要的真实文件和您想要的内容,并使用 git rm
删除另一个并提交。如果您想及时修复它,请查看第二个文件出现的位置,通过删除它来修改该修订版并在其上重写历史记录。