我怎么可能签出 Git 中不存在的分支?
How is it possible that I can checkout a non-existant branch in Git?
关于 Git 有很多我不知道的。我希望了解这是如何发生的:
- 2 个月前我有一个活跃的分支:feature/branch-1
- 该分支已合并到我的默认分支:develop
- 它已从远程存储库(位桶)中删除
- 已从本地文件系统中删除:
git branch -d feature/branch-1
git branch
没看到分店
- 今天我惊讶地发现我可以做到:
git checkout feature/branch-1
git branch
我能看到分支
是否git 找出合并点(分支合并时)并检查该提交?
git checkout
和 git switch
(在本例中做同样的事情)都内置了一个特殊功能。他们处理切换到类似于分支名称的字符串的请求的方式是这样的:
检查给定的字符串,例如 foo
或 feature/branch-1
或 5a73c
是否已经存在 as 一个分支名称。如果是这样,那就是要签出的分支机构的名称。
检查是否可以将给定的字符串(例如 5a73c
)转换为提交 的 有效哈希 ID。如果是这样,那就是 commit 作为一个分离的 HEAD 来检查。 (这里 git checkout
会这样做,而 git switch
会死于致命错误,除非你使用 --detach
,在这种情况下它很好,也会这样做。)
假设我们已经走到这一步,如果 --guess
有效(见下文),请使用猜测代码。在 Git 的旧版本中,这称为“DWIM 模式”,其中 DWIM 代表 Do What I Mean。 (DWIM 有很长的历史可以追溯到 1960 年代的 Lisp,甚至在我使用计算机之前:我直到 1970 年代才开始接触硬件,然后才开始接触软件。)
--guess
选项在 commit ccb111b342f472d12baddbfa5b5281
中首次成为正式(并正确记录),在 Git 2.23.0 中首次发布,但由于它默认为 on 并且在此之前一直存在,除非您明确将其关闭,否则它会打开,这需要至少 2.23 的 Git 版本。所以它几乎总是开着。
它的工作方式是扫描您自己的存储库中的每个远程跟踪名称。这些名称是在 git fetch
时间创建和更新的,包括大多数 git fetch
操作 运行 通过 git pull
操作。默认情况下,它们 不会被删除 除非你明确地 运行 git fetch --prune
或 git remote prune
,或者你特别使用 [=31] 的特殊情况=] 从您当前具有相应远程跟踪名称的远程删除分支。
您的远程跟踪名称是类似于 origin/foo
或 origin/feature/branch-1
的名称。你不太可能有一个 origin/5a73c
因为没有人会用它作为分支名称:你的远程跟踪名称是你的 Git 别人分支名称的副本,其他人会发疯的1 将其用作分支名称。但它可能会偶然发生,偶尔出现四个或更多字母的单词 2 完全由有效的十六进制数字组成:分支名称,例如 deed
或 efface
或faded
可以在这里触发怪异。
无论如何,假设我们首先进入第 3 步(--guess
代码),Git 会扫描您的远程跟踪名称。您输入了,例如:
git checkout feature/branch-1
当你没有feature/branch-1
分支时,第一步失败; feature/branch-1
无法转换为有效的哈希 ID,因为它包含非十六进制字符,例如 t
和正斜杠;所以我们到达第 3 步。Git 现在扫描您所有的 origin/*
名字:是其中之一 origin/feature/branch-1
?
在这种情况下:是的,一个是。 Git 也会扫描所有 other 远程跟踪名称,例如 upstream/*
,此时,找到 all考生。所有这些候选人的名单然后进入最后一组测试:
列表是否为空?如果是,则猜测失败。
列表是否恰好是一个元素长?如果是这样,那就是您希望 Git 猜测的远程跟踪名称。
否则(列表中有多个条目),由于比赛之间的竞争,猜测失败,除非您使用Git2.19),checkout.defaultRemote
。此功能让您可以选择“赢得”此类比赛的特定遥控器。
在这种情况下,您只得到一个匹配项:origin/feature/branch-1
。这使 --guess
能够猜测而不是:
git checkout feature/branch-1
你的意思是:
git checkout -b feature/branch-1 --track origin/feature/branch-1
所以这就是 git checkout
所做的。 (虽然 git switch
用 -c
拼写,git switch
在这里表现相同,使用相同的控制旋钮:--guess
在命令行和 checkout.defaultRemote
用于处理模棱两可的多重匹配。)
这里的一个潜在教训是,经常 运行 git fetch -p
或 git remote prune
可能是明智的,甚至将 fetch.prune
设置为 true
个人 Git 配置。否则,您可能会有很多陈旧的远程跟踪名称,并且人就是人,您为 您的 新功能发明的名称可能会与某人为 发明的旧名称发生冲突他们的 新功能。或者,代替那个教训,也许要采取的是禁用猜测(可能使用新的 Git-2.30 config.guess
设置)。注意,如果你想使用远程跟踪名称origin/foo
创建本地分支foo
,你可以输入:
git switch -t origin/foo
(隐含 -c foo
部分)。当然,这也适用于旧的 git checkout
。
1他们的疯狂可能有一种方法,或者只是他们方法的一种疯狂。
2最短的缩写 Git 将允许原始哈希 ID 为四个字符。因此,尽管分支名称 abc
由十六进制数字组成,但它绝不是提交哈希 ID。但是 abcd
有时是 提交哈希 ID。
关于 Git 有很多我不知道的。我希望了解这是如何发生的:
- 2 个月前我有一个活跃的分支:feature/branch-1
- 该分支已合并到我的默认分支:develop
- 它已从远程存储库(位桶)中删除
- 已从本地文件系统中删除:
git branch -d feature/branch-1
git branch
没看到分店- 今天我惊讶地发现我可以做到:
git checkout feature/branch-1
git branch
我能看到分支
是否git 找出合并点(分支合并时)并检查该提交?
git checkout
和 git switch
(在本例中做同样的事情)都内置了一个特殊功能。他们处理切换到类似于分支名称的字符串的请求的方式是这样的:
检查给定的字符串,例如
foo
或feature/branch-1
或5a73c
是否已经存在 as 一个分支名称。如果是这样,那就是要签出的分支机构的名称。检查是否可以将给定的字符串(例如
5a73c
)转换为提交 的 有效哈希 ID。如果是这样,那就是 commit 作为一个分离的 HEAD 来检查。 (这里git checkout
会这样做,而git switch
会死于致命错误,除非你使用--detach
,在这种情况下它很好,也会这样做。)假设我们已经走到这一步,如果
--guess
有效(见下文),请使用猜测代码。在 Git 的旧版本中,这称为“DWIM 模式”,其中 DWIM 代表 Do What I Mean。 (DWIM 有很长的历史可以追溯到 1960 年代的 Lisp,甚至在我使用计算机之前:我直到 1970 年代才开始接触硬件,然后才开始接触软件。)
--guess
选项在 commit ccb111b342f472d12baddbfa5b5281
中首次成为正式(并正确记录),在 Git 2.23.0 中首次发布,但由于它默认为 on 并且在此之前一直存在,除非您明确将其关闭,否则它会打开,这需要至少 2.23 的 Git 版本。所以它几乎总是开着。
它的工作方式是扫描您自己的存储库中的每个远程跟踪名称。这些名称是在 git fetch
时间创建和更新的,包括大多数 git fetch
操作 运行 通过 git pull
操作。默认情况下,它们 不会被删除 除非你明确地 运行 git fetch --prune
或 git remote prune
,或者你特别使用 [=31] 的特殊情况=] 从您当前具有相应远程跟踪名称的远程删除分支。
您的远程跟踪名称是类似于 origin/foo
或 origin/feature/branch-1
的名称。你不太可能有一个 origin/5a73c
因为没有人会用它作为分支名称:你的远程跟踪名称是你的 Git 别人分支名称的副本,其他人会发疯的1 将其用作分支名称。但它可能会偶然发生,偶尔出现四个或更多字母的单词 2 完全由有效的十六进制数字组成:分支名称,例如 deed
或 efface
或faded
可以在这里触发怪异。
无论如何,假设我们首先进入第 3 步(--guess
代码),Git 会扫描您的远程跟踪名称。您输入了,例如:
git checkout feature/branch-1
当你没有feature/branch-1
分支时,第一步失败; feature/branch-1
无法转换为有效的哈希 ID,因为它包含非十六进制字符,例如 t
和正斜杠;所以我们到达第 3 步。Git 现在扫描您所有的 origin/*
名字:是其中之一 origin/feature/branch-1
?
在这种情况下:是的,一个是。 Git 也会扫描所有 other 远程跟踪名称,例如 upstream/*
,此时,找到 all考生。所有这些候选人的名单然后进入最后一组测试:
列表是否为空?如果是,则猜测失败。
列表是否恰好是一个元素长?如果是这样,那就是您希望 Git 猜测的远程跟踪名称。
否则(列表中有多个条目),由于比赛之间的竞争,猜测失败,除非您使用Git2.19),
checkout.defaultRemote
。此功能让您可以选择“赢得”此类比赛的特定遥控器。
在这种情况下,您只得到一个匹配项:origin/feature/branch-1
。这使 --guess
能够猜测而不是:
git checkout feature/branch-1
你的意思是:
git checkout -b feature/branch-1 --track origin/feature/branch-1
所以这就是 git checkout
所做的。 (虽然 git switch
用 -c
拼写,git switch
在这里表现相同,使用相同的控制旋钮:--guess
在命令行和 checkout.defaultRemote
用于处理模棱两可的多重匹配。)
这里的一个潜在教训是,经常 运行 git fetch -p
或 git remote prune
可能是明智的,甚至将 fetch.prune
设置为 true
个人 Git 配置。否则,您可能会有很多陈旧的远程跟踪名称,并且人就是人,您为 您的 新功能发明的名称可能会与某人为 发明的旧名称发生冲突他们的 新功能。或者,代替那个教训,也许要采取的是禁用猜测(可能使用新的 Git-2.30 config.guess
设置)。注意,如果你想使用远程跟踪名称origin/foo
创建本地分支foo
,你可以输入:
git switch -t origin/foo
(隐含 -c foo
部分)。当然,这也适用于旧的 git checkout
。
1他们的疯狂可能有一种方法,或者只是他们方法的一种疯狂。
2最短的缩写 Git 将允许原始哈希 ID 为四个字符。因此,尽管分支名称 abc
由十六进制数字组成,但它绝不是提交哈希 ID。但是 abcd
有时是 提交哈希 ID。