849

我一直听到人们说他们在 Git 中分叉代码。Git "fork" 听起来很像 Git "clone" 加上一些(毫无意义的)心理愿意放弃未来的合并。Git 中没有 fork 命令,对吧?

GitHub 通过在其上装订通信使分叉更加真实。也就是说,你按下 fork 按钮,然后,当你按下 pull request 按钮时,系统足够聪明,可以向所有者发送电子邮件。因此,围绕存储库所有权和权限有点像跳舞。

是/否?对 GitHub 向这个方向扩展 Git 有任何担忧吗?或者有任何关于 Git 吸收该功能的传言?

4

10 回答 10

955

Fork,在 GitHub 上下文中,不扩展 Git。
它只允许在服务器端进行克隆。

当您在本地工作站上克隆 GitHub 存储库时,除非您被明确声明为“贡献者”,否则您无法回馈上游存储库。那是因为您的克隆是该项目的一个单独实例。如果你想为项目做贡献,你可以使用 forking 来做,方式如下:

  • 在您的 GitHub 帐户上克隆该 GitHub 存储库(即“fork”部分,服务器端的克隆)
  • 向该 GitHub 存储库贡献提交(它在您自己的 GitHub 帐户中,因此您有权推送到它)
  • 将任何有趣的贡献发回原始 GitHub 存储库(即通过您在自己的 GitHub 存储库上所做的更改的“拉取请求”部分)

还要检查“协作 GitHub 工作流程”。

如果要保持与原始存储库(也称为上游)的链接,则需要添加一个引用该原始存储库的远程。
请参阅“ GitHub 上的 origin 和 upstream 有什么区别?

分叉和上游

在 Git 2.20(2018 年第四季度)等版本中,使用delta island 从 fork 获取效率更高。

于 2011-06-09T00:37:30.077 回答
142

我一直听到人们说他们在 git 中分叉代码。Git "fork" 听起来很像 git "clone" 加上一些(毫无意义的)心理意愿放弃未来的合并。git中没有fork命令,对吧?

“分叉”是一个概念,而不是任何版本控制系统专门支持的命令。

最简单的分叉是分支的同义词。每次创建分支时,无论您的 VCS 是什么,您都已经“分叉”了。这些分叉通常很容易重新合并在一起。

您正在谈论的那种分叉,其中一个单独的一方获取代码的完整副本然后走开,必然发生在 VCS 之外的中央系统(如 Subversion)中。像 Git 这样的分布式 VCS 对分叉整个代码库和有效地启动新项目有更好的支持。

Git(不是 GitHub)本机支持通过以下几种方式“分叉”整个 repo(即克隆它):

  • 当您克隆时,origin会为您创建一个远程调用
  • 默认情况下,克隆中的所有分支都将跟踪它们的origin等价物
  • 从您派生的原始项目中获取和合并更改非常容易

Git 将更改贡献回 fork 的源代码,就像要求原始项目中的某个人从您那里拉取更改一样简单,或者请求写入权限以自己将更改推回。这是 GitHub 简化和标准化的部分。

对 Github 向这个方向扩展 git 有任何担忧吗?或者有任何关于 git 吸收该功能的传言?

没有焦虑,因为你的假设是错误的。GitHub 使用漂亮的 GUI 和发布拉取请求的标准化方式“扩展”了 Git 的分叉功能,但它没有功能添加到 Git。完全回购分叉的概念从根本上融入了分布式版本控制。你可以在任何时候放弃 GitHub,仍然继续推/拉你“分叉”的项目。

于 2011-06-09T15:59:14.240 回答
84

是的,fork 是一个克隆。它的出现是因为,未经他人许可,您无法推送到他人的副本。他们为您制作了一份副本fork),您也将拥有写入权限。

将来,如果实际所有者或其他具有分支的用户喜欢您的更改,他们可以将其拉回自己的存储库。或者,您可以向他们发送“拉取请求”。

