如何还原git checkout主体?

Ortomala Lokni

我在测试分支上,但我误会了

git checkout masTER

它将我的主分支重命名为masTER。当我跑步时git branch,我获得:

masTER
test

如果我跑步git checkout test然后git checkout mastermaster分支不会检​​索其原始大小写。

我该如何纠正这个错误,为什么会发生呢?

PS:我使用的是git版本2.7.4(Apple Git-66)

P.S2:我正在使用OS X 10.11.6,该操作系统使用Journaled HFS +,并且默认情况下不区分大小写。如果我运行:

touch abc
touch abC

跑步ls ab*只给

abc
周二

定义问题

在任何保留大小写但不区分大小写的文件系统上都会发生此问题。然后,默认情况下,它在Mac和Windows机顶盒上发生,而不是在Linux等上。

Git本身是区分大小写的,几乎到处都是。名为的文件与名为的文件master.txt无关masTER.txt,因此Git对象会将这两个文件保留为单独的项目,而Git的索引(也称为缓存或暂存区)将考虑这些单独的文件。有一个core.ignoreCase设置git config可以帮助它识别底层操作系统何时存在分歧,但是总的来说,Git认为它们是不同的。

由于这些文件的名称都存储在文件的类型,资源库对象,存储.git/objects/,和Git的索引,存储在.git/index1 -和不只是交给OS存储,它们可以,并因此,区分大小写,即使如果操作系统不是。2个

分支名称以及远程跟踪分支和标记名称也是如此。由于这些名称保留在文件中.git/packed-refs,因此它们可以区分大小写。(Git还将其当前分支的想法存储.git/HEAD为文本字符串,因此区分大小写。)但是这些名称并不总是保留在中.git/packed-refs实际上,它们通常根本不存在.git/packed-refs一个活性分支名酮正被修改-卷起存储在一个单独的文件中.git/refs/heads/,例如.git/refs/heads/master一种有源远程跟踪分支名中卷起.git/refs/remotes/,例如.git/refs/remote/origin/master

如果操作系统不区分大小写,则这意味着分支的名称master打包时masTER有所不同,但一旦变为活动状态,分支便会变得相同

不过,情况变得更糟。无效的名称会被打包:移入.git/packed-refs如果名称现在变得活跃,它出现在这两个 .git/packed-refs (假设它是一个分支名称).git/refs/heads/这意味着一个不活动的名称区分大小写,一个不活动的名称不区分大小写,并且您可以同时发生这两种情况,因此您的amasTER和amaster是不同的(因为这两个名称都出现在.git/packed-refs我们可以告诉他们的位置)分开),同时,相同!这意味着什么—当您身处奇异的薛定ding的猫3中时,Git的行为方式情况-尚不清楚。显然,这是一个坏主意。(我设法把我的测试回购进入这个状态,我有两个master masTERgit pack-refs --all,然后git checkout -b masTER我没有推进一步,虽然)。

修好它

今天提出问题的OS(不区分大小写,保留大小写)(再次参见脚注2)这意味着,一旦你有一个命名的文件masTER,试图使用或创建一个命名的文件masterMasterMASTERmAsTeR,等等,所有替代是指现有的文件masTER4

一些操作系统的让你的文件只是一个个案改变(重命名mv masTER master为实例),所以git branch -m masTER master 可能会做的伎俩,如果GIT中只会发出一个操作系统级“重命名”操作。las,实际上,Git首先进行检查,发现它可以访问名为master(当然是名为的文件masTER的分支

$ git branch -m masTER master
fatal: A branch named 'master' already exists.

因此,解决方法是两次重命名分支首先,我们将其移动到一个名字,该操作系统无法找到,不符合任何现有的情况下,折叠分支名称。您可以选择任何不太可能的名称并希望它不被使用,或者可以运行git branch(或git for-each-ref refs/heads)检查您刚刚选择的不太可能的名称是否确实在使用中。无论如何,如果将当前(错误大小写)分支重命名为not的新未使用名称,即使在愚蠢的大小写折叠规则下,也要匹配一些现有名称,这将作为副作用删除旧的,错误的-case-OS完全坚持匹配的名称:

$ git branch -m masTER tmp

现在已经彻底消除了旧的“ wrong-case-but”名称,现在您可以使用正确的大小写重新命名分支:

$ git branch -m tmp master

请注意,这也要注意从中去除错误大小写的名称.git/packed-refs(如果它在那里)。


1这些路径只是默认路径。新的Extra-worktree功能有时会在其中找到一些文件的地方发生更改,并且Git的环境变量可以覆盖其中的一些文件。

2从技术上讲,现代OS在每个文件系统的基础上而不是在全球范围内进行区分大小写。因此,如果显示“如果操作系统为case-X”,则可以在思维上替换为“如果我正在使用的文件系统为case-X”。

他们可能会弄错。考虑一下德语,其中“straße”(街道)一词以小写形式写成,但大写时变成了“ STRASSE”。如果我们一次将一个字符与不区分大小写的字符比较进行比较,则在碰到eszetß时会遇到问题,因为它会转换为一个而不是两个大写S-es。

这个Python3会话表明MacOS确实不相信ß= SS:

>>> s
'straße'
>>> with open(s, 'w') as stream:
...     stream.write('street\n')
... 
7
>>> os.listdir()[10]
'file_абвгде'          # oops, that's one I was using for testing proftpd
>>> os.listdir()[30]   # should clean out my tmp dir more often ...
'straße'
>>> open('STRASSE')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'STRASSE'
>>> open('STRAßE').read()
'street\n'

这样的事情有时使我确信计算机永远不应该与人互动,反之亦然。:-)

3亲爱的,你对那只猫做了什么?看起来半死了!-薛定ding的妻子

4个不区分大小写的较旧的OS(当时实际上是整个OS)将所有名称仅折叠为一个大小写,且始终为大写。因此要求创建masTER实际创建的MASTER代替。这至少和保留案例的折叠一样错误。但是,它不那么令人困惑:您至少可以说出操作系统将如何处理您的数据。当然,案例的选择是相当大声的。诚然,在仅使用大写字母的老式电传打字机时代,他们有借口。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章