【问题标题】:Change a Git remote HEAD to point to something besides master更改 Git 远程 HEAD 以指向除 master 之外的其他内容
【发布时间】:2010-12-01 22:00:56
【问题描述】:

如何将 Git 远程的 HEAD 引用设置为指向“master”之外的其他内容?

我的项目有一个不使用“主”分支的政策(所有分支都必须有有意义的名称)。此外,规范的主存储库只能通过 ssh:// 访问,没有 shell 访问权限(如 GitHub 或 Unfuddle)。

我的问题是远程存储库仍然有对 refs/heads/master 的 HEAD 引用,但我需要它指向不同的分支。这导致了两个问题:

  1. 在克隆 repo 时,有这个,

    警告:远程 HEAD 引用不存在的 ref,无法结帐。

    这令人困惑和不便。

  2. 基于 Web 的代码浏览器依赖 HEAD 作为浏览树的基础。那么我需要 HEAD 指向一个有效的分支。

【问题讨论】:

  • 只是添加了一种可能性作为记录,但不适合您的情况。
  • "no-common-ancestor" 技巧:有趣。您可以将其作为详细答案发布,如果您发现它有效,请选择它作为官方答案。
  • FWIW,因为您在问题中提到了 GitHub——如果您想更改 GitHub 上的 HEAD 引用,只需转到存储库的“管理”屏幕,然后将“默认分支”下拉列表更改为任何内容您希望 HEAD 指向的分支。

标签: git git-branch git-remote


【解决方案1】:

几乎一年前就有same question on GitHub

这个想法是重命名主分支:

git branch -m master development
git branch -m published master
git push -f origin master 

让master拥有你希望人们使用的东西,并在分支中完成所有其他工作。

(“git-symbolic-ref HEAD refs/head/published”不会传播到远程仓库)

这类似于“How do I delete origin/master in Git”。


正如this thread 中所说:(强调我的)

git clone”只创建一个本地分支。
为此,它会查看远程仓库的HEAD ref,并创建一个与它引用的远程分支同名的本地分支。

所以总结一下,你有 repo A 并克隆它:

  • HEAD 引用 refs/heads/master 并且存在
    -> 你会得到一个名为master 的本地分支,从origin/master 开始

  • HEAD 引用 refs/heads/anotherBranch 并且存在
    -> 你会得到一个名为anotherBranch 的本地分支,从origin/anotherBranch 开始

  • HEAD 引用 refs/heads/master 并且不存在
    ->“git clone”抱怨

不确定是否有任何方法可以直接修改 repo 中的 HEAD 引用

(我知道这是你问题的全部重点;))


也许唯一的方法是"publication for the poor",你:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

但这将涉及对服务器的写访问,这并不总是可能的。


正如我在“Git: Correct way to change Active Branch in a bare repository?”中解释的那样,git remote set-head 不会改变远程仓库中的任何内容。

它只会更改存储在本地仓库中的远程跟踪分支,位于remotes/<name>/HEAD


在 Git 2.29(2020 年第四季度)中,失败的“git remote set-head(man)”仍然表示暗示操作已通过,这具有误导性。

参见Christian Schlack (cschlack)commit 5a07c6c(2020 年 9 月 17 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 39149df,2020 年 9 月 22 日)

remoteset-head 失败时不显示成功消息

签字人:Christian Schlack

在出现错误时抑制消息“origin/HEAD set to master”。

$ git remote set-head origin -a
error: Not a valid ref: refs/remotes/origin/master
origin/HEAD set to master

