总结:处理对要维护一组本地更改的上游存储库的长期运行跟踪的最佳实践是什么?
我想让 github 上的一个分支与上游保持同步,但仍允许清楚地跟踪该分支独有的更改。 (对于此讨论,假设 upstream
指向主项目存储库并且 origin
指的是我的存储库分支)
假设我有这样的事情,当 upstream/master 位于 E 时,我 fork 了一个存储库。
Upstream:
A-B-C-D-E-F
Fork:
A-B-C-D-E ----- P ------T
\-L-M-/ \-Q-R-/
在 fork 存储库后,我创建了两个功能分支(L-M 和 Q-R)以添加我需要的新功能,并将它们 merge 回我的源/母版。所以现在我的分支有上游不存在的改进。
我发现上游有几个有趣的修复,所以我想重新与上游同步。根据我找到的大多数引用资料(git hub fork),推荐的方法是将 upstream/master merge 到您的 origin/master 中,然后继续您的工作。所以我会发出如下命令:
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',它具有相同的内容,但哈希值不同。所以我不能轻易地引用两个存储库之间的提交并知道我有变化。 (当考虑到上游可能有不止一个变化并且它有自己的一组已 merge 的功能分支时,它变得更加复杂)
随着我继续前进并继续这样做,我越来越难以知道除了上游中的内容之外,我的存储库中还有哪些更改。例如,我可以将其中一些更改提交回上游,同时继续添加我自己的改进。在多次迭代之后,查看我的存储库的人如何知道它与上游有何不同? (是否有 git 命令来查找这些更改?)
与 #2 类似,人们如何在上游找到修复程序并检查我的 fork 是否包含该修复程序?
我想问题的根源在于我无法保证我的存储库在任何给定点与上游“同步”,因为代码和哈希值不相同。那么,我该如何准确地跟踪变化并避免自己为了保持同步而发疯呢?
注意:我曾考虑使用 rebase 来使我的存储库 rebase 到上游,但这有一组完全不同的问题。例如,如果有人通过子模块、分支等引用我的存储库,那么历史重写将破坏他们的引用。此外,我认为我的分支历史不会在 rebase 后仍然存在,因此我无法完整查看我创建的所有功能分支和相关历史。
其他人如何处理这个问题?我应该研究哪些最佳实践?
更新:
根据 Seth 的反馈,我创建了一组测试存储库来展示我在说什么以及它如何按照他所说的方式运行。
存储库是:
它们应该更清楚地展示当本地发生变化时从上游 merge 的样子。
最佳答案
您的假设不正确。您在文本示例中说过您将运行 git merge
命令。如果你真的是这个意思,而不是 git cherry-pick
(并且为了记录,git-merge 是这种情况下的最佳实践)那么你不会在你的分支中得到 F`,你得到 F . 也许是一张图片:
在获取之后但在 merge 之前,您的存储库看起来像这样:
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]
merge 后,您的存储库将如下所示:
Fork: /-F-------------\ [upstream/master]
A-B-C-D-E ----- P ------T-U [master]
\-L-M-/ \-Q-R-/ [Other branches]
您的仓库中的新提交“U”将是 merge 提交,就像提交“P”和“T”一样。
git cherry-pick
将创建“F'”,如您在示例中所示。不要那样做。 git rebase
有时可以支持 rebase 分支 git rebase -p
但它并不总是有效。此外,这是在重写公共(public)历史,这是一个坏主意。
我有一份关于 git 最佳实践的文档:Commit Often, Perfect Later, Publish Once您可能特别想研究工作流部分以获得更多灵感。
关于git - 在 github 上的 fork 中跟踪上游的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11459072/