GitHub中的分叉与分支


278

我想更多地了解分叉github项目与创建github项目的分支的优缺点。

Forking使我的项目版本与原始版本更加隔离,因为我不必在原始项目的协作者列表中。由于我们正在内部开发项目,因此添加人员作为协作者没有问题。但是,我们想了解分叉项目是否会使合并更改更难回到主项目。也就是说,我想知道分支是否会使保持两个项目同步变得更容易。换句话说,分支时在我的主项目版本和主项目之间合并和推送更改是否更容易?

Answers:


279

因为您尚未注册为该特定项目的协作者,所以您不能总是创建一个分支或拉一个现有分支并将其推回去。

分叉不过是GitHub服务器端的克隆:

  • 无法直接退回
  • 带有添加的分叉队列功能来管理合并请求

您可以通过以下方式使fork与原始项目保持同步:

  • 将原始项目添加为远程项目
  • 定期从原始项目中获取
  • 在您从该获取中获取更新的关注分支的基础上重新构建当前的开发。

通过重新设置基础,您可以确保更改简单明了(没有要处理的合并冲突),当您希望原始项目的维护者在其项目中包含补丁程序时,可以更轻松地执行拉取请求。

目标实际上是允许协作,即使不一定总是可以直接参与。


您在GitHub端进行克隆的事实意味着您现在拥有两个 “中央”存储库(“中央”为“对多个协作者可见”),
如果您可以将它们直接添加为一个项目的协作者,则无需管理另一个一个用叉子。

在GitHub上分叉

合并体验大致相同,但是具有更高的间接性级别(先推入分叉,然后请求拉取,因为原始回购协议有发展的风险,使快进合并不再快进) 。
这意味着正确的工作流程是git pull --rebase upstream(基于上游的新提交重新构建工作),然后git push --force origin,为了以某种方式重写历史记录,您自己的提交始终位于原始(上游)存储库的提交之上。

也可以看看:


3
我们正在内部开发一个项目,将人们添加为协作者没有问题。但是,我们想了解是否分叉一个项目会使合并更改更难回到主项目。
重新编程

7
@reprogrammer:如果可以添加协作者,则不需要分叉。他们可以在本地进行基础调整,然后合并到目标分支上,然后直接推送到一个中央存储库,而不必管理两个中央存储库(原始的一个和分支)。变基将大致相同,但是涉及到fork时会有一个额外的间接寻址。同样:这里不需要。我已经更新了答案。
VonC

14
坦白说,即使您不必这么做,拥有一个神圣的仓库也是一个好主意,该仓库仅适用于高级开发人员,团队负责人或其他“受信任”的人。所有其他团队成员均应使用分叉(〜沙盒)进行工作,并以拉取请求的形式进行更改。由于DVCS使其成为可能,因此我们将其改编为“最佳实践”,即使在最小的项目中也成功地使用了它……
intland 2012年

1
@intland,因此您更喜欢stackoverflow.com/users/6309/vonc?tab=respons中描述的“集成管理器工作流程” ?对于将Git引入大公司而言,我倾向于首先采用集中式工作流程(每个人都比较熟悉),然后再转向“集成管理器”。
VonC '04

15
我们应该将叉子称为“树枝”,因为它们被折断了一个分支,并被用来开始一棵新的树。只是我的两分钱-我喜欢树栖习语。
埃里克(Eric)

66

以下是高层差异:

分叉

优点

  • 使分支按用户分隔
  • 减少主存储库中的混乱情况
  • 您的团队流程反映了外部贡献者流程

缺点

  • 使得查看所有处于活动状态(或与此相关的非活动状态)的分支变得更加困难
  • 在分支上进行协作比较棘手(fork所有者需要将该人添加为协作者)
  • 您需要了解Git中多个遥控器的概念
    • 需要额外的心理簿记
    • 对于那些对Git不太满意的人,这将使工作流程更加困难

分枝

优点

  • 将围绕一个项目完成的所有工作都集中在一个地方
  • 所有协作者都可以推送到同一个分支上进行协作
  • 只有一个Git遥控器要处理

缺点

  • 被遗弃的分支更容易堆积
  • 您的团队贡献过程与外部贡献者过程不匹配
  • 您需要先添加团队成员作为贡献者,然后才能分支

“外部贡献者过程”是什么意思?
卡尔斯·巴伦德雷赫特

1
@KarsBarendrecht更新为使用术语“外部贡献者”。write对该存储库没有权限的人。
艾丹·费尔德曼

45

它与Git的一般工作流程有关。您不太可能直接推送到主项目的存储库。我不确定GitHub项目的存储库是否支持基于分支的访问控制,例如,您不想授予任何人推送到master分支的权限。

一般模式如下:

  • 分叉原始项目的存储库以拥有自己的GitHub副本,然后您可以将其推送到其中。
  • 将GitHub存储库克隆到本地计算机上
  • (可选)将原始存储库添加为本地存储库中的其他远程存储库。然后,您将能够直接获取在该存储库中发布的更改。
  • 进行修改和自己在本地提交。
  • 将您的更改推送到GitHub存储库中(因为通常您不会直接对项目存储库具有写权限)。
  • 与项目的维护者联系,请他们获取您的更改并进行审查/合并,然后让他们推回到项目的存储库(如果您和他们愿意的话)。

没有这个,公共项目让任何人直接推送自己的提交是非常不寻常的。


@RecoJohnson,嗯...我没有在回答中使用“ pull”一词(但在Git术语中,“ pull”实际上是“ fetch” +“ merge”)。您认为“推”的哪一种用法是错误的?
布鲁诺

2
@RecoJohnson您作为贡献者推送到GitHub分支;项目的维护者会从您的叉子中抽出您的资金。
mljrg 2014年

1
我认为,在开源世界中,您不太可能被分配为协作者的假设比在许多使用git的开发团队的组织中更为正确。我认为这是一个很重要的区别,但还不够充分,这可能是为什么gitlab之类的公司之所以兴旺发展的原因,因为他们了解企业的​​需求和控制的需求。
code4cause 17'Jan

8

分叉从现有存储库创建一个全新的存储库(只需在gitHub / bitbucket上执行git clone)

最好使用叉子:当“拆分”的目的是创建一个逻辑上独立的项目时,该项目可能永远不会与其父级团聚。

分支策略在现有/工作存储库上创建一个新分支

最好使用分支:将它们创建为通过要素使用的临时场所时,目的是将分支与原点合并。

更具体:- 在开源项目中,存储库的所有者决定谁可以推送到存储库。但是,开源的思想是每个人都可以为该项目做出贡献。

用fork解决了这个问题:开发人员每次想在开源项目中进行更改时,都不会直接克隆官方存储库。相反,他们分叉它来创建副本。工作完成后,他们发出拉动请求,以便存储库所有者可以查看更改并决定是否将其合并到他的项目中。

从本质上讲,分叉类似于功能分支,但是不是创建分支,而是创建存储库的分支,并且创建合并请求而不是执行合并请求。

以下链接以解释清楚的方式提供了区别:

https://blog.gitprime.com/the-definitive-guide-to-forks-and-branches-in-git/

https://buddy.works/blog/5-types-of-git-workflows

http://www.continuousagile.com/unblock/branching.html


该答案中的“最佳使用”语句似乎忽略了许多阻碍分支工作的问题,例如开源项目,以及在现实世界中如何使用分叉的事实。常见的情况是,将派生与拉取请求结合使用,以使人们可以在一个项目上进行协作,而这些项目都没有直接修改给定存储库的权限。
StriplingWarrior
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.