ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

是的,它只是一种由 github 数据库跟踪的克隆。
GitHub 没有做一些特别的事情来避免存储需求翻倍(在 GitHub 自己的服务器上)吗?
尚未提及:删除私人仓库会删除其所有分叉。删除公共 repo 会保留分叉,但会将一个分叉提升为新的父 repo。如果您的老板将您的公共仓库设为私有,它会破坏所有现有的分叉,您将无法从它们向私有仓库发出拉取请求。 help.github.com/articles/…
我相信(没有证据,因为 GitHub 没有向我们展示这一点)这里的实际机制是 Git 的“替代品”。换句话说,fork 是使用了 --reference 的镜像克隆。究竟如何处理公共回购和删除还不清楚(将替代品移动到随机选择的提升回购品?将所有分叉指向一些不属于原始分叉的公共替代品?)但替代品的使用解释了各种可观察到的行为。

V
VonC

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

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

在您的 GitHub 帐户上克隆该 GitHub 存储库(即“fork”部分,服务器端的克隆)

向该 GitHub 存储库贡献提交(它在您自己的 GitHub 帐户中,因此您有权推送到它)

将任何有趣的贡献发回原始 GitHub 存储库(即通过您在自己的 GitHub 存储库上所做的更改的“拉取请求”部分)

还要检查“Collaborative GitHub Workflow”。

如果要保持与原始存储库(也称为上游)的链接,则需要添加一个引用该原始存储库的远程。
参见“What is the difference between origin and upstream on GitHub?

https://i.stack.imgur.com/cEJjT.png

在 Git 2.20(2018 年第四季度)及更高版本中,从 fork 中获取更高效,with delta islands


“当您在本地工作站上克隆 GitHub 存储库时,除非您被明确声明为“贡献者”,否则您无法回馈上游存储库。” ---这不是“分叉”吗?请解释。
@TestSubject528491 不,使用分叉,这意味着您正在将上游存储库克隆为 GitHub 服务器端的自己的存储库。然后您可以在您的计算机上本地克隆该新的“分叉”存储库并自由推回它,因为您是该分叉的创建者和所有者。
对我来说,关键是你不能从本地副本提交 PR,除非你被宣布为贡献者。我已经习惯了从本地 repo 提交 PR,但那是因为我总是被标记为贡献者。如果您考虑一下,要提交 PR,您必须将分支推送到远程仓库,然后创建 PR。我想如果你不希望随机的人在你的 repo 上创建分支是有道理的。并且您希望他们分叉并以这种方式提交 PR。
叉子是 clone --bare 还是 clone --mirror
服务器端(GitHub)上的@theonlygusti 镜像。
A
Al Sweigart

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

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

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

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

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

当您克隆时,会为您创建一个名为 origin 的远程

默认情况下,克隆中的所有分支都将跟踪它们的原始等价物

从您派生的原始项目中获取和合并更改非常容易

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

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

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


感谢您的出色回答。我只是想澄清一下,这意味着,在 github 的上下文之外我可以在我的机器上克隆一些 X project。如果我在本地进行更改并且没有对源的写入权限,我将通过电子邮件向项目的作者发送请求以请求拉取。他将制作一个名为 gideon 的遥控器,这将是我本地克隆的 url,他可以拉,对吗?
如果您想将您的更改贡献给一个项目,您可以将它们保存到文件中,例如使用 git format-patch 并将它们附加到具有写入权限的人的电子邮件中,或者您可以获得自己的托管,将您的工作推送到那个并在电子邮件中发送 URL,例如使用 git request-pull 命令。工作站上的存储库通常不能直接在线访问。
但是,是的,如果您的工作站恰好可以通过 Internet 访问项目的作者,那么您可以简单地将 URL 发送给他们,他们可以将其添加为远程并从中提取。
回复:焦虑,对我来说唯一的问题是没有链接或按钮可以点击来创建一个从我的仓库拉取的按钮,GitHub 告诉你你落后了 50 个提交。没什么大不了的,因为我知道他们使用术语“拉取请求”还包括从上游拉取到您的 GitHub 分支的请求。吉特很难。
P
Peter Mortensen

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

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


我可以简单地将存储库克隆到本地计算机,创建一个分支,然后向原始所有者提交拉取请求吗?在 GitHub 上托管多个 repos 副本似乎是多余的,只是为了方便代码更新。
@Casey 您只能从 GitHub 本身通过 GitHub 发送拉取请求,并且只能从 GitHub 上存在的分支发送 GitHub 拉取请求。如果您不是相关存储库的协作者,则无法创建一个分支,您可以从该分支发起 GitHub 拉取请求。没有什么能阻止你以老式的方式通过电子邮件进行操作,但 GitHub 并没有参与其中。
@Casey,一个 原因 是通常其他人没有 URL 访问您的工作站。 GitHub fork 表示在 GitHub 服务器上存在您的工作副本,您可以push访问该副本,并且其他人确实具有 URL 访问权限,因此他们可以pullpull request 只是将您的副本(在 GitHub 上)的 URL 提供给他们的标准方法,因此他们可以轻松地将其拉入他们的存储库。
我相信这应该是正确/可接受的答案。想象一个场景中的混乱,其中 15-20 名开发人员创建分支并推送到源,而 15-20 名开发人员拥有自己的相同存储库副本并创建尽可能多的分支并进行更改并将其推回。然后原始存储库的作者只能提取他/她想要的更改。
D
Daenyth

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


具体来说:“复制他们的代码 on the GitHub server,以便我可以添加自己的修改 and others can have URL access to my version”。大多数本地工作站不提供任何人都可以拉取的 URL 访问权限。但是,如果您推送到服务器上的分叉,那么他们可以获得拉取的 URL。
问题不是关于一般的分叉,而是关于 GitHub 的分叉。
S
Sam Johnson

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


D
Daniel Shen

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


a
aliasav

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

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


P
Peter Mortensen

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

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

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

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

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

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

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

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


亲爱的 Hugh,您的回答实际上有一半是不正确的——分叉是从一个用户帐户到另一个用户帐户的整个存储库的克隆,以及所有分支和历史记录。当您提交到分叉时,您分叉的原始存储库中没有任何变化。但除了您对“fork”是什么的一些误解之外,现在还有一些好消息:Visual Studio Team 服务现在包括“Fork”功能。 ;)
@SorinPostelnicu 来源?我倾向于在这里相信 Hugh,因为我个人的经验是,fork 的行为方式与它们是存储库的简单克隆不同。例如,当上游被删除时,叉子被删除(正如对 OP 问题的评论中提到的那样),有时上游在接受拉取请求时已经将事物合并到我的叉子的分支中,而我没有做任何事情。
确实,情况似乎如此。毕竟,对于 GitHub 来说,每次有人按下“fork”按钮时,实际上git clone 一个全新的存储库(甚至是一个“裸露的”存储库)是非常愚蠢的——这将是一种难以置信的存储浪费,并且很可能是一次攻击向量也是如此。
P
Peter Mortensen

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

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

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

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


嗯?叉子获取所有分支,但您必须知道在哪里查找(提示:git branch -a)。
P
Peter Mortensen

简单来说,

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

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