在GitHub上跟踪派生项目的最佳实践

13
总结:如何处理长时间跟踪上游存储库的最佳实践,以便维护一组本地更改?
我希望保持Github上的分支与上游同步,同时仍然允许清晰地跟踪特定于该分支的更改。(对于这个讨论,假设upstream指向主项目存储库,而origin指的是我对存储库的分支)
想象一下,当上游/主分支处于E时,我分叉了一个存储库,就像这样。
Upstream:
A-B-C-D-E-F


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

在复制仓库后,我创建了两个功能分支(L-M和Q-R),以添加所需的新功能,并将它们合并回我的原始/主分支。因此,现在我的分支具有上游不存在的改进。
我发现上游有一些有趣的修复,因此我想与上游保持同步。根据我找到的大多数参考资料(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. 实际上,我的repo中并没有提交F,而是有一个内容相同但哈希值不同的F'。因此,我不能轻易地在两个repo之间引用提交并知道我有哪些更改。(考虑到upstream可能有多个更改,并且有自己的一组功能分支被合并,情况会变得更加复杂)

  2. 随着我继续前进并继续这样做,我越来越难以知道我在我的repo中有哪些更改超出了upstream的范围。例如,我可能会将其中一些更改提交回upstream,同时继续添加自己的改进。经过几次迭代后,查看我的repo的人怎么知道它与upstream有何不同?(是否有git命令可以找到这些更改?)

  3. 类似于#2,有人如何在upstream中找到修复方法并检查我的fork是否包含该修复程序?

我想问题的根源在于我无法保证我的repo在任何给定时间点都与upstream同步,因为代码和哈希值并不相同。那么我该如何准确地跟踪更改并避免自己为了保持同步而疯狂呢?
注意:我曾考虑使用rebase来保持我的存储库与上游的同步,但这会带来完全不同的问题。例如,如果有人通过子模块、分支等引用我的存储库,那么历史记录重写将破坏他们的引用。此外,我认为我的分支历史记录无法在rebase中得以保存,因此我将无法完整地查看我所创建的所有功能分支及其相关历史记录。
其他人是如何处理这个问题的?有哪些最佳实践值得我去了解?

更新:

根据Seth的反馈,我创建了一组测试存储库来展示我所说的内容以及它按照他的说法如何运作。

这些存储库是:

它们应该更清楚地展示当有本地更改时从上游合并的情况。

1个回答

13
您的假设是错误的。在您的文本示例中,您说您将运行git merge命令。如果您确实是这个意思,而不是git cherry-pick(值得注意的是,在这种情况下,git-merge是最佳实践),那么您的分支不会得到F`,而是得到F。可能需要一张图片:
在获取(fetch)但合并之前,您的存储库看起来像这样:
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]

在合并之后,您的存储库将如下所示:
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最佳实践的文档:经常提交,稍后完善,发布一次。你可能想要特别研究工作流程部分以获取更多灵感。

感谢您的指导。我增加了一个示例来展示它确实会按照您的描述进行操作。现在看起来很显然,但是我错过了合并将上游历史与匹配提交哈希一起引入的重点。还有一个问题:如果我在我的派生分支上,如何轻松找到我与上游不同的所有更改,并以一种让我理解/看到分支具有哪些功能而上游没有的方式进行操作? - Allen
@Allen:git log --graph --decorate --oneline master..upstream/master 根据您的需求,改变两个点分隔参数的顺序或将点的数量改为三个可能会有所帮助。 - Seth Robertson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接