更改Git远程HEAD以指向除master以外的其他东西


123

如何设置Git遥控器的HEAD引用指向除“ master”之外的其他内容?

我的项目有一个不使用“ master”分支的策略(所有分支都应具有有意义的名称)。此外,规范的主存储库只能通过ssh://进行访问,而无外壳访问(例如GitHub或Unfuddle)。

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

  1. 克隆仓库时,有这个

    警告:远程HEAD引用不存在的引用,无法检出。

    这令人困惑和不便。

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


只是为记录添加了一种可能性,但不适合您的情况。
VonC

“不常见的祖先”把戏:有趣。您可以将其发布为详细答案,如果发现有效,则可以选择它作为正式答案。
VonC

12
FWIW,因为您在问题中提到了GitHub-如果要更改GitHub上的HEAD引用,只需转到存储库的“管理员”屏幕,然后将“默认分支”下拉列表更改为希望HEAD指向的任何分支。
2012年


Answers:


63

一年前在GitHub上几乎有相同的问题

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

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

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

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

这类似于“ 如何在Git中删除源/主服务器 ”。


就像在这个线程中所说的:(强调我的)

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

因此,要打包,您需要回购A并将其克隆:

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

  • HEAD引用refs/heads/anotherBranch存在并且存在
    ->您将获得一个名为的本地分支anotherBranch,从origin/anotherBranch

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

不知道是否有任何方法可以直接修改HEADrepo中的ref

(我知道这是您问题的全部内容;)


也许唯一的方法是“为穷人出版”,您可以:

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

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


正如我在“ Git:在裸仓库中更改Active Branch的正确方法? ”中所解释的那样,git remote set-head不会在远程仓库上进行任何更改。

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


谢谢,VonC。在发布之前,我已阅读过该内容。但是正如您所看到的,由于技术和政策原因,不欢迎在该项目中使用名为“ master”的分支。
JasonSmith,2009年

然后,您可以通过禁止使用预提交挂钩对master分支进行任何更新来实施该策略。
VonC

是的,如果事实证明没有办法做我想做的事,那么我会完全按照我的意思接受你的回答。感谢您的跟进!
JasonSmith

感谢更新。目前,我使用了“ no-common-祖先”技巧来制作只进行一次提交的master分支。(即:git branch -D master; echo ref:refs / heads / master> .git / HEAD; rm *)。然后,我刚刚触摸了一个名为GO_AWAY的文件,并通过提交消息说明了这种情况。现在可以使用。我可能会检查源,并跟踪接收方将HEAD设置为最终答案的位置。
JasonSmith,2009年

1
@ctn那仅仅是因为我忘记了-f--force)选项。我已经相应地编辑了答案。然后,您引用的答案确实使用相同的选项。
VonC

42

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

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

git remote set-head $REMOTE_NAME $BRANCH

因此,例如,将远程头切换origin到分支develop将是:

git remote set-head origin develop


此功能是否需要服务器上最新版本的git?如果客户端计算机已安装最新的git,是否足够?
Mikko Rantalainen 2014年

3
@Totor简洁但正确;这个答案应该被否决。Git具有“远程的本地默认分支”这个令人困惑的概念。它使您可以键入“ origin”而不是“ origin / defaultbranch”,这是纯客户端的事情。说来话长在git-scm.com/docs/git-remote#组头
三月

1
确认@MarchH在说什么:run 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(仍将是添加默认分支之前的状态)。
De Novo

37

既然您提到了GitHub,只需在您的项目中进入GitHub,然后...

admin > Default Branch > (choose something)

做完了


1
优秀的!那是最后遗失的一点。
berkus 2012年

我的原点/ HEAD已经指向功能分支而不是master。我尝试来回更改“主分支”,但这并没有影响HEAD ...有什么建议吗?
Daniil Shevelev 2014年

3
设置>分支>默认分支
春阳2015年

12

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

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

用法:

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

6
$ git symbolic-ref HEAD refs / heads / branch-branch
Lamy 2012年

