总结:处理要维护一组本地更改的上游存储库的长时间跟踪的最佳做法是什么?
我想在github上保持与上游最新的分支,但仍然允许清楚地跟踪fork的特有变化。 (对于此讨论,假设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)来添加我需要的新功能,并将它们合并回我的origin / master。所以现在我的分支机构有了上游不存在的改进。
我发现上游有几个有趣的修复,所以我想重新与上游同步。基于我发现的大多数参考文献(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-/
虽然我看到了一些问题。
我实际上并没有在我的仓库中提交F,我有F',它具有相同的内容,但是有不同的哈希值。所以我不能轻易引用两个存储库之间的提交,并知道我有一个更改。 (当考虑到上游可能有多个更改并且已经合并了它自己的一组功能分支时,它变得更加复杂)
当我继续前进并继续这样做时,我越来越难以知道我的存储库中的更改超出了上游的更改。例如,我可以向上游提交一些这些更改,同时继续添加我自己的改进。经过几次迭代后,任何查看我的存储库的人如何知道它与上游的区别? (是否有一个git命令来查找这些更改?)
与#2类似,有人会如何在上游找到修复程序并检查我的fork是否包含修复程序?
我想问题的根源是我无法保证我的存储库在任何给定点与上游“同步”,因为代码和散列不一样。那么我该如何准确地跟踪变化并避免疯狂地试图让事情保持同步呢?
注意:我曾考虑使用rebase来保持我的存储库在上游的重新定位,但这有一组完全不同的问题。例如,如果有人通过子模块,分支等引用我的存储库,那么历史记录重写将破坏它们的引用。另外,我不认为我的分支历史可以在rebase中存活,所以我不能完整地查看我所做的所有功能分支以及相关的历史记录。
其他人如何处理这个问题?我应该研究哪些最佳实践?
更新
根据Seth的反馈,我创建了一组测试存储库,以显示我所说的内容以及它如何按照他说的方式工作。
存储库是:
当有局部变化时,他们应该更清楚地显示上游的合并情况。
答案 0 :(得分:11)
您的假设不正确。您在文本示例中说过您将运行git merge
命令。如果你真的是这个,而不是git cherry-pick
(并且为了记录,git-merge是这种情况下的最佳实践)那么你不会在你的分支中获得F`,你得到F.也许是一张图片:< / p>
在获取之后但在合并之前,您的回购看起来像这样:
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最佳做法的文档:Commit Often, Perfect Later, Publish Once您可能特别希望调查工作流程部分以获得更多灵感。