在github上跟踪fork上游的最佳实践 [英] Best practice for tracking upstream in fork on github

查看:228
本文介绍了在github上跟踪fork上游的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结:处理长时间运行的上游存储库跟踪的最佳做法是什么?您希望维护一组本地更改吗?



我想保留一个叉在github上与最新的上游,但仍然允许明确跟踪叉的独特变化。 (对于本次讨论,假设上游指向主项目存储库,并且 origin 指向我的仓库分支)



想象一下,当上游/主人在E时,我有这样的分叉存储库。

 上游:
ABCDEF


分叉:
ABCDE ----- P ------ T
\-LM- / \ -QR- /

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



我发现上游有一些有趣的修复,所以我想恢复与上游同步。根据我发现的大多数参考文献( git hub fork ),推荐的方法是合并上游/主人到你的出身/主人,继续前进。所以我会发出如下命令:

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

然后我会看到如下所示的存储库: p>

 上游:
ABCDEF


货叉:
ABCDE - --- P ------ T-F'
\-LM- / \ -QR- /

我看到了一些问题。


  1. 我没有实际上在我的回购中有F提交,我有F'具有相同的内容,但是不同的散列。所以我不能轻易地引用这两个仓库之间的提交,并知道我有一个改变。 (当考虑到上游可能有多个更改并且它有自己的一组特征分支时,它会变得更加复杂)。

  2. 当我移动时继续这样做,对于我来说,越来越难以知道我在存储库中的变化超出了上游的变化。举例来说,我可能会将这些变化中的一部分提交回上游,同时继续添加我自己的改进。经过几次迭代之后,如何看待我的存储库中的任何人知道它与上游的区别? (是否有git命令来查找这些更改?)
  3. 与#2类似,有人会在上游找到修复程序并检查是否我的叉包含修复?


我猜问题的根源是没有办法保证我的存储库与任何给定点的上游处于同步,因为代码和散列不相同。那么,我该如何准确地跟踪变化并避免疯狂地尝试保持同步?



注意:我曾考虑使用rebase来继续重新定义我的存储库上游,但这有一个完全不同的问题。例如,如果任何人通过子模块,分支等引用我的respository,那么历史重写将会破坏它们的引用。此外,我认为我的分支历史不会在rebase存活下来,所以我不会完整查看我所做的所有功能分支以及相关历史记录。



其他人如何处理这个问题?什么是我应该考虑的一些最佳实践?






更新:

根据Seth的反馈,我创建了一套测试存储库,以显示我在说什么,以及如何按照他的说法行事。



存储库是:



他们应该更清楚地显示当上游有何变化时,上游合并的情况。

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



在获取之后但合并之前,您的回购看起来像这样:

 上游:
ABCDEF [master]


分叉:/ -F [上游/主]
ABCDE ----- P ------ T [master]
\-LM- / \ -QR- / [其他分支]

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

  Fork:/ -F ------------- \ [upstream / master] 
ABCDE ----- P ------ TU [master]
\-LM- / \ -QR- / [其他分支]

新提交U 在你的repo中将是一个合并提交,就像提交P和T一样。

git cherry-pick 会创建F',正如你在前面指出的那样充足。不要这样做。 git rebase 有时可以支持rebasing分支 git rebase -p ,但它并不总是有效。此外,这是重写公共历史,这是一个坏主意。



我有一个关于git最佳实践的文档:确保后期完美,发布一次您可能特别想调查工作流程部分以获取更多灵感。


Summary: What are the best practices for handling long running tracking of upstream repositories where you want to maintain a set of local changes?

I want to keep a fork on github up-to-date with the upstream but still allow clear tracking of changes unique to the fork. (for this discussion, assume that upstream points to the main project repository and that origin refers to my fork of the repository)

Imagine I have something like this where I forked a repository when upstream/master was at E.

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


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

After forking the respository I created two feature branches (L-M and Q-R) to add new features I needed and merged them back to my origin/master. So now my branch has improvements that don't exist upstream.

I find that upstream has a couple of interesting fixes so I want to get back into sync with upstream. Based upon most references I have found (git hub fork), the recommended way to do this is to merge upstream/master into your origin/master and continue on your way. So I would issue commands like:

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

Then I would end up with repositories that looks like this:

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


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

There are a couple of problems I see with this though.

  1. I don't actually have commit F in my repo, I have F' which has the same content, but a different hash. So I can't easily reference commits between the two repositories and know that I have a change. (it gets even more complex when considering that upstream probably has more than one change and has it's own set of feature branches that have been merged)

  2. As I move forward and continue doing this it becomes increasingly difficult for me to know what changes I have in my repository beyond what is in the upstream. For example I may submit some of these changes back upstream while continuing to add my own refinements. After several iterations of this, how does anyone looking at my repository know how it differs from upstream? (is there a git command to find these changes?)

  3. Similar to #2, how would someone find a fix in upstream and check to see if my fork contains the fix?

I guess the root of the problem is there is no way for me to guarantee that my repository is in "sync" with the upstream at any given point because the code and the hashes are not the same. So how do I go about tracking the changes accurately and keep myself from going insane trying to keep things in sync?

Note: I had considered using rebase to keep rebasing my repository off upstream, but this has an entirely different set of issues. For example if anyone references my respository through submodules, branches, etc then the history rewrite will break their references. Additionally, I don't think my branch history would survive the rebase so I would not have a complete view of all the feature branches I had made and the associated history.

How do other people handle this? What are some best practices I should be looking into?


Update:

Based upon feedback from Seth, I created a set of test repositories to show what I was talking about and how it works out the way he says.

The repositories are:

They should show more clearly how merging from upstream looks when there are local changes as well.

解决方案

You are incorrect in your assumption. You said in your text example that you would be running the git merge command. If you really meant this, and not git cherry-pick (and for the record, git-merge is the best practice in the situation) then you do NOT get F` in your branch, you get F. Perhaps a picture:

After the fetch but before the merge, your repos look like this:

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]

After you merge, your repo will look like this:

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

New commit "U" in your repo will be a merge commit, just like commits "P" and "T".

git cherry-pick would create "F'" as you indicated in your example. Don't do that. git rebase can sometimes support rebasing branches git rebase -p but it doesn't always work. Also, that is rewriting public history, which is a bad idea.

I have a document on git best practices: Commit Often, Perfect Later, Publish Once You might specifically want to investigate the workflow section for further inspiration.

这篇关于在github上跟踪fork上游的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