Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git:在Windows中协调两个名称重复(大小写不同)的文件夹,同时保留历史记录_Windows_Git_Version Control_Path_Revision History - Fatal编程技术网

Git:在Windows中协调两个名称重复(大小写不同)的文件夹,同时保留历史记录

Git:在Windows中协调两个名称重复(大小写不同)的文件夹,同时保留历史记录,windows,git,version-control,path,revision-history,Windows,Git,Version Control,Path,Revision History,我最近发现,我的解决方案中有两个文件夹在Git中有两个不同的路径(GitHub显示两个单独的文件夹),一个是FooBar,另一个是FooBar。这是因为有些文件是以前一个文件夹名作为路径注册的,有些文件是以后一个文件夹名注册的 这是通过将Git配置为不忽略大小写在本地(在Windows中)发现的:Git config core.ignorecase false 我尝试通过删除整个文件夹,提交,然后重新添加文件夹并再次提交来修复此问题。这解决了问题,但是更改路径的文件丢失了Git历史记录。针对这些

我最近发现,我的解决方案中有两个文件夹在Git中有两个不同的路径(GitHub显示两个单独的文件夹),一个是
FooBar
,另一个是
FooBar
。这是因为有些文件是以前一个文件夹名作为路径注册的,有些文件是以后一个文件夹名注册的

这是通过将Git配置为不忽略大小写在本地(在Windows中)发现的:
Git config core.ignorecase false

我尝试通过删除整个文件夹,提交,然后重新添加文件夹并再次提交来修复此问题。这解决了问题,但是更改路径的文件丢失了Git历史记录。针对这些文件的新路径运行
gitk
,只显示一个提交。在他们的老路上运行
gitk
揭示了他们的整个历史

下一步:使用
git mv
移动文件:

git mv Foobar/file.txt Foobar/file.txt

这将产生以下错误:

致命:目标存在,source=Foobar/file.txt,destination=Foobar/file.txt

如果我先尝试删除文件,当然Git会抱怨源文件不存在

然后我发现,如果在
mv
命令中添加
-f
,Git不会抱怨目标已经存在。但是,在提交重命名后,
gitk
显示历史记录无论如何都被切断了

我甚至试着去做,但这只是做
-f
的另一种方式。同样的结果


基本上,我只想在不区分大小写的操作系统中以某种方式将文件从
Foobar/file.txt
移动到
Foobar/file.txt
,同时保留Git历史记录。这可能吗?

真正的问题没有简单的解决方案

在Git中,文件没有历史记录。提交有历史记录,或者更准确地说,提交就是历史记录。这就是所有的历史。为了让Git“跟踪”一个文件,就像在Git log--follow中一样,Git查看提交,一次一个,将每个提交与其父提交进行比较

如果父级和子级之间的差异显示父级包含一个名为
parent/path/to/pfile
的文件,子级包含一个名为
child/path/to/cfile
的文件,并且这两个提交中这两个文件的内容“非常相似”(这里必须有几个条件),那么,在Git的“眼睛”中,父到子转换表示该文件的重命名。因此,此时,
git log--follow
,它一直在寻找
子/path/to/cfile
,开始寻找
父/path/to/pfile

如果没有
--follow
git log
不会执行此特殊的“查找重命名”操作。。。一般来说,Git认为任何具有任何字节级别差异的路径名都代表不同的文件。换句话说,不会发生大小写折叠和UTF-8规范化。考虑,例如“代码> S/<代码>代码> C> <代码> H< /代码>代码> O< <代码> >代码> N>代码>或代码> S/<代码>代码> C <代码>代码> H < /代码>代码> O\代码>合并-<代码>我们可以在Linux机器上使用这两个不同的UTF-8样式名称创建两个不同的文件。运行
ls
将显示两个名称相同的文件:

$ cat umlaut.py
import os
p1 = u'sch\N{latin small letter o with diaeresis}n'
p2 = u'scho\N{combining diaeresis}n'
os.close(os.open(p1.encode('utf8'), os.O_CREAT, 0o666))
os.close(os.open(p2.encode('utf8'), os.O_CREAT, 0o666))
$ python umlaut.py
$ ls
schön  schön  umlaut.py
Git非常乐意分别存储这两个文件。但是,MacOS拒绝允许这两个文件共存,就像Windows一样。因此,MacOS默认情况下也拒绝允许
Foobar
Foobar
共存

让Git在新的字节序列下以新的提交方式存储文件,并保留历史记录,而不是您想要保留的历史记录。但是存储库中已经存在的历史已经不是您想要保存的历史


实际上,你应该在Git眼中重命名文件,这对你操作系统眼中的文件名没有影响
FooBar
FooBar
在这里是同一个名称,可以继续工作。您的替代方法是重写所有历史记录,通过复制(稍加修改)每个“坏”提交到一个新的和改进的“好”提交,可以追溯到错误对第一次添加到存储库的时间点。但这意味着让所有使用回购协议的人从“旧的不良回购协议”转换为“新的和改进的良好回购协议”。

啊,我明白了。所以发生这种情况并不是因为我的环境,而是因为Git通常不跟踪或关心文件本身(只是快照/内容)。我明白了。