13

简介: 处理要维护一组本地更改的上游存储库的长期运行跟踪的最佳实践是什么?

我想让 github 上的分支与上游保持同步,但仍允许清晰地跟踪分支独有的更改。(对于本次讨论,假设upstream指向主项目存储库,并且origin指向我的存储库分支)

想象一下,当上游/主服务器位于 E 时,我有这样的事情,我在其中分叉了一个存储库。

Upstream:
A-B-C-D-E-F


Fork:    
A-B-C-D-E ----- P ------T
         \-L-M-/ \-Q-R-/

分叉存储库后,我创建了两个功能分支(LM 和 QR)来添加我需要的新功能并将它们合并回我的源/主。所以现在我的分支有了上游不存在的改进。

我发现上游有一些有趣的修复,所以我想重新与上游同步。根据我发现的大多数参考资料(git hub fork),推荐的方法是将上游/主服务器合并到您的源站/主服务器并继续您的方式。所以我会发出如下命令:

git checkout master
git fetch upstream
git git merge upstream/master
git push

然后我最终会得到如下所示的存储库:

Upstream:
A-B-C-D-E-F


Fork:    
A-B-C-D-E ----- P ------T-F'
         \-L-M-/ \-Q-R-/

不过,我看到了一些问题。

  1. 我的存储库中实际上没有提交 F,我有 F',它具有相同的内容,但哈希值不同。所以我不能轻易地引用两个存储库之间的提交并且知道我有更改。(考虑到上游可能有不止一个更改并且有自己的一组已合并的功能分支时,它变得更加复杂)

  2. 随着我继续前进并继续这样做,我越来越难以知道我的存储库中除了上游的更改之外还有哪些更改。例如,我可以将其中一些更改提交回上游,同时继续添加我自己的改进。经过多次迭代,查看我的存储库的人如何知道它与上游有何不同?(是否有 git 命令来查找这些更改?)

  3. 与 #2 类似,有人如何在上游找到修复并检查我的 fork 是否包含修复?

我想问题的根源是我无法保证我的存储库在任何给定点都与上游“同步”,因为代码和哈希值不一样。那么,我该如何准确地跟踪变化并避免让自己疯狂地试图保持同步呢?

注意:我曾考虑使用 rebase 来保持我的存储库远离上游,但这有一组完全不同的问题。例如,如果有人通过子模块、分支等引用我的存储库,那么历史重写将破坏他们的引用。此外,我认为我的分支历史不会在 rebase 中幸存下来,因此我无法完整查看我创建的所有功能分支和相关历史记录。

其他人如何处理这个问题?我应该研究哪些最佳实践?


更新:

根据 Seth 的反馈,我创建了一组测试存储库来展示我在说什么以及它是如何按照他所说的方式运行的。

存储库是:

他们应该更清楚地展示当有本地更改时从上游合并的外观。

4

1 回答 1

13

你的假设是不正确的。您在文本示例中说您将运行该git merge命令。如果你真的是这个意思,而不是git cherry-pick(为了记录,git-merge 是这种情况下的最佳实践),那么你的分支中没有得到 F`,你得到 F。也许是一张图片:

在 fetch 之后但在合并之前,您的 repos 如下所示:

Upstream:
A-B-C-D-E-F  [master]


Fork:    /-F                  [upstream/master]
A-B-C-D-E ----- P ------T     [master]
         \-L-M-/ \-Q-R-/      [Other branches]

合并后,您的 repo 将如下所示:

Fork:    /-F-------------\    [upstream/master]
A-B-C-D-E ----- P ------T-U   [master]
         \-L-M-/ \-Q-R-/      [Other branches]

你的仓库中的新提交“U”将是一个合并提交,就像提交“P”和“T”一样。

git cherry-pick如您在示例中所示,将创建“F'”。不要那样做。 git rebase有时可以支持变基分支git rebase -p,但并不总是有效。此外,这是改写公共历史,这是一个坏主意。

我有一份关于 git 最佳实践的文档:经常提交、稍后完善、一次发布 您可能特别想研究工作流部分以获得更多灵感。

于 2012-07-13T00:21:51.370 回答