GitHub 分支机构:区分大小写问题?
GitHub Branches: Case-Sensitivity Issue?
我似乎遇到了存储库不断在本地重新创建分支的问题,因为远程有一些分支。我在 Windows 机器上,所以我怀疑这是区分大小写的问题。
这是一对命令的示例:
$ git pull
From https://github.com/{my-repo}
* [new branch] Abc -> origin/Abc
* [new branch] Def -> origin/Def
Already up to date.
$ git pull -p
From https://github.com/{my-repo}
- [deleted] (none) -> origin/abc
- [deleted] (none) -> origin/def
* [new branch] Abc -> origin/Abc
* [new branch] Def -> origin/Def
Already up to date.
当做 git pull
时,有问题的分支是大写的。当我执行 git pull -p
(用于修剪)时,它首先尝试删除分支的小写版本,然后创建大写版本。
远程分支是大写的(origin/Abc
和origin/Def
)。
我试图暂时更改我的 Git 配置,使 ignorecase=false
(当前为 ignorecase=true
)。但我注意到行为没有变化。我猜我这边有一些本地的东西目前正在抓住那些小写的分支。但是 git branch
不会在本地显示这些分支的任何版本。
如果没有完全删除存储库(单独文件夹中的新 git clone
在尝试 pulls/fetches 时不会提取这些幻影分支),我能做些什么吗?
在 Git 上,分支只是指向提交的指针。分支作为普通文件存储在您的 .git
存储库中。
例如,您可能在 .git/refs/heads
上有 abc
和 def
个文件。
$ tree .git/refs/heads/
.git/refs/heads/
├── abc
├── def
└── master
这些文件的内容就是分支指向的提交号。
我不确定,但我认为选项 ignorecase
只与您的工作目录相关,与 .git
文件夹无关。因此,要删除 奇怪的 大写分支,您可能只需要 remove/rename .git/refs/heads
中的文件。
除此之外,从本地分支到远程分支的上游link存储在.git/config
文件中。在这个文件中你可能有这样的东西:
[branch "Abc"]
remote = origin
merge = refs/heads/abc
请注意,在此示例中,远程分支名为 Abc
,但本地分支名为 abc
(小写)。
为了解决您的问题,我会尝试:
- 修改
.git/config
文件
- 重命名
.git/refs/heads
中损坏的分支 例如 abc
重命名 abc-old
- 试试你的
git pull
Git 对此感到精神分裂。1 部分 Git 是 case-sensitive,所以分支 HELLO
和分支 hello
是 不同的 分支。 Git 的其他部分,无论如何在 Windows 和 MacOS 上,case-in 敏感,所以分支 HELLO
和分支 hello
相同分支。
结果是混乱。最好完全避免这种情况。
更正问题:
设置一些 附加的,私有的和临时的,分支或标签名称,你不会觉得混淆,记住你的任何提交哈希 ID真正关心的,在你自己的本地存储库中。然后 运行 git pack-refs --all
这样你所有的引用都被打包了。这将删除所有 文件名 ,将所有引用放入 .git/packed-refs
flat-file,它们的名称是 case-sensitive。你的 Git 现在可以区分你的 Abc
和你的 abc
,如果你两者都有的话。
既然您的存储库是 de-confused,删除 任何错误的分支名称。您的临时名称包含您想记住的值。如果一个或两个可能被弄乱,您可以同时删除 abc
和 Abc
。你的remember-abc
里面有正确的散列。
转到 Linux 服务器计算机,该计算机的分支仅在大小写上与您的分支不同。 (它始终是 Linux 机器;此问题永远不会发生在 Windows 或 MacOS 服务器上,因为它们足够早地执行 case-folding,您永远不会 创建 首先是问题。)在那里,重命名或删除有问题的坏名称。
Linux 机器没有大小写问题——名称不同只是大小写不同的分支总是不同的——所以这里没有奇怪之处。可能需要几个步骤和一些 git branch
命令来列出所有名称,但最终,您将只得到清晰和不同的名称:不会有名为 Abc
和 [= 的分支18=]两者。
如果Linux服务器上没有这样的问题,第2步就是"do nothing".
在您的本地系统上使用 git fetch --prune
。您现在不再有任何错误的名称作为 remote-tracking 名称,因为在第 2 步中,您确保服务器(您的本地 Git 调用 origin
的系统)没有错误的名称,并且您的本地 Git 已使您的本地 origin/*
名称与其分支名称匹配。
现在 re-create 您在本地想要的任何分支名称,and/or 重命名您在步骤 1 中创建的临时名称。例如,如果您让 remember-abc
记住abc
,你可以 运行 git branch -m remember-abc abc
到 移动 remember-abc
到 abc
.
如果 abc
应该将 origin/abc
设置为其上游,请立即执行此操作:
git branch --set-upstream-to=origin/abc abc
(您可以在创建 remember-abc
时在步骤 1 中执行此操作,但我认为这里更有意义,因此我将其放在步骤 4 中。)
除了上述 4 个步骤之外,您还可以使用各种快捷方式。为了清楚起见,我以这种方式列出了所有四个步骤:每个步骤要完成的对你来说应该是显而易见的,如果你阅读了本文的其余部分,为什么 你正在做这一步。
出现问题的原因在nowox's answer中有概述:Git有时将分支名称存储在文件名中,有时将其作为字符串存储在数据文件中。由于 Windows(和 MacOS)倾向于使用 file-name-conflation,file-name 变体保留其原始大小写,但忽略了创建另一个 case-variant 名称的第二个文件的尝试,并且那么 Git 认为 Abc
和 abc
在其他方面 相同 。 data-in-a-file 变体保留了 case-distinction 以及 value-distinction 并认为 Abc
和 abc
是两个不同的分支,它们标识两个不同的提交。
当 git rev-parse refs/heads/abc
或 git rev-parse refs/remotes/origin/abc
从 .git/packed-refs
(包含字符串的数据文件)获取信息时,它会获取 "right" 信息。但是当它从文件系统获取信息时,尝试打开 .git/refs/heads/abc
或 .git/refs/remotes/origin/abc
实际上会打开 .git/refs/heads/Abc
(如果该文件现在存在)或 similarly-named remote-tracking 变体(如果该文件存在),并且 Git 获取 "wrong" 信息。
设置 core.ignorecase
(任何设置)根本没有帮助,因为这会影响 仅 Git 处理 case-folding 的方式work-tree。 Git 内部数据库中的文件不会受到任何影响。
如果 Git 使用真实的数据库来存储其 table,那么整个问题就不会出现了。在 Linux 上使用单个文件效果很好。它在 Windows 和 MacOS 上不能正常工作,反正不是这样。使用单个文件 可以 在那里工作 if Git 没有将它们存储在具有可读名称的文件中——例如,而不是 refs/heads/master
,也许 Git 可以使用名为 refs/heads/6d6173746572
的文件,尽管这会将可用的 component-name 长度减半。 (练习:0x6d m
、0x61 a
等等如何?)
1从技术上讲,这是一个错误的词。虽然它肯定是描述性的更好的词可能是 schizoid,如 one episode of The Prisoner, but it too has the wrong meaning. The root word here is really schism 的标题中所用,意思是分裂和有点 self-opposed,这就是我们在这里的目的。
and torek 提供的答案非常有帮助,但没有包含确切的解决方案。 .git/config
中对远程的现有引用和 git/refs/heads
中的文件不包含 abc
或 def
.
的任何版本
相反,问题存在于 .git/refs/remotes/origin
。
我的 .git/refs/remotes/origin
目录引用了这些功能分支文件夹的小写版本。一些功能分支是在 abc
和 def
下使用小写版本创建的,但它们不再存在于远程。这些功能分支的创建者最近切换到远程使用 Abc
和 Def
。我删除了 .git/refs/remotes/origin/abc
和 .git/refs/remotes/origin/def
然后执行了新的 git pull -p
命令。新文件夹 Abc
和 Def
已创建,后续 pull
或 fetch
正确显示 Already up to date.
感谢 nowox 和 torek 让我走上正轨!
我做了以下事情来解决我的问题:
- 我导航到
.git/refs/remotes/origin
文件夹。
- 我删除了带有 buggy 分支名称的文件夹。
- 我在终端做了
git pull
。
我似乎遇到了存储库不断在本地重新创建分支的问题,因为远程有一些分支。我在 Windows 机器上,所以我怀疑这是区分大小写的问题。
这是一对命令的示例:
$ git pull
From https://github.com/{my-repo}
* [new branch] Abc -> origin/Abc
* [new branch] Def -> origin/Def
Already up to date.
$ git pull -p
From https://github.com/{my-repo}
- [deleted] (none) -> origin/abc
- [deleted] (none) -> origin/def
* [new branch] Abc -> origin/Abc
* [new branch] Def -> origin/Def
Already up to date.
当做 git pull
时,有问题的分支是大写的。当我执行 git pull -p
(用于修剪)时,它首先尝试删除分支的小写版本,然后创建大写版本。
远程分支是大写的(origin/Abc
和origin/Def
)。
我试图暂时更改我的 Git 配置,使 ignorecase=false
(当前为 ignorecase=true
)。但我注意到行为没有变化。我猜我这边有一些本地的东西目前正在抓住那些小写的分支。但是 git branch
不会在本地显示这些分支的任何版本。
如果没有完全删除存储库(单独文件夹中的新 git clone
在尝试 pulls/fetches 时不会提取这些幻影分支),我能做些什么吗?
在 Git 上,分支只是指向提交的指针。分支作为普通文件存储在您的 .git
存储库中。
例如,您可能在 .git/refs/heads
上有 abc
和 def
个文件。
$ tree .git/refs/heads/
.git/refs/heads/
├── abc
├── def
└── master
这些文件的内容就是分支指向的提交号。
我不确定,但我认为选项 ignorecase
只与您的工作目录相关,与 .git
文件夹无关。因此,要删除 奇怪的 大写分支,您可能只需要 remove/rename .git/refs/heads
中的文件。
除此之外,从本地分支到远程分支的上游link存储在.git/config
文件中。在这个文件中你可能有这样的东西:
[branch "Abc"]
remote = origin
merge = refs/heads/abc
请注意,在此示例中,远程分支名为 Abc
,但本地分支名为 abc
(小写)。
为了解决您的问题,我会尝试:
- 修改
.git/config
文件 - 重命名
.git/refs/heads
中损坏的分支 例如abc
重命名abc-old
- 试试你的
git pull
Git 对此感到精神分裂。1 部分 Git 是 case-sensitive,所以分支 HELLO
和分支 hello
是 不同的 分支。 Git 的其他部分,无论如何在 Windows 和 MacOS 上,case-in 敏感,所以分支 HELLO
和分支 hello
相同分支。
结果是混乱。最好完全避免这种情况。
更正问题:
设置一些 附加的,私有的和临时的,分支或标签名称,你不会觉得混淆,记住你的任何提交哈希 ID真正关心的,在你自己的本地存储库中。然后 运行
git pack-refs --all
这样你所有的引用都被打包了。这将删除所有 文件名 ,将所有引用放入.git/packed-refs
flat-file,它们的名称是 case-sensitive。你的 Git 现在可以区分你的Abc
和你的abc
,如果你两者都有的话。既然您的存储库是 de-confused,删除 任何错误的分支名称。您的临时名称包含您想记住的值。如果一个或两个可能被弄乱,您可以同时删除
abc
和Abc
。你的remember-abc
里面有正确的散列。转到 Linux 服务器计算机,该计算机的分支仅在大小写上与您的分支不同。 (它始终是 Linux 机器;此问题永远不会发生在 Windows 或 MacOS 服务器上,因为它们足够早地执行 case-folding,您永远不会 创建 首先是问题。)在那里,重命名或删除有问题的坏名称。
Linux 机器没有大小写问题——名称不同只是大小写不同的分支总是不同的——所以这里没有奇怪之处。可能需要几个步骤和一些
git branch
命令来列出所有名称,但最终,您将只得到清晰和不同的名称:不会有名为Abc
和 [= 的分支18=]两者。如果Linux服务器上没有这样的问题,第2步就是"do nothing".
在您的本地系统上使用
git fetch --prune
。您现在不再有任何错误的名称作为 remote-tracking 名称,因为在第 2 步中,您确保服务器(您的本地 Git 调用origin
的系统)没有错误的名称,并且您的本地 Git 已使您的本地origin/*
名称与其分支名称匹配。现在 re-create 您在本地想要的任何分支名称,and/or 重命名您在步骤 1 中创建的临时名称。例如,如果您让
remember-abc
记住abc
,你可以 运行git branch -m remember-abc abc
到 移动remember-abc
到abc
.如果
abc
应该将origin/abc
设置为其上游,请立即执行此操作:git branch --set-upstream-to=origin/abc abc
(您可以在创建
remember-abc
时在步骤 1 中执行此操作,但我认为这里更有意义,因此我将其放在步骤 4 中。)
除了上述 4 个步骤之外,您还可以使用各种快捷方式。为了清楚起见,我以这种方式列出了所有四个步骤:每个步骤要完成的对你来说应该是显而易见的,如果你阅读了本文的其余部分,为什么 你正在做这一步。
出现问题的原因在nowox's answer中有概述:Git有时将分支名称存储在文件名中,有时将其作为字符串存储在数据文件中。由于 Windows(和 MacOS)倾向于使用 file-name-conflation,file-name 变体保留其原始大小写,但忽略了创建另一个 case-variant 名称的第二个文件的尝试,并且那么 Git 认为 Abc
和 abc
在其他方面 相同 。 data-in-a-file 变体保留了 case-distinction 以及 value-distinction 并认为 Abc
和 abc
是两个不同的分支,它们标识两个不同的提交。
当 git rev-parse refs/heads/abc
或 git rev-parse refs/remotes/origin/abc
从 .git/packed-refs
(包含字符串的数据文件)获取信息时,它会获取 "right" 信息。但是当它从文件系统获取信息时,尝试打开 .git/refs/heads/abc
或 .git/refs/remotes/origin/abc
实际上会打开 .git/refs/heads/Abc
(如果该文件现在存在)或 similarly-named remote-tracking 变体(如果该文件存在),并且 Git 获取 "wrong" 信息。
设置 core.ignorecase
(任何设置)根本没有帮助,因为这会影响 仅 Git 处理 case-folding 的方式work-tree。 Git 内部数据库中的文件不会受到任何影响。
如果 Git 使用真实的数据库来存储其 refs/heads/master
,也许 Git 可以使用名为 refs/heads/6d6173746572
的文件,尽管这会将可用的 component-name 长度减半。 (练习:0x6d m
、0x61 a
等等如何?)
1从技术上讲,这是一个错误的词。虽然它肯定是描述性的更好的词可能是 schizoid,如 one episode of The Prisoner, but it too has the wrong meaning. The root word here is really schism 的标题中所用,意思是分裂和有点 self-opposed,这就是我们在这里的目的。
.git/config
中对远程的现有引用和 git/refs/heads
中的文件不包含 abc
或 def
.
相反,问题存在于 .git/refs/remotes/origin
。
我的 .git/refs/remotes/origin
目录引用了这些功能分支文件夹的小写版本。一些功能分支是在 abc
和 def
下使用小写版本创建的,但它们不再存在于远程。这些功能分支的创建者最近切换到远程使用 Abc
和 Def
。我删除了 .git/refs/remotes/origin/abc
和 .git/refs/remotes/origin/def
然后执行了新的 git pull -p
命令。新文件夹 Abc
和 Def
已创建,后续 pull
或 fetch
正确显示 Already up to date.
感谢 nowox 和 torek 让我走上正轨!
我做了以下事情来解决我的问题:
- 我导航到
.git/refs/remotes/origin
文件夹。 - 我删除了带有 buggy 分支名称的文件夹。
- 我在终端做了
git pull
。