为什么在“为git push配置的本地引用”部分中存在分支,但在“为git pull配置的本地分支”部分中不存在

时间:2017-08-06 09:55:14

标签: git version-control push pull

我正在学习git,请阅读“progit 2nd edi”一书。

在“检查遥控器”一节中,作者有以下示例。

enter image description here

我注意到“markdown-strip”分支在“为git pull配置的本地分支”部分中不存在,但是出现在“为git push配置的本地引用”部分中。我想知道为什么会这样。

PS:我理解“git pull”和“git push”是如何工作的。在“为git pull配置的本地分支”中缺少“markdown-strip”分支令我感到困惑。

1 个答案:

答案 0 :(得分:3)

这似乎是一个合成的例子,所以它可能只是一个错误。但是,它也可能是特定配置的副作用,其中本地分支markdown-strip没有上游集。

请记住,任何分支的上游都是一个由两部分组成的设置,您可以使用一个命令进行设置:

git branch --set-upstream-to=<upstream> <branch>

如:

git branch --set-upstream-to=origin/master master

或使用两个单独的git config命令进行相当笨拙的配置:

git config branch.master.remote origin
git config branch.master.merge refs/heads/master

每个分支名称(例如master)可以具有一个上游集,或者它可以具有 no 上游集。 (也就是说,你不能设置两个或更多上游。你可以设置一个remote和两个或更多merge个,git show对它们做一些特别的事情;但这不是正常配置,git branch --set-upstream-to不能也不会这样做。)

要以正常方式移除上游,请使用git branch --unset-upstream。下面,我做了一个异常的方式,虽然对git remote show origin的影响是相同的。 (我删除了编辑器中的两个设置之一,因为这样我就可以在编辑器中撤消删除,这比输入git branch命令更容易。当然我现在花了更多的时间来解释这个而不仅仅是按照正常的方式去做。:-))

任何本地分支的上游可以是另一个本地分支,但更常见的是Git称之为远程跟踪分支。 1 你不要# 39; t通常需要或需要取消设置上游。您有时希望设置上游,但是如果您使用普通方法,则在第一次推送该新分支之前,您无法为新分支设置上游:< / p>

$ git checkout -b newbr
... the usual stuff here ...
$ git commit
$ git branch --set-upstream-to=origin/newbr

此抱怨并失败,因为origin/newbr尚不存在,因为我们在本地创建了newbr但尚未将其推送到origin,因此我们的存储库中没有origin/newbr。一旦我们执行运行git push origin newbr,就会在原点上创建newbr。这反过来创建我们自己的origin/newbr来记住我们刚刚在原点上创建的newbr,并且哇! - 现在我们最终可以将origin/newbr设置为newbr的上游。

我认为在这种情况下,Pro Git作者有一个存储库,他们在本地创建了一个分支,然后将其推送到远程名为origin,但从未在分支上运行git branch --set-upstream-to。< / p>

一个例子

例如,我的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)

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)

请注意,这仍然声明master pushes to master。事实上, nothing 推送任何,因为origin存储库是只读的。

如果我要运行git push origin master,这个说法只是Git会尝试的内容。在这种情况下,我的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就开始再说一遍。这并不意味着我的master 总是与他们的master合并:这只意味着如果我要运行git pull,他们的master有了新的提交,我的Git将作为git pull的第二步,运行git merge origin/master(或多或少)。 git pull命令使用上游设置来确定要执行的操作。但我从不 2 运行git pull,因为git pull是一个糟糕的工具。

(我总是先git fetch,然后通常检查一下,然后运行git rebase(如果适用),或使用我的git mff别名,这是git merge --fast-forward的缩写。 git rebasegit merge 使用上游设置。git status就此而言 - 所以设置上游甚至非常有用如果你避免git pull。)

1 请记住,像origin/master这样的所谓远程跟踪分支是(a)在您的存储库中(&& #39;根本不是遥远的,它是本地的); (b)只是你的Git记住你的Git在{G}召唤originorigin master上看到的内容的方式origin 1}}&#39; Git。你不能得到&#34; on&#34; origin/master git checkout master让您进入自己的origin分支的方式,这意味着(c)远程跟踪分支甚至不是分支!所以远程跟踪分支(1)不是远程的,(2)记住你的Git在另一个Git上看到的东西,(3)不是分支。名称中只有一个 tracking 中的一个是正确的! : - )

带连字符的表单远程跟踪使这更好,因为它是跟踪远程&#34;上看到的分支的事情。然后整个事情有点意义,但这个名字开始时非常误导。人们认为远程跟踪分支就像一个本地分支,它不是。但这不是最严重的问题:它们曾经被称为远程分支,有些人仍然使用该短语。在任何情况下,这些本地名称和这些远程跟踪名称都只是名称;分支本身是另一个实体。见What exactly do we mean by "branch"?

2 What, never? Well, hardly ever!