Git分支实际上是Git克隆吗?


817

我不断听到人们说他们在用Git编写代码。Git“ fork”听起来像Git“ clone”,加上一些(毫无意义的)放弃未来合并的心理意愿。Git中没有fork命令,对吗?

GitHub通过在其上装订对应关系使分叉更加真实。也就是说,您按下派生按钮,然后再按下拉取请求按钮时,系统足够智能,可以向所有者发送电子邮件。因此,这是关于存储库所有权和权限的一点点舞动。

是/否?对GitHub的任何焦虑都将Git扩展到这个方向?还是有关Git吸收功能的传言?


10
是的,它只是github数据库跟踪的一种克隆类型。
圣保罗Ebermann

15
GitHub不会做一些特别的事情来避免存储需求翻倍吗(在GitHub自己的服务器上)?
基思·汤普森

18
尚未提及:删除私有存储库将删除其所有fork。删除公共存储库将保留分支,但会将一个存储库升级为新的父存储库。如果老板将您的公共存储库设为私有,那么它将破坏所有现有的分支,您将无法从它们向私有存储库发出请求请求。help.github.com/articles/…–
柏拉图

我相信(由于GitHub没有向我们证明这一点而没有证据),这里的实际机制是Git的“替代”。换句话说,fork是与之--reference使用的镜像克隆。完全不清楚如何处理公共回购和删除(将替代品移至随机选择的提升存储区吗?将所有分叉指向不属于原始分叉的某个常见替代品?),但是使用替代品可以解释各种可观察到的行为。
torek '19

Answers:


925

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

在本地工作站上克隆GitHub存储库时,除非明确声明为“贡献者”,否则您无法向上游存储库作出贡献。那是因为您的克隆是该项目的单独实例。如果您想为该项目做出贡献,可以通过以下方式使用分支:

  • 在您的GitHub帐户上克隆该GitHub存储库(即“叉子”部分,在服务器端进行克隆)
  • 将提交内容提交到该GitHub存储库(位于您自己的GitHub帐户中,因此您有权将其推送到它)
  • 向原始GitHub存储库发出任何有趣的贡献(通过您在自己的GitHub存储库上所做的更改来表示“拉取请求”部分

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

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

叉子和上游

在Git 2.20(2018年第四季度)及更高版本中,使用delta岛从fork取数据更加高效。


6
“当您在本地工作站上克隆GitHub存储库时,除非明确声明为“贡献者”,否则您无法向上游存储库提供内容。” ---“分叉”不是这样吗?请解释。
chharvey

61
@ TestSubject528491不,用叉子,这意味着您正在克隆上游存储库作为自己在GitHub服务器端的存储库。然后,您可以在本地计算机上克隆该新的“ fork”存储库,然后自由地将其回推,因为您是该fork的创建者和所有者。
VonC

9
对我而言,关键点是除非声明您是贡献者,否则您不能从本地副本提交PR 。我很习惯从本地仓库提交PR,但这是因为我总是被标记为贡献者。如果您考虑一下,要提交PR,您必须将分支推送到远程仓库,然后创建PR。我想如果您不希望随便有人在您的仓库上创建分支,那是有道理的。并且您希望他们分叉并以这种方式提交PR。
亚当·泽纳

我已经在其他地方看到了第二种“上游”远程方法,但是直接从“ GitHub-Original”拉到“ GitHub-Fork”不是更直接吗?第二种远程方法似乎在我的Eclipse和eGit设置中不起作用,无法推送到我的“ GitHub-Fork”存储库(无推送)。
威廉·T·马拉德

没关系,这里的信息链接给了我一些见识。作为贡献者,从“ GitHub-Original”拉到“ GitHub-Fork”,然后从“ -Fork”拉到本地计算机是有意义的,但是如果您是所有者,则可能要直接从我的“ -Fork”拉出首先查看,运行测试等,然后再按“-原始”。
威廉·T·马拉德

135

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

“派生”是一个概念,而不是任何版本控制系统特别支持的命令。

最简单的分叉是分支的同义词。每次创建分支时,无论您使用什么VCS,都已“分叉”。这些分叉通常很容易合并回去。

您所谈论的这种派生方式是,一个独立的参与者获取代码的完整副本然后走开,它一定会发生在VCS之外的Subversion之类的集中式系统中。像Git这样的分布式VCS为分支整个代码库和有效地启动新项目提供了更好的支持。

Git(不是GitHub)本身支持以下两种方式“分叉”整个存储库(即克隆它):

  • 克隆时,origin会为您创建一个名为
  • 默认情况下,克隆中的所有分支都将跟踪其origin等效项
  • 从您分叉的原始项目中获取和合并更改非常容易

Git使更改返回到派生源很简单,就像要求原始项目中的某人从您那里拉出,或请求写入权限以将更改自己推回。这是GitHub简化和标准化的部分。

对Github的焦虑会向这个方向扩展git吗?还是有任何关于git吸收功能的传言?

没有焦虑,因为您的假设是错误的。GitHub通过漂亮的GUI和发布请求的标准化方式“扩展”了Git的分叉功能,但并未向Git 添加功能。全库分叉的概念已从根本上融入了分布式版本控制。您可以随时放弃GitHub,而仍然继续推/拉您已经“分叉”的项目。


6
感谢您的出色回答。我只想澄清一下,这意味着,在github上下文之外,我可以X project在计算机上克隆一些内容。如果我在本地进行更改并且没有原始源的写权限,我将通过电子邮件将项目的作者发送给我,以请求拉取。他将创建一个名为gideon的远程目录,该目录将作为我本地副本的网址,并且他可以拉,对吗?
gideon

1
如果您想将更改保存到项目中,则可以将其保存到文件中(例如,使用git format-patch)并将其附加到具有该写访问权限的人的电子邮件中,或者您可以获取自己的托管服务,将您的工作推送到该位置并通过git request-pull命令以电子邮件形式发送URL。通常无法直接在工作站上访问工作站上的仓库。
bdsl

但是,是的,如果您的工作站碰巧可以由项目的作者通过Internet访问,那么您只需将URL发送给他们,他们就可以将其添加为远程对象并从中提取。
bdsl

1
回复:焦虑,对我来说唯一这样的是,没有链接或按钮可以单击以创建一个“我的仓库”透视图按钮,GitHub告诉您落后50个提交。现在,我知道他们使用术语“ Pull Request”来包含从上游到您的GitHub fork的请求也就不足为奇了。Git很难。
威廉·T·马拉德

80

是的,fork是一个克隆。之所以出现,是因为,未经他人允许您不能将其推入他人的手中。他们为您制作了一个副本fork),您还将在其中拥有写权限。

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


