创建不是无头但没有主分支的远程
Create remote that is not HEAD-less but does not have a master branch
我是 git 的新手,正在遵循 Missing Semester 的以下出色指导。大约 1 小时后,他们讨论了遥控器。我经历了创建远程(作为测试的子目录)的过程,但是,我故意偏离说明,因为这有助于我的理解。我将一个分支推送到远程但没有命名它 "master"。我最终意识到这个遥控器中没有 HEAD,而且一切都无法正常工作。我查看了 git remote set-head 命令,认为这可以解决问题。我认为没有。最终起作用的是在远程创建一个名为 "master" 的分支,并且 HEAD 自动指向它。我没有在文档中看到这个要求。有没有办法让存储库没有名为 "master" 的分支?或者,如果没有名为 "master" 的分支,如何在远程创建后让 HEAD 指向一个分支?
TL;DR:您需要进入服务器(不知何故——如何 取决于服务器)并拥有 服务器的 Git 设置其 HEAD
。 (请注意,GitHub 有一个可点击的网页按钮界面,在 settings
下,然后是 branches
。)
不过,通常情况下,您只需让服务器创建其第一个名称为 master
的分支,之后一切都会按照大家期望的方式进行。请注意,如果服务器 Git 已经有一个名为 br1
的分支,您可以使用以下命令克隆该服务器 Git 存储库:
git clone -b br1 <em>url</em>
在您的客户端,然后是:
git push origin br1:master
要求该服务器创建名称 master
,指向与您在克隆中自己的 br1
相同的提交。现在服务器 有 master
并且一切恢复正常。
Long:这里到底发生了什么?
每个 Git 存储库都有一个 HEAD
所有 Git 存储库都有一个 HEAD。这是 Git 的基本要求:当 Git 去寻找存储库时,它会对其检查的每个目录进行多次完整性检查。目录必须:
- 作为目录存在;
- 包含一个名为
HEAD
的文件或符号链接似乎有效;
- 有一个
refs/
子目录;和
- 有一个
objects/
子目录(除非通过在环境中设置 GIT_OBJECTS_DIRECTORY
覆盖)。
未通过任何一项测试会使 Git 移动到存储库目录的下一个候选者,或者,如果它有 运行 个候选者,则放弃并声明没有Git 要找到的存储库。
执行此检查的代码在 setup.c. The is_valid_ref
test is elsewhere (path.c
) and basically tests whether HEAD
is a symbolic link to refs/*
, or starts with the literal ASCII text ref: refs/
, or contains a valid hash ID. The first two tests are the same as testing whether a reference is a symbolic ref (see the git symbolic-ref
command)。
包含提交哈希 ID 的 HEAD
文件是一个 分离的 HEAD。这表明 Git 存储库根本不在分支上。关于这一点几乎没有什么可说的(无论如何,直到我们开始克隆,下面)。要在可以直接使用 运行 Git 命令的存储库中设置分离的 HEAD,请将 git switch --detach
或 git checkout --detach
或 git checkout
与任何自动导致的参数一起使用分离的 HEAD 条件,即对不是分支名称的提交的任何引用。
(无法使用 GitHub Web 界面设置分离的 HEAD。)
可以对不存在的引用进行符号引用。这就是一个没有分支的新的空 Git 存储库可以在分支 master
上的方式,即使分支 master
尚不存在。因此,HEAD
链接到的分支,如果 HEAD
没有分离,实际上可能存在也可能不存在——但肯定会有一个 HEAD
.
由 git init
创建的一个新的完全空的存储库有一个符号 HEAD
引用名称 master
。
(据我所知,无法 设置 对 GitHub Web 界面不存在的分支的 HEAD 引用。但是 new 存储库仍然创建,其中 HEAD
象征性地引用 master
。)
遥控器
请注意,远程只是您自己的本地Git存储库中的字符串。也就是说,您可以创建名称 origin
来保存 url https://github.com/user/project.git
或 ssh://git@bitbucket.com/user/project.git
或类似的名称。
您对本地存储库所做的任何操作都不会改变 Git Hub 或 Bitbucket 上其他 Git 中的任何内容,因此您在此处所做的任何调整都无效。您需要使 Git 在 GitHub 或 Bitbucket 或任何其他实际托管服务器的站点上对 its Git 存储库,在您所做的任何更改之前实际上会产生任何影响。
(对于 GitHub,您只需登录 GitHub 并使用他们的网页操作您的存储库。这可以让您完全按照他们允许您做的事情进行操作,这比如果你能登录到他们的服务器,你能做的一切都比不上。)
克隆:其他存储库建议签出
当您克隆一个存储库时使用:
git clone [<options>] <url>
options
允许您指定:
对方叫什么Git:遥控器的名字。例如,使用 -o xyzzy
将名称从默认的 origin
更改为 xyzzy
。
分支名称在第六步中检查什么(见下文)。例如,git clone -b plugh
在第六步告诉你的 Git 到 git checkout plugh
。
如果您省略 -b
选项,您的 Git 会询问 他们的 Git 哪个分支 他们推荐。通常,您的 Git 将在第六步中尝试 git checkout
这个分支名称。
此建议背后的方法和细节随时间发生了变化。在遥远的过去,你的 Git 读取了他们 Git 的 HEAD
哈希 ID,如果他们提供了一个,并且 猜到了 这意味着哪个分支名称。在现代 Git 中,它们的 Git 可以提供从符号 HEAD
引用中读取的文字文本字符串。您的 Git 可以选择使用它,也可以忽略它。
git clone
命令是shorthand六步过程:
运行 mkdir
(或任何您计算机的命令)创建一个新的空目录,其中将创建新的 Git 存储库.剩下的五个步骤运行在这个新的空目录中。
运行 git init
创建一个 Git 存储库(新目录中的 .git
子目录)。
运行 git remote add
添加一个 远程 。除非您使用 -o
选项,否则遥控器的名称将是 origin
。遥控器的 URL 将是您给 git clone
的 URL。
运行 需要任何额外的 git config
命令,例如来自 -c
选项。
运行 git fetch origin
(或您使用的任何远程名称),以获取提交并使用远程跟踪名称填充您的存储库,例如 origin/master
基于任何分支名称存在于其他存储库中。
运行 git checkout
(pre-2.23)或git switch -c
(Git 2.23或更高版本),创建一个新分支并检查它的提交。
第六步中使用的分支名称是您的 -b
选项中的名称。您的 Git 将查看他们的分支(和标签!)名称,如果您的 -b
选项匹配他们的分支或标签名称之一,将使用该名称。如果名称是标签名称,您的 Git 将在适当的提交时进入分离的 HEAD 模式。
如果您没有使用 -b
,您的 Git 将询问他们的 Git 他们推荐哪个分支,如上所述。如果这是一个有效的名称,您的 Git 将创建该名称并检查该提交。
如果这两个都失败了,您的 Git 将返回到名称 master
。如果该名称也失败,您的 Git 将告诉您第六步失败:您有一个有效的存储库,并且您已将其全部克隆,但没有当前分支和提交。由您来纠正这种情况。
如果你克隆的仓库没有master
假设您从某个 URL 克隆了一个存储库,并且该存储库:
- 确实有提交;和
- 确实有分支——假设,不失一般性,例如,它们有
br1
和br2
;但是
- 没有名为
master
的分支。
进一步假设您在 git clone
行中没有提供 -b
选项。那么:
在第 5 步中,您的 git fetch
获得了他们的 br1
和 br2
名称,并创建了您的 origin/br1
和 origin/br2
名称。由于他们没有 master
,您的 Git 没有 origin/master
.
在第 6 步中,您没有提供 -b
,因此您的 Git 询问他们 Git 他们推荐哪个分支。
如果您没有采取任何特殊行动,他们将推荐的分支是符号名称在他们的 HEAD
中的分支。如果那个符号名称是master
,他们会推荐他们的master
——这当然不存在。您的 Git 会对这个建议感到困惑(它不起作用)并且会使用它自己的内置后备:尝试 master
。这也行不通,你会看到你所看到的。
当然,如果他们 有一个名为 master
的分支,您的第 5 步将创建您的 origin/master
,因此您的第 6 步将能够在他们的 origin/master
的基础上创建自己的 master
,一切都会好起来的。
如果您让他们更改符号名称 HEAD
以指向他们的 br2
分支,您将在第 6 步中得到的建议是您的 Git 应该创建一个分支根据他们的 br2
命名 br2
,现在(通过第 5 步)你的 origin/br2
,这也将很好地工作。但是您需要以某种方式进入服务器并让他们更改他们的推荐。
我是 git 的新手,正在遵循 Missing Semester 的以下出色指导。大约 1 小时后,他们讨论了遥控器。我经历了创建远程(作为测试的子目录)的过程,但是,我故意偏离说明,因为这有助于我的理解。我将一个分支推送到远程但没有命名它 "master"。我最终意识到这个遥控器中没有 HEAD,而且一切都无法正常工作。我查看了 git remote set-head 命令,认为这可以解决问题。我认为没有。最终起作用的是在远程创建一个名为 "master" 的分支,并且 HEAD 自动指向它。我没有在文档中看到这个要求。有没有办法让存储库没有名为 "master" 的分支?或者,如果没有名为 "master" 的分支,如何在远程创建后让 HEAD 指向一个分支?
TL;DR:您需要进入服务器(不知何故——如何 取决于服务器)并拥有 服务器的 Git 设置其 HEAD
。 (请注意,GitHub 有一个可点击的网页按钮界面,在 settings
下,然后是 branches
。)
不过,通常情况下,您只需让服务器创建其第一个名称为 master
的分支,之后一切都会按照大家期望的方式进行。请注意,如果服务器 Git 已经有一个名为 br1
的分支,您可以使用以下命令克隆该服务器 Git 存储库:
git clone -b br1 <em>url</em>
在您的客户端,然后是:
git push origin br1:master
要求该服务器创建名称 master
,指向与您在克隆中自己的 br1
相同的提交。现在服务器 有 master
并且一切恢复正常。
Long:这里到底发生了什么?
每个 Git 存储库都有一个 HEAD
所有 Git 存储库都有一个 HEAD。这是 Git 的基本要求:当 Git 去寻找存储库时,它会对其检查的每个目录进行多次完整性检查。目录必须:
- 作为目录存在;
- 包含一个名为
HEAD
的文件或符号链接似乎有效; - 有一个
refs/
子目录;和 - 有一个
objects/
子目录(除非通过在环境中设置GIT_OBJECTS_DIRECTORY
覆盖)。
未通过任何一项测试会使 Git 移动到存储库目录的下一个候选者,或者,如果它有 运行 个候选者,则放弃并声明没有Git 要找到的存储库。
执行此检查的代码在 setup.c. The is_valid_ref
test is elsewhere (path.c
) and basically tests whether HEAD
is a symbolic link to refs/*
, or starts with the literal ASCII text ref: refs/
, or contains a valid hash ID. The first two tests are the same as testing whether a reference is a symbolic ref (see the git symbolic-ref
command)。
包含提交哈希 ID 的 HEAD
文件是一个 分离的 HEAD。这表明 Git 存储库根本不在分支上。关于这一点几乎没有什么可说的(无论如何,直到我们开始克隆,下面)。要在可以直接使用 运行 Git 命令的存储库中设置分离的 HEAD,请将 git switch --detach
或 git checkout --detach
或 git checkout
与任何自动导致的参数一起使用分离的 HEAD 条件,即对不是分支名称的提交的任何引用。
(无法使用 GitHub Web 界面设置分离的 HEAD。)
可以对不存在的引用进行符号引用。这就是一个没有分支的新的空 Git 存储库可以在分支 master
上的方式,即使分支 master
尚不存在。因此,HEAD
链接到的分支,如果 HEAD
没有分离,实际上可能存在也可能不存在——但肯定会有一个 HEAD
.
由 git init
创建的一个新的完全空的存储库有一个符号 HEAD
引用名称 master
。
(据我所知,无法 设置 对 GitHub Web 界面不存在的分支的 HEAD 引用。但是 new 存储库仍然创建,其中 HEAD
象征性地引用 master
。)
遥控器
请注意,远程只是您自己的本地Git存储库中的字符串。也就是说,您可以创建名称 origin
来保存 url https://github.com/user/project.git
或 ssh://git@bitbucket.com/user/project.git
或类似的名称。
您对本地存储库所做的任何操作都不会改变 Git Hub 或 Bitbucket 上其他 Git 中的任何内容,因此您在此处所做的任何调整都无效。您需要使 Git 在 GitHub 或 Bitbucket 或任何其他实际托管服务器的站点上对 its Git 存储库,在您所做的任何更改之前实际上会产生任何影响。
(对于 GitHub,您只需登录 GitHub 并使用他们的网页操作您的存储库。这可以让您完全按照他们允许您做的事情进行操作,这比如果你能登录到他们的服务器,你能做的一切都比不上。)
克隆:其他存储库建议签出
当您克隆一个存储库时使用:
git clone [<options>] <url>
options
允许您指定:
对方叫什么Git:遥控器的名字。例如,使用
-o xyzzy
将名称从默认的origin
更改为xyzzy
。分支名称在第六步中检查什么(见下文)。例如,
git clone -b plugh
在第六步告诉你的 Git 到git checkout plugh
。
如果您省略 -b
选项,您的 Git 会询问 他们的 Git 哪个分支 他们推荐。通常,您的 Git 将在第六步中尝试 git checkout
这个分支名称。
此建议背后的方法和细节随时间发生了变化。在遥远的过去,你的 Git 读取了他们 Git 的 HEAD
哈希 ID,如果他们提供了一个,并且 猜到了 这意味着哪个分支名称。在现代 Git 中,它们的 Git 可以提供从符号 HEAD
引用中读取的文字文本字符串。您的 Git 可以选择使用它,也可以忽略它。
git clone
命令是shorthand六步过程:
运行
mkdir
(或任何您计算机的命令)创建一个新的空目录,其中将创建新的 Git 存储库.剩下的五个步骤运行在这个新的空目录中。运行
git init
创建一个 Git 存储库(新目录中的.git
子目录)。运行
git remote add
添加一个 远程 。除非您使用-o
选项,否则遥控器的名称将是origin
。遥控器的 URL 将是您给git clone
的 URL。运行 需要任何额外的
git config
命令,例如来自-c
选项。运行
git fetch origin
(或您使用的任何远程名称),以获取提交并使用远程跟踪名称填充您的存储库,例如origin/master
基于任何分支名称存在于其他存储库中。运行
git checkout
(pre-2.23)或git switch -c
(Git 2.23或更高版本),创建一个新分支并检查它的提交。
第六步中使用的分支名称是您的 -b
选项中的名称。您的 Git 将查看他们的分支(和标签!)名称,如果您的 -b
选项匹配他们的分支或标签名称之一,将使用该名称。如果名称是标签名称,您的 Git 将在适当的提交时进入分离的 HEAD 模式。
如果您没有使用 -b
,您的 Git 将询问他们的 Git 他们推荐哪个分支,如上所述。如果这是一个有效的名称,您的 Git 将创建该名称并检查该提交。
如果这两个都失败了,您的 Git 将返回到名称 master
。如果该名称也失败,您的 Git 将告诉您第六步失败:您有一个有效的存储库,并且您已将其全部克隆,但没有当前分支和提交。由您来纠正这种情况。
如果你克隆的仓库没有master
假设您从某个 URL 克隆了一个存储库,并且该存储库:
- 确实有提交;和
- 确实有分支——假设,不失一般性,例如,它们有
br1
和br2
;但是 - 没有名为
master
的分支。
进一步假设您在 git clone
行中没有提供 -b
选项。那么:
在第 5 步中,您的
git fetch
获得了他们的br1
和br2
名称,并创建了您的origin/br1
和origin/br2
名称。由于他们没有master
,您的 Git 没有origin/master
.在第 6 步中,您没有提供
-b
,因此您的 Git 询问他们 Git 他们推荐哪个分支。
如果您没有采取任何特殊行动,他们将推荐的分支是符号名称在他们的 HEAD
中的分支。如果那个符号名称是master
,他们会推荐他们的master
——这当然不存在。您的 Git 会对这个建议感到困惑(它不起作用)并且会使用它自己的内置后备:尝试 master
。这也行不通,你会看到你所看到的。
当然,如果他们 有一个名为 master
的分支,您的第 5 步将创建您的 origin/master
,因此您的第 6 步将能够在他们的 origin/master
的基础上创建自己的 master
,一切都会好起来的。
如果您让他们更改符号名称 HEAD
以指向他们的 br2
分支,您将在第 6 步中得到的建议是您的 Git 应该创建一个分支根据他们的 br2
命名 br2
,现在(通过第 5 步)你的 origin/br2
,这也将很好地工作。但是您需要以某种方式进入服务器并让他们更改他们的推荐。