我签出特定的提交(因此,最终以分离的HEAD状态结束),然后在其上面进行一些提交。假设我在存储库A中进行了此操作。进一步假设我有另一个存储库B,该存储库B以A作为其远程服务器之一。现在,在B中,如何在不创建A的新分支的情况下获取A 的分离的HEAD?
答案 0 :(得分:2)
与ElpieKay answered in a comment一样,使用git fetch remote HEAD
,这会将获取的提交的哈希ID保存在特殊的FETCH_HEAD
文件中。然后,您可以使用FETCH_HEAD
作为参考,直到下一个git fetch
覆盖它为止。
获取和推送操作都可以使用名称,但是它们不是对称的。
在传输 commits 时,它们 是对称的。也就是说,无论您运行git fetch remote [refspec...]
还是git push remote [refspec...]
,发送和接收Git系统都会进行涉及对象哈希ID的对话,在该会话中,发送方将发送方想要提供给接收方的哪些哈希ID公告: em>我为您准备了
不过,完成此操作后,push
操作将使发送者发送一系列推荐的refs/heads/master
设置为{{1 }} 。这意味着,如果您在{em>您的存储库中的a123456...
上处于分离状态,git push
,则仍必须给 other Git一个提交的名称:
HEAD
例如,足以让您的Git发送您的git push origin HEAD:refs/heads/somebranch
提交的哈希ID,但是建议他们的Git将其 HEAD
设置为完成后该哈希ID。您不能要求他们设置他们的refs/heads/somebranch
:如果尝试,他们只会创建一个名为HEAD
的分支,即HEAD
(如果您现在在分支机构上,否则请拒绝您的推送请求:
refs/head/HEAD
另一方面,当您运行error: unable to push to unqualified destination: HEAD
时,您控制哪个参考(如果有的话)最终得到更新。他们的Git只是发送 all 他们的引用的列表(无论如何,协议v0; v2更为出色)。您的Git会选择列表,如果他们为您的git fetch
和refs/heads/master
发送了新的哈希ID,则您的Git通常会更新您自己的refs/heads/branch
和refs/remotes/origin/master
。您的Git会获取他们的引用列表,生成您一方的“想要的”哈希ID列表,然后将其传递给发送者,以开始进行有/想要的哈希ID对话。
也就是说,如果您运行refs/remotes/origin/branch
,并且添加了 no git fetch origin
参数,并且假设您的配置正常,那么Git就是这样做的(例如,不是refspec
克隆的特殊配置)。但是,如果您执行添加refspec参数,例如:
--single-branch
然后,您的Git要求其Git仅发送您与他们的git fetch origin refs/heads/master:refs/weird/name
合作所需的提交。也就是说,有/想要的对话以其master
中的哈希ID only 开始(即使如此,仅当您还没有哈希ID时)。完成需求后,对象已到达存储库中,Git然后创建或更新您的refs/heads/master
引用。
请记住,这些refspec的常规格式为refs/weird/name
。 src:*dst
部分是源引用(发送方用来查找提交的名称或哈希ID)和 src
部分是目标参考,接收者应使用该参考来最终记住哈希ID。您可以通过编写 dst
或src
来省略两者之一,具体取决于推与取,它们具有各种特殊情况的含义。原始哈希ID是否在此表达式的 :dst
部分中起作用取决于两件事:
src
,则它始终有效(只要对象存在); push
,则当且仅当他们允许时,它才有效。(因此,在这里,我们已经看到提取和推送是不对称的。)
对于fetch
,如果您省略了refspec的git fetch
部分(例如:dst
或git fetch origin refs/heads/master
),您的Git会跳过创建或更新部分,但用于所谓的机会更新(在这种情况下,创建或更新git fetch origin master
)。但是,对于您的refs/remotes/origin/master
获得的每个名称,您的Git 总是将git fetch
文件中:
FETCH_HEAD
(请注意,尽管$ git fetch origin HEAD master
From ...
* branch HEAD -> FETCH_HEAD
* branch master -> FETCH_HEAD
$ cat .git/FETCH_HEAD
f84b9b09d40408cf91bbc500d9f190a7866c3e0f <url>
f84b9b09d40408cf91bbc500d9f190a7866c3e0f branch 'master' of <url>
在git fetch
的名称/ ID对列表中有许多分支和标签,但我们{em>只是为origin
和{ {1}},这就是HEAD
写到master
的内容。)
如果您正在发送提交,则必须为另一个Git提供一个名称。通常,该名称是隐式的:您按下分支git fetch
,因此要 them 设置的名称是 their 分支.git/FETCH_HEAD
。您可以推送任何对象:接收对象后,由其Git决定是否接受
但是,如果您正在接收,则不需要在您的身边提供名称。他们的Git将发送其名称和对象,而您的Git将使用您的bran
文件来记住您从他们那里获得的哈希ID。如果确实提供名称,则Git会更新这些名称,否则,Git会具有一些复杂的默认获取规则,以便通过bran
名称记住其分支名称。
虽然.git/FETCH_HEAD
本身不是分支名称,但它是有效的名称。您可能无法使他们更新其分离的refs/remotes/remote/
(通过HEAD
),但是通常可以让他们向您发送存储在其分离的{{1 }},您的Git会在您的HEAD
中将其记为“未命名”。
答案 1 :(得分:-1)
我认为您不能只推一个独立的头。如果要查看B中的这些更改,则必须将提交推送到A中的某个位置。要么进入新分支,要么进入现有分支。 由于您不想在A中创建新分支,因此我假设您已将提交推送到原始分支中。因此,您可以通过简单的拉动来访问它们。
如果您还没有将提交推送到任何地方,那么我可以说,最好的方法是直接在存储库B中进行更改。