【讨论】:

  • 谢谢,VonC。我在这里发帖之前读过。但正如您所见,由于技术和政策原因,该项目不欢迎名为“master”的分支。
  • 您可以通过 pre-commit hook 禁止 master 分支上的任何更新来强制执行该策略。
  • 是的,如果事实证明没有办法做我想做的事,那么我会这样做并接受你的回答。感谢您的跟进!
  • 感谢您的更新。目前,我使用“no-common-ancestor”技巧来创建一个只有一次提交的主分支。 (即:git branch -D master;echo ref:refs/heads/master > .git/HEAD;rm *)。然后我只是触摸了一个名为 GO_AWAY 的文件,提交消息说明了情况。现在可以了。我可能会检查源并追踪接收方设置 HEAD 的位置以获得最终答案。
  • @ctn 那只是因为我忘记了-f (--force) 选项。我已经相应地编辑了答案。然后回答你参考确实使用相同的选项。
【解决方案2】:

更新:这仅适用于存储库的本地副本(“客户端”)。请在下方查看其他人的 cmets。

使用最新版本的 git(2014 年 2 月),正确的程序是:

git remote set-head $REMOTE_NAME $BRANCH

例如,将远程origin 上的头部切换到分支develop 将是:

git remote set-head origin develop

【讨论】:

  • 这个功能是否需要服务器上最新版本的 git 或者如果客户端机器安装了最新的 git 就足够了?
  • @Totor 简洁但正确;这个答案应该被否决。 Git 有一个“远程的本地默认分支”这个有点令人困惑的概念。它可以让你输入“origin”而不是“origin/defaultbranch”,并且是一个纯客户端的东西。长篇大论git-scm.com/docs/git-remote#set-head
  • 确认@MarchH 在说什么:运行git checkout -b default; git push origin HEAD; git remote set-head origin default。然后您可以使用cat .git/refs/remotes/origin/HEAD(应该是ref: refs/remotes/origin/default)检查本地更改,使用git remote show origin(它仍然是添加默认分支之前的任何内容)缺少远程更改。
【解决方案3】:

既然你提到了 GitHub,要在他们的网站上做,只需进入你的项目,然后...

admin > Default Branch > (choose something)

完成。

【讨论】:

  • 太棒了!这是最后一个缺失的部分。
  • 我的 origin/HEAD 已经指向一个特性分支而不是 master。我尝试来回更改“主分支”,但它并没有影响 HEAD...有什么建议吗?
  • 设置 > 分支 > 默认分支
  • 更改 Gitlab/Github 中的默认分支,不会更改 remotes/origin/HEAD -> origin/master 指针
【解决方案4】:

见:http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

这将设置 git 存储库中的默认分支。您可以在裸存储库或镜像存储库中运行它。

用法:

$ git symbolic-ref HEAD refs/heads/<branch name>

【讨论】:

  • $ git symbolic-ref HEAD refs/heads/name-of-branch
  • 我在我的远程仓库中做了这个,它解决了我的克隆问题,由于某种原因头部是另一个分支名称,因此尝试克隆 master 会导致错误,同时尝试在 composer 中关闭 master,这可能非常特定于这种情况,但其他人可能处于该位置并想知道该怎么做
【解决方案5】:

(已经有基本相同的问题“create a git symbolic ref in remote repository”,没有得到普遍的答案。)

但是对于各种 git“农场”(多个用户可以通过受限接口管理 git repos:通过 http 和 ssh)有特定的答案:http://Github.comhttp://Gitorious.orghttp://repo.or.czGirarhttp://git.altlinux.org)。

这些具体答案可能对阅读此页面并考虑这些具体服务的人有用。

【讨论】:

【解决方案6】:

如果您可以从 shell 访问远程存储库,只需进入 .git(或主目录,如果它是一个裸存储库)并更改 HEAD 文件以指向正确的头。例如,默认情况下它总是包含'refs: refs/heads/master',但如果你需要 foo 作为 HEAD,只需编辑 HEAD 文件并将内容更改为'refs: refs/heads/foo'。

