Tho*_*hor 5 git version-control push pull
我目前正在按照“progit 2nd edi”一书学习git。
在“检查遥控器”部分,作者有以下示例。
我注意到“markdown-strip”分支在“为 git pull 配置的本地分支”部分中不存在,但在“为 git push 配置的本地引用”部分中存在。我想知道为什么会这样。
PS:我了解“git pull”和“git push”是如何工作的。令我困惑的是“为 git pull 配置的本地分支”中缺少“markdown-strip”分支。
这似乎是一个综合的例子,所以它可能只是一个错误。但是,这也可能是特定配置的副作用,其中本地分支markdown-strip
没有上游集。
请记住,任何分支的上游都是一个由两部分组成的设置,您可以使用一个命令进行设置:
git branch --set-upstream-to=<upstream> <branch>
Run Code Online (Sandbox Code Playgroud)
如:
git branch --set-upstream-to=origin/master master
Run Code Online (Sandbox Code Playgroud)
或者使用两个单独的git config
命令进行相当笨拙的配置:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
Run Code Online (Sandbox Code Playgroud)
每个分支名称,例如master
,可以有一个上游集,也可以没有上游集。(也就是说,你不能设置两个或更多的上游。你可以设置一个remote
和两个或更多的merge
s,并git show
用它们做一些特殊的事情;但这不是一个正常的配置,git branch --set-upstream-to
不能也不会这样做。)
要以正常方式删除上游,请使用git branch --unset-upstream
. 下面,我用一种不正常的方式来做,虽然效果git remote show origin
是一样的。(我删除了编辑器中的两个设置之一,因为这让我可以在编辑器中撤消删除操作,这比输入git branch
命令更容易。当然,我现在花了更多的时间来解释这一点,而不仅仅是按照正常方式进行. :-) )
任何本地分支的上游都可以是另一个本地分支,但更常见的是 Git 称之为远程跟踪分支。1 您通常不需要或不需要取消设置上游。您有时确实想设置一个上游,但是如果您使用普通方法,则在您首先推送新分支之前,您无法为新分支设置上游:
$ git checkout -b newbr
... the usual stuff here ...
$ git commit
$ git branch --set-upstream-to=origin/newbr
Run Code Online (Sandbox Code Playgroud)
这种抱怨和失败,因为origin/newbr
尚不存在,因为我们创造了newbr
在本地,但还没有推它origin
,所以是没有origin/newbr
在我们的资料库。一旦我们不运行git push origin newbr
,创建newbr
于原点。这反过来又创建了我们自己的origin/newbr
来记住newbr
我们刚刚在原点创建的,而且——哇!——现在我们终于可以设置origin/newbr
为newbr
.
我认为在这种情况下,Pro Git 作者有一个存储库,他们在本地创建了一个分支,然后将其推送到远程 named origin
,但从未git branch --set-upstream-to
在分支上运行。
例如,我用于 Git 的 Git 存储库副本将本地分支master
配置为将其上游设置为origin/master
. 如果我运行git remote show origin
我得到(在通常的早期输出之后):
Remote branches:
maint tracked
master tracked
next tracked
pu tracked
todo tracked
Local branches configured for 'git pull':
master merges with remote master
stash-exp merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
Run Code Online (Sandbox Code Playgroud)
(这stash-exp
是我git stash
很久以前修复错误的地方)。如果我删除行merge = refs/heads/master
从.git/config
与运行git remote show origin
再次,我得到这个:
Remote branches:
maint tracked
master tracked
next tracked
pu tracked
todo tracked
Local branch configured for 'git pull':
stash-exp merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
Run Code Online (Sandbox Code Playgroud)
请注意,这仍然声称master pushes to master
. 实际上,由于存储库是只读的,因此没有任何内容可以推送任何内容origin
。
这种说法仅仅是关于什么的Git会尝试,是我跑git push origin master
。在这种情况下,我的 Git 会调用他们的 Git 并发现我们都有一个名为master
. 然后,我的 Git 会向他们的 Git 建议他们应该将其 设置refs/heads/master
为指向与我的 refs/heads/master
. 他们会拒绝——他们的存储库设置为拒绝这样的尝试——但我的 Git 不知道这一点。
当我删除branch.master.merge = refs/heads/master
设置时,我的 Git 不再说master merges with remote master
. 一旦我把那个设置放回去,我的 Git 又开始说了一遍。这并不意味着 mymaster
总是与他们的 合并master
:这只是意味着如果我要运行git pull
,并且他们master
有新的提交,我的 Git 将作为 的第二步git pull
,运行git merge origin/master
(或多或少)。该git pull
命令使用上游设置来确定要执行的操作。但我从不2 run git pull
,因为它git pull
是一个糟糕的工具。
(我总是git fetch
首先,然后通常检查事物,然后git rebase
在适当的时候运行,或者使用我的git mff
别名,它是 的缩写git merge --fast-forward
。请注意,git rebase
并且git merge
还使用上游设置。因此git status
,就此事而言,设置上游非常有用,即使你避免git pull
。)
1请记住,所谓的远程跟踪分支就像origin/master
是(一)在您的资料库(这不是远程的话,那就是本地); 和(b)仅仅是记住你的Git的方法是什么您的Git锯origin
为origin
的master
是最后一次使用Git调用origin
的Git的。你不能origin/master
像git checkout master
让你进入自己的origin
分支那样“进入” ,这意味着 (c) 远程跟踪分支甚至不是分支!因此,远程跟踪分支 (1) 不是远程分支,(2) 会记住您的 Git 在另一个 Git 上看到的内容,并且 (3) 不是分支。它的名字中的tracking三个词中只有一个是对的!:-)
连字符形式的remote-tracking使这更好,因为它是“跟踪在遥控器上看到的分支”的东西。整个事情就有点意思了,但这个名字一开始就很误导人。人们认为远程跟踪分支就像本地分支,但事实并非如此。但这还不是最糟糕的问题:它们曾经被称为远程分支,有些人仍然使用这个短语。无论如何,这些本地名称和这些远程跟踪名称都只是名称;分支机构本身是另一个实体。请参阅“分支”究竟是什么意思?