我在远程存储库中执行了此操作,它解决了克隆问题,由于某些原因,该头是另一个分支名称,因此尝试克隆master会导致在尝试在composer中关闭master时导致错误,这可能是特定于此情况的,但其他人可能会担任这个职位,并想知道该怎么做
Christopher Thomas

10

(已经存在基本相同的问题“ 在远程存储库中创建git符号引用 ”,但没有得到普遍的答案。)

但也有不同的git的“农场”一个具体的答案(其中多个用户可以通过一个受限制的接口管理git的回购协议:通过HTTP和SSH):http://Github.comhttp://Gitorious.orgHTTP:/ /repo.or.czGirarhttp://git.altlinux.org)。

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


4
现在他们有了一个下拉菜单,用于在repo.or.czgitorious.org上选择HEAD分支(例如:repo.or.cz/editproj.cgi?name=for-me- and -for- all_imz.git)。也一样 大!
IMZ -伊万Zakharyaschev

7

如果您可以从Shell访问远程仓库,只需进入.git(如果是裸仓库,则进入主目录)并更改HEAD文件以指向正确的头。例如,默认情况下,它始终包含“ refs:refs / heads / master”,但是如果您需要foo作为HEAD,则只需编辑HEAD文件并将内容更改为“ refs:refs / heads / foo”。


我在Git服务器上具有管理员权限,并且我做的完全一样。我们使用Gitolite,然后转到了我创建的存储库。目录名称为myrepo.git。给定目录中HEAD文件的内容已从更改ref: refs/heads/masterref: refs/heads/mainline。现在,当我尝试在本地机器上克隆存储库时,它仍然指向master。我执行git clone ssh://gitolite@git.server/myrepo命令。对这种行为有任何想法吗?
Technext

Git服务器版本:git version 1.7.1&Git客户端版本:git version 1.9.4.msysgit.2
Technext

5

您可以仅使用瓷器Git命令创建一个独立的master分支:

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

这给我们的分支带来了粗鲁的信息(您可能要礼貌些)。现在,我们创建我们的“真实”分支(为了纪念SVN,我们将其称为trunk)并将其与master离婚:

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

嘿,presto! gitk --all将显示mastertrunk,它们之间没有链接。

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

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

--allow空时,才需要标志,因为我们正在犯一个空的树。如果在git rm之后有一些git add,则没有必要。

实际上,您可以随时创建一个独立的分支,方法是在存储库中分支初始提交,删除其树,添加独立的树,然后执行git commit --amend

我知道这不能回答如何修改远程存储库上的默认分支的问题,但是它为如何创建分离的分支提供了明确的答案。


1
通过从另一个存储库中获取一个不相关的分支并为其命名,可以更轻松地创建一个分离的分支。例如,git fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEAD将添加detached-branchremote-branch-nameremote 中的分支匹配的新分支git:user@example.com:foo。当然,“远程”可以是您先前准备的本地文件系统中的存储库。
Mikko Rantalainen

2

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

$>git branch main

接下来,将该分支推到原点

$>git push origin main

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

然后,您可以选择删除master分支:

$>git push origin :master


要理解的关键点是,如果您的托管提供程序(在本示例中为GitHub)未提供修改默认分支的方法,那么您就不走运了。Git协议不提供修改远程默认分支的功能。您将需要能够git symbolic-ref在远程Shell 上运行,或者能够修改HEAD远程存储库根目录中调用的文本文件。
Mikko Rantalainen 2013年

2

与该问题有关,我在搜索时到这里结束了:

如何使本地存储库知道GitHub上默认的分支已更改

为了完整性,请添加答案:

git remote set-head origin -a

0

对于gitolite人来说,gitolite支持一个名为-等待-的命令symbolic-ref。如果您对存储库具有W(写入)权限,则它允许您远程运行该命令。


-1

很简单,只需登录您的GitHub帐户,然后在导航菜单的最右侧选择设置,在设置选项卡中选择默认分支,然后返回存储库的主页即可。


1
尽管它在GitHub界面中将新分支显示为默认分支,但是当执行git clone [repo]时,我没有得到该分支。即.git / HEAD包含错误的引用。
约瑟夫·希迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.