于 2011-06-09T21:12:43.730 回答
39

在这种情况下,“分叉”的意思是“复制他们的代码,以便我可以添加自己的修改”。没什么好说的了。每个克隆本质上都是一个分叉,由原始版本决定是否从分叉中提取更改。

于 2011-06-08T23:51:58.020 回答
27

克隆涉及将 git 存储库的副本复制到本地计算机,而分叉是将存储库克隆到另一个存储库。克隆仅供个人使用(尽管将来可能会发生合并),但是通过分叉,您正在复制并打开一个新的可能的项目路径

于 2011-06-09T00:24:57.017 回答
11

我认为 fork 是其他存储库的副本,但您的帐户已修改。例如,如果您直接在本地克隆其他存储库,则远程对象来源仍在使用您从中克隆的帐户。你不能提交和贡献你的代码。它只是代码的纯副本。否则,如果你 fork 一个存储库,它将在你的 github 帐户中使用你的帐户设置更新来克隆该存储库。然后在您的帐户上下文中克隆 repo,您​​可以提交您的代码。

于 2013-06-04T19:30:37.690 回答
11

当您决定为某个项目做出贡献时,分叉就完成了。您将制作整个项目及其历史日志的副本。此副本完全在您的存储库中制作,一旦您做出这些更改,您就会发出拉取请求。现在由源所有者来接受您的拉取请求并将更改合并到原始代码中。

Git clone 是一个实际的命令,它允许用户获取源的副本。git clone [URL] 这应该在您自己的本地存储库中创建 [URL] 的副本。

于 2014-06-11T18:40:02.073 回答
11

这里对“分叉”是什么存在误解。一个分叉实际上只不过是一组每个用户的分支。当您推送到分叉时,您实际上确实推送到了原始存储库,因为那是唯一的存储库。

您可以通过推送到一个分支来尝试这一点,注意提交,然后转到原始存储库并使用提交 ID,您会看到提交“在”原始存储库中。

这很有意义,但远非显而易见(我最近才偶然发现这一点)。

当 John fork 存储库 SuperProject 时,似乎实际发生的是源存储库中的所有分支都以“John.master”、“John.new_gui_project”等名称复制。

GitHub“隐藏”了“约翰”。来自我们并给我们一种错觉,我们在 GitHub 上拥有自己的存储库“副本”,但我们不需要,甚至不需要。

所以我的 fork 分支“master”实际上被命名为“Korporal.master”,但是 GitHub UI 从来没有显示这个,只显示“master”。

无论如何,这几乎就是我认为基于我最近一直在做的事情的引擎盖下发生的事情,当你思考它时,这是非常好的设计。

出于这个原因,我认为微软很容易在他们的 Visual Studio Team Services 产品中实现 Git 分支。

于 2017-08-26T18:38:05.307 回答
5

除了克隆是从服务器到您的机器并且分叉是在服务器本身上制作副本这一事实之外,一个重要的区别是,当我们克隆时,我们实际上得到了所有的分支、标签等。

但是当我们 fork 时,实际上我们只获取了 master 分支中的当前文件,仅此而已。这意味着我们没有得到其他分支等。

因此,如果您必须将某些内容合并回原始存储库,这是一个跨存储库合并,肯定需要更高的权限。

Fork 不是 Git 中的命令;它只是 GitHub 实现的一个概念。请记住,Git 旨在在点对点环境中工作,而无需与任何主副本同步内容。服务器只是另一个对等点,但我们将其视为主副本。

于 2015-04-23T05:51:32.143 回答
3

简单来说,

当你说你正在分叉一个存储库时,你基本上是在你的 GitHub 帐户中的 GitHub ID 下创建原始存储库的副本。

当您说您正在克隆存储库时,您是在直接在系统(PC/笔记本电脑)中创建原始存储库的本地副本,而您的 GitHub 帐户中没有副本。

于 2018-10-04T12:42:44.790 回答