git 远程同步分支的过程

Process for syncing branches between git remotes

我正在制作我自己的 git 存储库副本,名为 buildroot。我在免费的 bitbucket 服务器上创建了一份 repo 副本。我正在尝试定期从主线 buildroot 存储库同步我的私人存储库。

我使用

将本地副本下载到我的 PC
git clone https://my_user@bitbucket.org/my_user/buildroot.git

然后我将主线 buildroot 回购添加为远程

git remote add mainline https://git.buildroot.net/buildroot

git remote -v 现在看起来像这样

mainline    https://git.buildroot.net/buildroot (fetch)
mainline    https://git.buildroot.net/buildroot (push)
origin      https://my_user@bitbucket.org/my_user/buildroot.git (fetch)
origin      https://my_user@bitbucket.org/my_user/buildroot.git (push)

我可以从 mainline 远程上的单个分支(例如 master)提取更改,这些更改会在 git push[=23 之后显示在我的 origin 存储库中=]

get pull mainline master
git push

但是,新分支从未出现在我的 origin 存储库中。我是否必须从 mainline 中明确检查每一个,然后推送到 origin 还是有更好的方法来做到这一点?

如下所示,我的私人仓库缺少分支 2018.02.x 和 2018.05.x

git branch -a

* master
remotes/mainline/2017.02.x
remotes/mainline/2017.05.x
remotes/mainline/2017.08.x
remotes/mainline/2017.11.x
remotes/mainline/2018.02.x
remotes/mainline/2018.05.x
remotes/mainline/master
remotes/mainline/next
remotes/origin/2017.02.x
remotes/origin/2017.05.x
remotes/origin/2017.08.x

TL;DR

Do I have to explicitly ... push to origin

是的,但与您的想法不同。不过,这可能是最方便的。

每个 Git 存储库都是一个独立的实体。远程(如在您自己的存储库中)或分支链接(如在 GitHub 或 Bitbucket 分支中)记录另一个 Git 存储库的身份,但这两个存储库仍然是独立的实体。因此,每个分支都有 自己的 分支,不与任何其他 Git 存储库共享。

与其他 Git 存储库共享的内容,但仅限于 "sharing time"(git fetchgit push),是提交。这些是使用它们的原始哈希 ID 共享的。不过,这也是分支名称真正发挥作用的地方,因为 Git 存储库 发现 通过其分支名称(和其他引用,但我们将只关注分支名称在这里)。

请记住,分支名称在 Git 存储库中的作用是包含要考虑的 last 提交的哈希 ID "on"那个分支,即分支的tip commit。当您使用 git checkout <em>branch</em> 后跟最终的 git commit 时,您的 Git:

  • 构建新提交
  • 同时将新提交的 parent 哈希 ID 设置为当前提交哈希 ID
  • 然后将 new 提交的哈希 ID 写入当前 name

以便分支名称再次指向最新的(提示)提交。该提示提交向后指向上一个提示,后者向后指向另一个更早的提交,依此类推。

因此,git push所做的是:

  • 移交一些提交,理想情况下,只需扩展一些现有分支,然后
  • 请求其他 Git 设置 分支名称以记住这些添加的提交的最尖端提交。

(像这样扩展分支是快进操作。)

如果新提交只是扩展一些现有的分支,那些特定的名称更新必须是"forced":另一个Git只会对那些不是快进操作且不是强制的更新请求说不。

但是,不要求这些分支名称值更改对应于您自己的存储库中的任何实际分支名称。例如,考虑一个常见的(至少对我而言)情况,我正在处理某些功能并且我写了六个或更多的提交。其中,我确定其中一个绝对是个好主意,因此我 运行 git rebase -i feature 并将其放在前面。那我可能 运行:

git push origin <hash>:for-review

并根据 for-review 提出拉取请求。如图所示,此时我自己的存储库中的内容如下所示:

...--o--o   <-- origin/feature
         \
          *   <-- origin/for-review
           \
            o--o--o--o--o   <-- feature

六个提交中有五个未被推送;只有一个在此处标记为 *,已推送到 origin 存储库中的名称 for-review。然而,我可以继续在我自己的 feature 分支上的存储库中工作,该分支比 origin/feature 提前六次提交,比 origin/for-review 提前五次提交。我只需要小心记住提交 * 现在是共享的(这很简单:它有一个可以访问它的 origin/ 名称)。

这让我们了解了您必须在自己的存储库中执行的操作,以便将提交从位于 mainline 的 Git 存储库转移到位于 origin 的存储库。首先,您必须从 mainline:

获取提交(及其提示名称)
git fetch mainline

现在你有所有的提交;现在您可以更新 origin 使用,例如:

git push origin mainline/2018.05.x:2018.05.x

这将发送任何 origin 没有但确实需要的提交来完成这项工作,然后在 origin 上创建名称 2018.05.x,指向相同的作为你自己的提交 mainline/2018.05.x.

无可否认,这有点混乱——但重点是您不必为提交指定 分支名称 ,只要您有 some 您(和您的 Git)可以在您自己的存储库中找到提交的名称。要发送那些提交另一个Git,你可以git push他们通过哈希ID,或origin/whatever名称,或者你可以创建一个分支名称,或者做任何你喜欢的事情,只要它标识适当的提示提交。但是,在 lhs:rhs 名称对的右侧,您必须提供 origin 处的 Git 可以创建或更新的名称。

方便

使用 git push(但不是 git fetch!),如果您 运行:

git push origin abc

"means" 与以下内容相同:

git push origin abc:abc

所以在很多方面方便每个分支都有自己的本地名称。