Git 中的本地远程跟踪分支何时创建?

When are the local remote-tracking branches created in Git?

在本地 Git 存储库中,此文件夹包含克隆后的 HEAD 文件:

.git\refs\remotes\origin\

当我从远程跟踪分支创建本地分支时,该分支将创建于:

.git\refs\heads

当我将该本地分支上的更改推送到远程存储库时,会在以下位置创建该分支的新副本:

.git\refs\remotes\origin\

那么远程跟踪分支在最初推送到远程仓库时是否首先在上述文件夹中创建?

你不应该关心 分支存储在哪里(因为你应该使用 "advertised" 接口,git branchgit for-each-ref,等等在)。不过 when 问题更有趣。

远程跟踪分支只是 refs/remotes 名称中的一个引用-space。通常还有一个级别添加到此,特别是遥控器本身的名称,因此对于名为 origin 的遥控器,分支将全部落入 refs/remotes/origin.

git clone 命令在您的本地 git 配置文件(针对该存储库)中创建一个 remote 配置条目。假设您告诉 git clone 使用默认的 origin 名称,此配置条目将部分读取:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*

这就是名称-space 的来源:remote.origin 配置条目中的 fetch 行,即来自:

的内容
$ git config --get-all remote.origin.fetch

实际的远程跟踪分支创建发生在几个地方。

最明显的是 fetch(或初始 clone 步骤,其中包括 fetch 的轻微变化)或 git remote update 运行s .这些命令向遥控器询问其引用。匹配一个或多个 fetch 行的那些被复制并根据每个 refspec 的右侧 修改

这意味着,在 git clonegit fetch origingit remote origin update 期间,如果遥控器有 refs/heads/foo(分支 foo),您自己的本地存储库获取相应的 refs/remotes/origin/foo。如果您之前没有,这会创建一个(本地)远程跟踪分支。

(如果您 运行 git fetch 阻止它获取分支 foo,但是,跟踪分支 不会 得到创建。例如,如果您 运行 git fetch origin refs/heads/bar:refs/temp_bar,此提取仅带来 refs/heads/bar。不同版本的 git 将或不会创建或更新 refs/remotes/origin/bar这次:1.8.4 之前的版本不会,但更新的 git 会。所有这些都假定正常的 fetch 配置。)

git push 期间发生了一个不太明显的情况。在这种情况下,当您的本地 git 成功传递对远程 refs/heads 名称-space 的引用时,您的本地 git 也将创建或更新远程跟踪分支,使用与 git fetch 相同的 refspec 映射。 因此,使用默认设置,推送 refs/heads/new 以便 在远程 origin 上创建 分支 foo also 创建一个(本地)远程跟踪分支 refs/remotes/origin/new. (我把它加粗是因为我 认为 这是对我认为你问的问题。)

如果你将--prune添加到git fetchgit remote update命令,它也会同时删除个远程跟踪分支,如果它们现在在遥控器上丢失了——它们可以分辨出来,因为它们从遥控器获得了 all 引用。 (请记住,这与 git push--prune 选项非常不同,后者用于删除远程分支,如 git push --deletegit push :dst。)