我可以简单地将存储库克隆到本地计算机上,创建一个分支,然后向原始所有者提交拉取请求吗?在整个GitHub上托管多个repos副本似乎只是多余的,只是为了方便代码更新。
Casey 2015年

4
@Casey您只能从GitHub本身通过GitHub发送请求请求,并且只能从GitHub上存在的分支发送GitHub请求请求。如果您不是相关存储库上的合作者,则无法创建分支以从中发起GitHub拉取请求。没有什么可以阻止您以老式的方式通过电子邮件完成此操作的,但是GitHub没有参与其中。
Beau Simensen

2
@Casey,原因是通常其他人无法访问您的工作站。GitHub fork意味着GitHub服务器上有您的工作副本,您可以访问该副本push,其他人也可以访问URL,以便他们可以pull。这pull request只是将副本的URL(在GitHub上)获取到他们的标准方法,因此他们可以轻松地将其拉到其存储库中。
Jesse Chisholm

这应该是我相信的正确/可接受的答案。想象一下一个场景,一个由15至20名开发人员创建分支并将其推向原始位置的团队与15至20名拥有自己的相同存储库副本并进行尽可能多的分支并进行更改并将其推回的开发人员的场景。然后,原始存储库的作者只能提取他/她想要的更改。
Kishor Pawar

37

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


2
具体来说:“复制他们的代码,on the GitHub server以便我可以添加自己的修改and others can have URL access to my version”。大多数本地工作站不提供URL访问权限,任何人都无法提取。但是,如果您在服务器上推送到分叉,则它们可以具有拉取的URL。
Jesse Chisholm

问题不是一般的分叉,而是有关GitHub的分叉。
reinierpost

26

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


11

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

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


10

我认为fork是其他存储库的副本,但您需要修改帐户。例如,如果您直接在本地克隆其他存储库,则远程对象源仍在使用您从其克隆的帐户。您不能提交和贡献您的代码。它只是代码的纯副本。否则,如果您分叉存储库,它将使用您的github帐户中帐户设置的更新克隆存储库。然后,在您的帐户环境中克隆仓库,您可以提交代码。


10

关于什么是“叉子”,这里存在误解。实际上,派生不过是一组按用户分支。当您推入叉子时,实际上您确实会推入原始存储库,因为这是唯一的存储库。

您可以通过将其推入一个叉子,注意提交,然后转到原始存储库并使用提交ID来进行尝试,您将看到该提交位于原始存储库中。

这很有道理,但远非显而易见(我是最近才偶然发现的)。

当John分支存储库SuperProject时,实际上发生的事情是使用“ John.master”,“ John.new_gui_project”等名称复制源存储库中的所有分支。

GitHub“隐藏”“ John”。从我们这里得到的错觉给我们一种错觉,即我们在GitHub上拥有自己的存储库“副本”,但是我们不需要,甚至也不需要。

因此,我的叉子的分支“ master”实际上被命名为“ Korporal.master”,但是GitHub UI从不显示此信息,仅向我显示“ master”。

无论如何,根据我最近所做的事情,这几乎是我认为可以进行的工作,并且当您仔细考虑时,这是非常好的设计。

因此,我认为Microsoft在其Visual Studio Team Services产品中实现Git分支将非常容易。


亲爱的休,您的回复实际上有一半是不正确的-分支是整个存储库的克隆,从一个用户帐户到另一个用户帐户,以及所有分支和历史记录。提交到分叉时,分叉的原始存储库中没有任何变化。但是,除了您对“ fork”是什么的一些误解之外,现在还有一些好消息:Visual Studio Team服务现在包括“ Fork”功能。;)
Sorin Postelnicu

1
@SorinPostelnicu来源?我倾向于在这里相信Hugh,这是由于个人对fork的经验,这种行为与将其作为存储库的简单副本不一致。例如,删除上游时,将删除派生叉(如对OP问题的评论中所述),并且有时上游在接受拉取请求时会将事情合并到我的派生分支中,而我却没有做任何事情。
土豆

确实确实如此。毕竟,git clone每当有人按下“ fork”按钮时,GitHub真正地建立一个全新的存储库(甚至是一个“裸”的存储库)实在是太愚蠢了-这将是不可思议的存储浪费,并且也可能是攻击的载体。
格雷格·伍兹

7

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

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

因此,如果您必须将某些内容合并回原始存储库,则这是存储库之间的合并,并且肯定需要更高的特权。

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


7
??叉子获得了所有分支,尽管您必须知道在哪里看(提示:)git branch -a
三胞胎

3

简单来说

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

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

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.