TL;DR summary
Git fetches from one remote when you run "git fetch" with no additional arguments. When running "git merge" or "git rebase" with no additional arguments, Git uses a name based on the "merge" setting under the "branch" section. Running "git pull" with no additional arguments runs "git fetch" followed by either "git merge" or "git rebase".
Long
The "merge" setting under each "branch" section is the least obvious of the three settings mentioned. The Git documentation is not very clear about it, so let's start with the other two.
Settings under a "[remote "..."]" section
有很多可能的设置。通常情况下,你不需要直接用git config
来设置它们——几乎所有这些设置都有包装命令以更“用户友好”的方式进行设置。这包括您在此处看到的两个设置。很少需要更改这些设置。
每个命名远程主机(例如origin
)的remote
部分列出了git fetch
的URL(和可选的单独推送URL),以及其他remote.*
配置项,如《git config》文档中所述。它还有一个或多个fetch
行,为从该远程主机进行git fetch
提供默认的refspec参数。
也就是说,如果你运行:
git fetch origin
Git会查找remote.origin.url
以确定连接位置,然后连接到该位置,并根据所有remote.origin.fetch
条目检索引用。这里看到的默认设置:
+refs/heads/*:refs/remotes/origin/*
告诉Git将远程仓库的所有分支1复制到你自己的仓库中,重命名为以origin/
为前缀的远程跟踪分支2,因此:
git fetch origin
基本上会获取所有内容。(前导的+
表示Git应该无论远程跟踪分支更新是否为快进操作都执行此操作。也就是说,它类似于使用--force
,但无需指定--force
。)
另一方面,如果你运行:
git fetch origin a:b c:d
Git将完全忽略所有的“fetch=”行,仅从远程检索引用a和c,并将它们写入存储库中的引用b和d。由于这既没有“+”也没有“--force”,因此这些引用都不会被强制更新 - 虽然在大多数情况下这没有任何区别。参考是一个泛指词,涵盖分支和标签(以及其他更多的内容)。分支名称如master只是以refs/heads/开头的引用的简称。Remote-tracking分支名称(origin/master)只是以refs/remotes/开头的引用的简称。请注意,origin/部分来自fetch =行,但为了使所有这些正常工作,该行必须匹配方括号中的remote名称。在[branch "..." ]部分下的设置有很多可能的设置。通常,您不需要使用git config直接设置它们 - 几乎所有这些设置都有包装器命令以更加“用户友好”的方式设置它们。其中包括您在此处看到的两个设置。远程部分本身非常清晰:它意味着如果您在分支master上运行git fetch而根本没有给出远程名称,则Git应该从名为origin的远程获取。合并部分比较棘手。它列出了一个分支的名称,正如在远程上看到的那样。它可能应该是refs/remotes/origin/master,但是这个设置比远程本身还要早。因此,它没有列出引用的完整名称,而是列出了在远程上显示的引用的全名。
这个设置会在你运行 git merge
或者 git rebase
时,没有提供分支名字的情况下使用。Git 通过 fetch =
行提供的映射来确定它应该合并哪个分支,例如它会合并到 origin/master
。
这个设置也被 git pull
命令使用,这个命令实际上等同于运行 git fetch
然后运行 git merge
你可能需要更改这些设置中的一个或两个。例如,如果你创建了一个新的本地分支 feature/tall
,它可能根本就没有设置branch.feature/tall.remote
和 branch.feature/tall.merge
。
因为你刚刚创建了这个分支,所以没有origin/feature/tall
。位于 origin
的 Git 还没有 feature/tall
,所以你没有它的副本。
然后你可以运行 git push origin feature/tall:feature/tall
让你的 Git 调用 origin
的 Git,并让他们的 Git 创建 那个分支,这样你现在就有了 origin/feature/tall
。你可能想让你的 Git 记住这个设置。
你可以运行两个 git config
命令,但是相反地,你可以运行一个更高级别的包装器命令:
git branch --set-upstream-to=origin/feature/tall feature/tall
这会告诉Git将branch.feature/tall.remote
设置为origin
,并将branch.feature/tall.merge
设置为refs/heads/feature/tall
(即origin
上的名称)。
您可以使用git push -u
将git push
和git branch --set-upstream-to
步骤组合在一起,这样更好。但重点仍然是:您使用一个包装器同时设置两个值,因为仅设置一个值不是那么有用。4
特殊的远程名称.
表示此存储库(而不是某个远程存储库)。如果[branch "xyzzy"]
部分说remote = .
和branch = refs/heads/whatever
,则分支xyzzy
具有本地分支whatever
作为其上游,而不是以origin/whatever
为其上游。
3 这故意忽略了很多琐碎的细节。
4 仅设置remote
部分确认会影响到未来的git push
,但是git merge
和git rebase
无法进行远程跟踪分支映射而没有这两个条目。