创建不是无头但没有主分支的远程

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 --detachgit checkout --detachgit 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.gitssh://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六步过程:

  1. 运行 mkdir(或任何您计算机的命令)创建一个新的空目录,其中将创建新的 Git 存储库.剩下的五个步骤运行在这个新的空目录中。

  2. 运行 git init 创建一个 Git 存储库(新目录中的 .git 子目录)。

  3. 运行 git remote add 添加一个 远程 。除非您使用 -o 选项,否则遥控器的名称将是 origin。遥控器的 URL 将是您给 git clone 的 URL。

  4. 运行 需要任何额外的 git config 命令,例如来自 -c 选项。

  5. 运行 git fetch origin (或您使用的任何远程名称),以获取提交并使用远程跟踪名称填充您的存储库,例如 origin/master 基于任何分支名称存在于其他存储库中。

  6. 运行 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 克隆了一个存储库,并且该存储库:

  • 确实有提交;和
  • 确实有分支——假设,不失一般性,例如,它们有br1br2;但是
  • 没有名为 master 的分支。

进一步假设您在 git clone 行中没有提供 -b 选项。那么:

  • 在第 5 步中,您的 git fetch 获得了他们的 br1br2 名称,并创建了您的 origin/br1origin/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,这也将很好地工作。但是您需要以某种方式进入服务器并让他们更改他们的推荐。