从中央仓库创建本地分支的标准方法是什么?

What is the standard way to create a local branch from a central repo?

假设中央仓库有 masterbranch_Abranch_B。 在我的本地工作 space 中,我只有 masterbranch_A.

我想在我的工作中获得一个本地分支 branch_B-space 以一种干净的方式。

即我想从中央仓库的 branch_B 中获取完全相同的内容,仅此而已。

我认为 git checkout -b my_name/branch_B 会这样做。 但是,当我这样做时,我得到了很多冲突,我不知道为什么。

我不想手动解决冲突。我想要的只是从中央回购的 branch_B 中获取完全相同的内容,仅此而已(即丢弃任何本地更改,如果有的话)

您需要执行:

git checkout -b branch_B origin/branch_B

"origin" 是远程存储库的默认名称。要知道正确的名称执行:

git remote -v

第一个git fetch

git fetch 之后,您的本地仓库应该已经从中央仓库获取所有分支,通常称为 origin

这将创建一个名为 origin/branch_B:

的本地远程跟踪分支
$ git fetch
 * [new branch]      branch_B -> origin/branch_B

此远程跟踪分支 origin/branch_B 跟踪 在您的存储库中 从中央存储库获取的最新更改是什么。

你不应该提交给它,所以你需要创建一个实际的分支来处理。


然后git checkout branch_B

然后 git checkout branch_B 应该创建一个自动跟踪 origin/branch_B:

的本地 branch_B
$ git checkout branch_B
Branch branch_B set up to track remote branch branch_B from origin.
Switched to a new branch 'branch_B'

如果你想同时列出你的本地和远程分支,你可以使用git branch -va

你想要的只是git checkout branch_B 即使branch_B不存在。其实关键是不存在,否则git checkout无法创建


不过,在你使用它之前,请花点时间考虑一下:你根本不是 "creating a branch from a central repo"。您不能:您只能在您自己的存储库.

上操作

这似乎是一个没有区别的区别,但它对于理解无数 Git 怪异之处至关重要。 你所做的一切,你所做的,或在你自己的存储库中。

(有点例外的一件事——但不是真的——是 git push。在这里,你把你已经完成的事情 to/in 你自己的存储库,并将它们提供给另一个 Git,它有 its 自己的存储库,然后请求它根据您提供的内容对 its 存储库执行操作。它了到 that Git 做那些事情,到它自己的存储库。)

集中式存储库

在处理中央存储库时,您从 那里获取内容的方法是使用git fetchfetch 命令调用他们的 Git 并向他们请求他们的分支名称和其他此类引用的列表,这为您的 Git 他们的分支提示提交 ID(SHA-1哈希)。您的 Git 然后通过哈希 ID 和任何其他对象(文件,或者技术上 "blobs" 请求任何提交对象,树对象,早期提交及其树和blob 和带注释的标记对象)需要完成提取。然后,您的 Git 将所有这些对象移到 您的 存储库中,作为最后一步, 将它们的所有分支名称重命名为 新的您的 Git 保证不会与您的任何分支名称冲突的名称。

你的 Git 从他们的名字合成的新名字是你的 远程跟踪分支 origin/master 等等)。这些由 git fetch 创建和更新。如果您使用 --prune,或将修剪设置为默认设置,您的 git fetch 操作将从 您的 存储库中删除您不再拥有的任何远程跟踪分支名称在另一个 Git 中有一个相应的常规分支。 (这有时很有用,但不是默认设置,可能是由于历史原因加上 "only useful if there's a lot of branch creation and deletion in the other repo" 方面。)

origin/masterorigin 部分只是 远程 的名称。遥控器只是一个名称——通常是 origin,事实上,因为它是由 git clone 创建的默认值——你的 Git 存储用于 git fetch 的 URL ].这些远程跟踪分支的名称是通过将远程名称放在远程分支名称前面来构造的:因此 master 变为 origin/masterbranch_A 变为 origin/branch_A , 等等。

为什么 git checkout 创建分支

您想要的命令的完整形式是:

git checkout -b branch_B --track origin/branch_B

(假设您的其他中央存储库已归档在 origin 下)。这里的 -b 表示 "create a branch", --track 表示: "I'm going to supply another name that I want you, my Git, to look up in my repository to find a commit hash ID. When I do that, I also want you to do the equivalent of git branch --set-upstream-to once the branch is made." 最后,当然, origin/branch_B 是(已经存在的)远程的名称-跟踪分支。

这被广泛使用,所以 Git 人决定让 git checkout 变得更加聪明:如果你要求 Git 按名称签出一个分支,and 它不存在,git checkout 在从远程跟踪分支名称。 (喔!)也就是说,如果你 git checkout sneeze,你的 Git 会查看是否有 origin/sneezeupstream/sneeze 或其他任何东西。

如果只有一个这样的远程跟踪分支,然后 git checkout被指示创建 本地分支,使用远程跟踪分支的当前哈希 ID 作为起点。

但是快捷方式确实必须完全这样拼写

请注意,git checkout -b branch_B 不会从 origin/branch_B 开始创建新的 branch_B。它只是从 当前提交 开始创建一个新的 branch_B。新分支也 not 设置为跟踪任何远程跟踪分支。这是因为 -b 告诉 git checkout 立即创建分支,因此它永远不会触发 "hey, wait, I don't have an existing branch_B ... maybe I should run some automatic special-case code instead?" 代码。

当然,要使特殊情况代码起作用,您的存储库中必须具有 origin/branch_B。它不会伸出手去在中央存储库中找到它。只有 git fetch 会这样做——只有 git fetchgit push 会调用另一个 Git,使用隐藏在遥控器名称下的 URL。

(事实上,git remote有时也会调用另一个Git,但那是针对其他SO问题。)