我有两个存储库绑定到我的工作目录。
git remote show origin
* remote origin
Fetch URL: ssh://project.git/
Push URL: ssh://project.git/
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
git remote show develop
* remote develop
Fetch URL: ssh://projecttest.git/
Push URL: ssh://projecttest.git/
HEAD branch: master
Remote branch:
master new (next fetch will store in remotes/develop)
Local ref configured for 'git push':
master pushes to master (local out of date)
据我所知,本地分支以这种方式引用远程分支:
origin/master
指向本地分支master
develop/master
指向本地分支master
我想要实现的是更改develop/master
远程分支的此引用。我希望它指向trunk
本地分支
develop/master
应指向本地分支trunk
我该怎么做?
答案 0 :(得分:13)
在我回答之前,我想在这里更改这些术语,因为您使用某些单词的方式与大多数git文档中使用的单词和方法不匹配。
首先,让我们谈谈git存储库中提交生成的图形。
每次在存储库中创建提交时,都必须指定以下项。其中许多是隐含的;实际上,git commit
和git merge
(这两个主要的提交创建者)将为您查找所有这些内容:
-m
参数,或git commit
激活您的编辑器等) Git结合了所有这些并创建了一个新的唯一SHA-1值 - 那些笨拙的40个字符的字符串,如9c4ea50db79d3ce6fe3abccf20f1af27abae45b2
- 是提交(它存储此提交对象)回购,由其SHA-1 ID)。如果提交是普通提交,则它有一个父项,git commit
在HEAD
创建之前不久.git
通过git commit
找到(git存储在git merge
目录中)新提交。如果它是" root commit"就像新回购中的第一次提交一样,它有没有父母。如果它是"合并提交" (例如,由.git
创建),它具有至少两个父ID(这些ID来自o-o-o-o-o-o-o
\ /
o-o-o
目录中的文件git store)。存储在任何给定提交中的父项是原始SHA-1 ID。
因此,给定任何一个提交SHA-1 ID,您可以从存储库中读取提交并获取其父提交。读那些让你的父母。继续,直到您到达根提交,并且您可以绘制一些内容,其中包含可能的分支点和合并点:
o
这是一个提交图,有10个提交"节点" (-
s)其中一些分支然后合并回来。我在\
/
和master
个字符的节点之间绘制了线条
当我们使用git时,我们经常将这些行称为#34; branches",这是一个合理的名称,但是" branch"的另一个含义。
接下来,让我们定义一个"分支" (或者#34;本地分支")这样,这就是git真正起作用的方式:一个(本地)分支是一个名称,如develop
或url
,存储SHA-1 ID并且具有另一个特殊属性。特殊属性是当我们进行新提交时存储的ID 更改,以便branch-name始终标识"提示"分支机构。
请记住,每次提交都有父 ID,但不包含任何子 ID。当你进行新的提交时,新的提交"指回" (通过这些存储的ID)到旧的,但旧的永远不会改变。仅仅给出父ID而难以找到子ID,但是仅仅给出子ID的父ID很容易找到。所以只要分支名称"指向"分支的提示,我们可以找到"分支的其余部分"容易。因此git只是保证本地分支名称始终标识分支的提示。
(有点不幸的是,&#34;分支&#34;意味着两者&#34;本地名称持有分支小费的ID&#34; < em>和&#34;通过从尖端开始并向后工作形成的提交链#34;几乎总是显而易见的是哪一个将被使用,但只有&#34;几乎&#34;。)
现在让我们定义&#34; remote&#34;:远程是你组成的名称并放在你的本地git存储库中,用于记住某些其他的东西 git存储库,通常在另一台计算机上,属于其他人。远程有一个remote.origin.url
(或者有时几个:remote.origin.pushurl
,可选remotes/origin/master
,这就是git将如何获取和推送到另一个repo。
当然,其他repo有(本地)分支 - 分支名称指向提交提交 - 事实证明我们经常想知道其他repo的本地分支名称和提示提交 - 或者更准确地说,他们上次检查时他们是什么。 (它们已经过时了,所以我们不时刷新它们。)这些就是成为&#34;远程分支机构&#34;。所以现在我们可以定义&#34;远程分支&#34;通过示例稍微宽松一点:远程分支master
是远程origin
上本地分支origin
的副本,上次我们有机会连接到{{1}并问你&#34; master
中的内容是什么?&#34;
更准确地说:每个远程分支remotes/R/B
都是远程 B
上本地分支 R
的副本我们最后一次检查并保存了它。
现在我们只需要一个&#34;跟踪分支&#34;的另一个定义。 跟踪分支是一个本地分支,我们告诉git有一个相应的远程,并在该远程上有一个相应的分支名称。我们告诉git这两个方面的低级方式是配置带有git config
的两个字符串。例如,假设我们希望本地分支greyhound
跟踪名为racetrack
的远程hare
上的分支。要在最低级别执行此操作,我们执行此操作:
git config branch.greyhound.remote racetrack
git config branch.greyhound.merge hare
(使事情变得复杂 - 这似乎是一个历史性事故 - 实际的跟踪是通过遥控器的fetch
配置进行映射的。但remote.racetrack.fetch
几乎总是设置为阅读+refs/heads/*:refs/remotes/racetrack/*
在大多数情况下,我们可以假设refs/remotes/
部分是常量。)所以,再次,在底层,当git想知道greyhound
是否已经赶上hare
,它真正做的是看remotes/racetrack/hare
。 hare
部分来自branch.greyhound.merge
行,racetrack
部分来自branch.greyhound.remote
。
remotes/
部分。因此,您可以通常只编写remotes/origin/master
而不是origin/master
。 (如果你创建歧义,有一些例外,例如,如果你创建一个名为origin
的本地分支,它会变得棘手。但只要你不这样做,你就可以省略{{1}人们和git经常把它留下来。)
最后一点注意,因为我有上面的所有其他定义。特殊参考remotes/
通常是&#34;符号引用&#34;。符号引用包含另一个引用的名称,通常是本地分支名称。这就是git知道如何将本地分支调整到新的分支提示:如果您在分支主文件&#34;上,HEAD
包含HEAD
,那么{{1添加新提交并更新ref: refs/heads/master
。如果git commit
包含原始SHA-1值,master
会像往常一样添加新提交,然后更改HEAD
以获得新的SHA-1,但没有本地分支名称指向新提交。这是&#34;分离的HEAD&#34;条件。
呼!好的,现在回到手头的问题。你即将绊倒目前在git中修复的烦恼。
您想要或需要:
git commit
的遥控器上,必须有一个带HEAD
分支的git仓库origin
的遥控器上,必须有一个带master
分支的git仓库develop
成为master
的跟踪分支master
成为origin/master
的跟踪分支trunk
时,您希望将develop/master
推送到git push origin
,并且可能根本没有推出master
master
时,您希望trunk
被推动开发git push develop
,并且可能根本没有推动trunk
master
(没有其他参数)时,你想......好吧,我不确定你想要什么,但我会在下面猜一下。步骤1到4只需要完成一次。如果尚未在其中一个或两个上创建分支master
,您可以执行以下操作:
git push
(如果你的git推送足够新,让master
)一次完成所有事情。或者,如果您有,可以使用git push -u origin master:master
git push -u develop trunk:master
,或者如果您愿意,可以使用-u
完全手动进行跟踪。但是,如果需要,可以通过这种或那种方式在远程存储库上创建分支,然后选择它们(作为&#34;远程分支机构&#34;在您的本地存储库中)并将您的本地分支机构设置为&#34; track&#34 ;远程分支。
剩下的步骤。这些有点令人困惑。
在最新版本的git(至少1.7以后)中,有一个配置设置--set-upstream
会影响git config
在省略refspec时的工作方式,即push.default
项目5到7中的命令。您需要将其设置为git push
。这绝不是默认设置,因此您必须运行:
push
设置它。
如果你运行裸upstream
(如在#7中),git使用相同的跟踪分支信息来选择远程。所以,现在您已经更改了git config push.default upstream
,如果您在分支git push
上运行push.default
,那么您实际上将运行master
,如果您和#39;在分支git push
上运行git push origin master:master
,您实际上将运行trunk
。
如果您只是让git push
设置执行此操作,并在git push develop trunk:master
上运行push.default upstream
,那么,您没有告诉它推动您的名为git push develop
的本地分支。因此,要使5和6工作,您需要两个不同的 git配置项。
如果您运行master
(没有refspec参数),trunk
会查找git push remote
,并在设置时使用该git push
。因此,您可以设置remote.remote.push
和remote.origin.push master:master
。现在remote.develop.push trunk:master
有一个设置,不需要使用git push develop
。