【讨论】:

  • 我在 Git 服务器上拥有管理员权限,而且我的操作完全相同。我们使用 Gitolite,然后我去了我创建的存储库。目录名称为myrepo.git。给定目录中 HEAD 文件的内容从 ref: refs/heads/master 更改为 ref: refs/heads/mainline。现在,当我尝试在本地机器上克隆存储库时,它仍然指向 master。我运行了git clone ssh://gitolite@git.server/myrepo 命令。对这种行为有什么想法吗?
  • Git 服务器版本:git version 1.7.1 & Git 客户端版本:git version 1.9.4.msysgit.2
【解决方案7】:

您可以仅使用瓷器 Git 命令创建一个分离的 ma​​ster 分支:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

这给了我们一个带有粗鲁信息的 ma​​ster 分支(你可能想要更有礼貌)。现在我们创建我们的“真实”分支(我们称它为 trunk 以纪念 SVN)并将其与 ma​​ster 分离:

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

嘿,快! gitk --all 将显示 ma​​stertrunk 之间没有链接。

这里的“魔法”是 --amend 导致 git commit 创建一个与当前 HEAD 具有相同父级的新提交,然后让 HEAD 指向它.但是当前的 HEAD 没有父级,因为它是存储库中的初始提交,因此新的 HEAD 也没有得到父级,从而使它们彼此分离。

旧的 HEAD 提交不会被 git-gc 删除,因为 refs/heads/master 仍然指向它。

--allow-empty 标志是唯一需要的,因为我们正在提交一个空树。如果在 git rm 之后有一些 git add,那么就没有必要了。

事实上,您可以随时通过在存储库中对初始提交进行分支、删除其树、添加您的分离树、然后执行 git commit --amend 来创建分离分支。。 p>

我知道这并没有回答如何修改远程存储库上的默认分支的问题,但它给出了关于如何创建分离分支的明确答案。

【讨论】:

  • 您可以通过从另一个 repo 获取不相关的分支并为其命名来更轻松地创建分离的分支。例如,git fetch git:user@example.com:foo remote-branch-name &amp;&amp; git checkout -b detached-branch FETCH_HEAD 将添加与远程git:user@example.com:foo 中的分支remote-branch-name 匹配的新分支detached-branch。当然,“远程”可以是您之前准备好的本地文件系统中的存储库。
【解决方案8】:

与问题有关,我在搜索时最终到了这里:

如何让本地存储库了解 GitHub 上更改的默认分支

为了完整起见,添加答案:

git remote set-head origin -a

【讨论】:

  • git remote set-head origin &lt;branch&gt;
【解决方案9】:

首先,创建您想要设置为默认的新分支,例如:

$&gt;git branch main

接下来,将该分支推送到origin

$&gt;git push origin main

现在,当您登录您的 GitHub 帐户时,您可以转到您的存储库并选择设置>默认分支,然后选择“main”。

然后,如果你这样选择,你可以删除 master 分支:

$&gt;git push origin :master

【讨论】:

  • 要理解的关键点是,如果您的托管服务提供商(本例中为 GitHub)没有提供修改默认分支的方法,那么您就不走运了。 Git 协议不提供修改远程默认分支的功能;您需要能够在远程 shell 上运行 git symbolic-ref,或者能够修改远程存储库根目录中名为 HEAD 的文本文件。
【解决方案10】:

对于 gitolite 人,gitolite 支持名为 -- 等待 -- symbolic-ref 的命令。如果您对 repo 有 W(写)权限,它允许您远程运行该命令。

【讨论】:

    【解决方案11】:

    只需登录您的 GitHub 帐户,然后在导航菜单的最右侧选择 Settings,在 Settings 选项卡 中选择 Default Branch 并返回对我有用的存储库主页。

    【讨论】:

    • 虽然它在 GitHub 界面中将新分支显示为默认分支,但在执行 git clone [repo] 时,我没有得到该分支。即 .git/HEAD 包含错误的参考。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2018-02-15
    • 2014-07-11
    • 1970-01-01
    • 2014-04-21
    相关资源
    最近更新 更多