Linux内核社区迁移到github?

简介: github是目前最火的开源软件代码托管平台,那么Linux内核社区能否迁移到github上呢?Intel的Daniel Vetter写了一篇关于这个问题的博客,他给出的答案是NO。至于这个答案是否公允,就留给读者自己来判断了。

本文主要根据 http://blog.ffwll.ch/2017/08/github-why-cant-host-the-kernel.html 做了摘要和改编而来。原作者Daniel Vetter是来自 Intel OTC 内核开发。

Daniel 说,这篇文章的写作动机来自两个事情:

其一是在 maintainerati 会议 (一个开源软件维护者的业内聚会) 上的讨论。 Daniel 和几个开源软件维护者讨论了如何扩展真正的大规模开源项目,以及 Github 如何强制项目只能以几种特定的方式来扩展。而 Linux 内核开发恰恰使用了不同的模型,这些正是在 Github 上搞开源的维护者不懂的,因此 Daniel 在讨论中解释 Linux 如何运作,以及 Linux 模型为何不同;

其二是在 Daniel 的另一篇博客 Maintainers Don’t Scale 的评论区里,支持最高的评论就是 “……为啥这些恐龙们不去使用现代的开发工具?“。(其实这个问题曾经在笔者心中也盘旋了很久….) 一些内核社区顶级的维护者,捍卫者传统的邮件列表及布丁的提交方式,抵制使用 Github pull request 的方式。难道真的就是这一小撮掌权者的问题?Daniel 认为不是的。根本原因是,Github 的模式根本支撑不来 Linux 内核这种有着巨大体量的贡献者的开发模式。因此,哪怕是把内核社区的几个子系统移到 Github 上开发都是不可能的。Daniel 说,这不仅和托管 git 的数据有关,而且还和 how pull request, issue 和 fork 这几个 Github 的功能的工作方式有关。(写到这里,我有点儿怀疑这种结论,Github 那么多大型项目,托管整个社区也就罢了,说连个内核子系统都搞不定,就有点儿糊弄人了吧?)

Github 扩展的方式

Git 牛的地方就是让每个人都可以很方便地 fork 开源项目,在其上创建分支。最后一但有了不错的改进,又可以基于上游主仓库创建一个 pull request,并且得到代码的 review,测试,然后被合并。Github 也很牛,因为它把这些 Git 复杂的方式都用 UI 简单化了,易学易用,让新手很容易去为开源项目做贡献。

最终,一个获得巨大成功的开源项目,没办法在一个代码仓库里,能够利用 tagging, labelling, sorting, bot-herding 和 automating 等手段管理好所有 pull request 和 issue,于是就必须通过把单一代码库拆分成多个可管理的部份组成。更重要的是,项目的各部分因为规模和成熟度的不同,需要不同的规则和流程:非常新的实验性质的库,与主线代码相比,有不同的稳定性和 CI (持续集成) 条件。并且,或许项目里还有一大堆过时的,不会被支持的代码,但是目前还不能删除:这需要把非常大的项目拆分成多个子项目,每个子项目都有自己风格的流程,合并条件,独立的仓库,独立的 pull request 和 issue 的跟踪。一般来说,直到管理的开销成为痛点,庞大的重组成为必要时,项目管理可能需要几十甚至几百全职的贡献者。

几乎所有的 Github 托管项目,解决这个问题时,都是靠把单一的源码树,按照功能区分,拆分成许多不同的项目。通常拆分的结果就是,一些核心代码,加上一堆插件,库,和扩展的代码。所有这些通过某种插件或者安装包管理器再构建到一起,在一些情况下,可能就是直接从其它的 Github 仓库里直接拉取代码构建。

因为几乎所有的大项目都是这么搞的,在这里,Daniel 不再赘述它的好处,而是主要把这种做法的缺点指出来了,这里简单摘要如下:

  • 社区被不必要地割裂了。大多数贡献者只有他们直接贡献代码的仓库,忽略掉了项目的其它部份。这个对他们有好处,但是也会导致在不同的子项目里并行的,重复的工作被及时发现,并且共享成果。
  • 项目重构和代码共享存在导致低效的障碍:首先你需要为新代码变更,发布核心项目的新版本,然后过一遍所有的其它子项目的代码,然后更新它们,然后再去删除核心项目里的旧的被共享的代码。
  • 理论上,支持多个子项目版本组合难以为继。必须通过集成测试来保证。
  • 对同属一个大项目的多个子项目重组很痛苦,因为这需要重组 Git 仓库和决定如何拆分。而在一个单一的代码仓库,重组仅仅是把维护者信息文件重新更新一下。

(看到这里,笔者认为,如果一个内部强耦合的代码库,非要因为规模大拆分,是存在这些问题…… 可是确实,项目如果足够大,其实这种耦合关系就可以通过一些流程来规避了。例如,Linux 发行版,不就可以看作是按照上述方式拆分的多个仓库的集合么?当然,Linux 发行版本来就是很多独立开源项目组成的。但是笔者之前工作在 Solaris OS 上,其实就是把弱耦合的项目拆分成多个库了。为了规避接口耦合的问题,才在不同的仓库之间设计了接口稳定性上的约定,如公开接口,私有接口。对公开接口,要支持多版本,EOL 也会存在相应的规则。)

为什么要有 Pull Request?

Daniel 说,Linux 内核是他知道的几个没有像之前所说的那样拆分的项目之一。Linux 内核是一个巨型项目,没有子项目规划的话,也没办法运转。因此,看一下为什么 Git 需要 Pull Request 也是必要的:在 Github 上,Pull Request 是贡献者的代码得到合并的真正方式。但是,内核改动则是通过提交 patch 到邮件列表,甚至在 Git 被内核项目使用之后。

但在 Git 非常早期版本,Pull Request 就被支持了。最初的 Pull Request 的使用者,是内核维护者们,Git 早先就是为了解决 Linus Torvalds 的维护内核的问题的。毫无疑问,Pull Request 非常有必要,而且有用,但是,它不是为了处理独立贡献者的代码改动的:直到今天,Pull Request 被用来转发整个子系统的代码变化,或者同步代码的重构,或者横跨多个子项目之间,同步交割代码的改动。举个例子,在 4.12 网络子系统维护者 Dave S. Miller 的 Pull Request,被 Linus 提交: 这个提交里包含了两千多的,来自 600 个独立贡献者的代码提交,并且还有一堆代码合并和来自下一级维护者的 pull request。但是,这里面所有的补丁,都是从邮件列表里挑选出来,由维护者提交,而不是由原作者提交。Linux 内核流程的古怪之处就是,原作者不提交代码到代码库。这也是为啥 Git 独立地跟踪记录提交者和作者。

Github 的创新和改进就包括了,到处使用 Pull Request,Pull Request 下放给了独立贡献者。但是,这并不是 Pull Request 最早被创造出来的目的。

Linux 内核扩展的方式

初看 Linux 就是一个单体的仓库,所有东西都被塞进 Linus 的主仓库。但是实际上相差甚远:

  • 用 Linus Torvalds 主仓库运行 Linux 的人很少。如果他们运行 upstream 内核,通常都是用稳定内核分支。但更多的是用 Linux 发行版,这些发行版通常会有额外的补丁和 backport,并且甚至不是 kernel.org 托管的,而通常会是完全不同的组织。或者,他们用硬件制造商那里拿到的内核,与主仓库相比,这里常常有非常多的改动。
  • 除了 Linus 自己,没有人直接在 Linus 的仓库里做开发。每个子系统,甚至是大的驱动,有它们自己的 Git 代码库,及自己的邮件列表去跟踪补丁提交和问题讨论,这些子系统都是相互独立的。
  • 跨子系统的工作,是在 linux-next 的集成代码树里做的,它通常包含了上百个 Git 分支,这些分支来自不同的 Git 代码库。
  • 所有的这些都通过 MAINTAINERS 的文件和 get_maintainers.pl 的脚本来管理,它可以告诉任意给定的代码片段相关的一切,谁是维护者,谁是代码 review 者,哪里是 Git 仓库,使用哪个邮件列表,哪里去报告 bug。这个工具不仅仅是根据文件的位置,也通过捕捉代码的一些特征来确定跨子系统的改动,例如,设备树的处理,kobject 的层级结构,都会被合适的专家处理。

Daniel 认为,这种方式有有如下好处 (自然是和前面 Github 上的子项目拆分相比的),摘要如下:

  • 重新组织子项目的拆分超级得容易,只需要更新 MAINTAINERS 文件,随后创建新的 Git 仓库就可以了。
  • 跨子系统的 Pull Request 讨论和问题的讨论,非常非常容易在子项目之间重新分派,只需在邮件回复里增加要 Cc: 的子系统的邮件列表。类似地,做跨子系统的工作,也会非常容易的协同,因为同一个 Pull Request 可以被提交到多个子项目,并且只有一个全局的讨论。
  • 跨子系统的工作,不需要多项目之间任何发布的协同。直接在自己的仓库里修改全部代码即可。
  • 它也不妨碍你创建自己的实验性改动,这是多仓库重要好处之一。直接在自己的 fork 里增加代码就好,没有人强迫你把代码改回去,或者把你的代码放到单一的仓库,因为没有中心仓库。

(说了这么多,Github 唯一的问题就是不支持跨仓库的工作流呗….

Linux 的模式: monotree with multiple repositories

有人可能会质疑,Linux 的模式看起来像是一个,本文开头说过的,有扩展问题的单体代码库。接下来,Daniel 在文章中,花了很多篇幅解释了,Linux 其实是 单体代码树,多个代码仓库 (monotree with multiple repositories) 的模式。

Daniel 还以内核社区的维护者们之间的 Pull Request 工作流为例,说明 Linux 这种模式在 Github 里为啥不行,摘要如下:

简单的场景就是在内核维护者的层级结构中扩散代码改动,直到改动最终落地到了可以最终做软件发布的代码树里。对 Github 来说,这个很容易,直接用 Pull Request UI 就可以做到。

更有意思的是,跨越多个子系统的改动,因为 Pull Request 的工作流会成为一个无环图及其变体组成的 Mesh 网格。第一步是让代码改动都被所有子系统的维护者 Review 和测试。在 Github 工作流里,这个将是一个 Pull Request 同时提交到多个代码库,只要有一个单一的讨论线索,并在所有的仓库里共享。在内核社区里,这个是靠补丁同时提交给一大堆邮件列表和维护者来实现的。

内核这种 Review 方式,通常还不是代码最终合并的方式。而是在所有其它子系统维护者同意的情况下,多个子系统其中的一个被确定为接受 Pull Request 的方式。通常,被选的子系统是受到改动影响最多的子系统,但是有时候,也可以是因为某个子系统正在做的工作与这个 Pull Request 有冲突。有时候,还可以是一个全新的代码仓库和其维护者被确立。这通常发生在改动的功能跨越了整个代码树,不是很容易地在一个地方,一个目录下的被一些文件囊括的情形。最新的例子就是 DMA mapping tree (DMA 映射项目的代码树),该项目试图将各种驱动,平台维护者,还有处理器架构支持的改动都在一个项目里完成。

但是,有时候,多个子系统的代码改动存在冲突的情况,导致它们都需要不小的努力去解决合并冲突。在这种情况下,这种跨子系统的补丁,通常不能直接被接受 (相当于一个 Github 上的 rebase 的 Pull Request),而是 Pull Request 经过修改,使这些补丁对所有子系统都通用,然后再合并到所有子系统。为了避免无关的改动影响到某个子系统,共同的基线是非常重要的。由于这种 Pull Request 是为了一个特定的 Topic 而存在的,这些代码分支也通常被叫做 Topic 分支。

Daniel 还举了微软公司的 OS 项目的例子,说它是一个单体代码树。并且根据他和微软的人交流,这个代码树大到需要微软写一个 GVFS 的虚拟文件系统来支持更高效的开发。(笔者认为,这个例子略有些不恰当,微软的 OS 不光有内核,还有用户态的许多其它代码,而这里的内核代码树就是内核代码,从更全局和更平等的 Linux 发行版的角度看,Linux 发行版其实是多个代码树了…….. 恰恰是 Daniel 在前面抨击 Github 上用多代码树划分子项目的方法……)

亲爱的 Github,轮到你了…

很不幸的是,Github 不能支持前面讨论的跨子系统的工作流,至少在原生的 UI 是不能的。当然,这些工作可以用原始的 git 命令完成,但是不得不回到通过邮件列表发 patch 的方式,Pull Request 也得回到邮件,然后手工合并。在 Daniel 看来,这是唯一的原因,为什么 kernel 社区不能搬到 github 上。也还有一些小问题 (真的是小问题么?),一些顶级的维护者对 Github 极度地反对,但这个不是一个技术问题。并且,不只是 Linux 内核,它是所有巨型的 Github 项目要扩展所面对的一般问题,因为 Github 没有给他们一个扩展到多个仓库,但是保持一个单体代码树的选择。

简而言之,Daniel 提出了一个他认为简单的新特性需求给 Github:

请支持 Pull Request 和 issue 跟踪管理跨多个不同的,基于单体代码树的代码仓库。

非常简单的想法,但是有巨大的影响。

Daniel 不但给出了核心想法,还给出了一些建议的细节,摘要如下:

仓库和组织

首先,需要支持同一个组织可以拥有同一个代码库的多个派生仓库。以 git.kernel.org 为例,上面大多数代码库不是个人的。

在一个代码库里使用多个分支不能替代这个需求,因为之所以要拆分代码库,主要就是想让 Pull Request 和 issue 彼此隔离。

还有就是,需要可以基于既成事实(历史)去建立代码库派生关系。对新项目来说,这个不是问题。但以 Linux 搬迁为例,这是个问题:一次要把 Linux 所有子系统都搬过来,并且,Github 上已经存在大量的 Linux 代码库,彼此间没有正确的 Github 派生关系。

Pull Request

Pull Request 需要能同时提交到多个代码库,但是还可以保一个讨论线索。一次提交给所有代码库以外,还要能够重新指派 Pull Request 到某个代码库的不同分支。

并且,Pull Request 的状态需要因每个代码库而不同。一个代码库的维护者或许关闭了这个 Pull Request 而不去合并,因为维护者们一致同意其中一个子系统拉取这个 Pull Request,而那个维护者将会合并和关闭 Pull Request。另一个代码树或许要按照无效的请求去关闭这个 Pull Request,因为这个 Pull Request 不适合这个旧版本的代码库,或者某个特定厂商的派生代码库。甚至更有意思的是,一个 Pull Request 或许会被合并很多次,在每个子系统的代码库里,且使用不同的合并提交 (Commit ID)。

Issues

和 Pull Request 类似,问题跟踪也需要按照多个代码库隔离,且需要有移动的能力。一个例子就是,一个 bug 可能先报告给了一个发行版的内核代码仓库,然后经过 bug 分析,这个驱动的 bug 也在最新的开发分支存在,因此这个 issue 不但和这个代码库有关,还需加上主线 upstream 分支,或许更多的代码仓库。

Issue 状态应该在不同代码库独立,因为一次在一个仓库的 push,不会理解在所有的仓库可用。甚至,backport 到老内核和发行版,可能需要更多的工作,而一些代码库可以决定不值得修这个 bug,以 WONTFIX 关闭这个 bug,但是同时在其它代码库里它标识为成功解决。(笔者之前的公司,这些功能都有啊。的确这是一个商业软件的缺陷跟踪系统必须有的功能)

总结: 单体代码树,不是单体代码库 (Monotree, not Monorepo)

Linux 内核没打算搬到 Github 上去。但是在 Github 上支持搬迁“单体代码树,不是单体代码库”这种类型的项目到 Github 上,将会是对所有存量的巨型项目非常大的好处。

Tradeoff 无处不在

Daniel 的文章到此为止,接下来是笔者谈一谈自己的看法,一家之言,仅供参考。

首先,因为 Github 的设计问题,把紧耦合的代码库强行拆分成多个子项目确实是一个大问题。但是,对原本就是松耦合的代码之间,拆分的好处也是明显的。大家可以按照各自的方向,节奏,去开发和维护。广义的看,Glibc 和 Linux 内核的关系就是这样,之所以运转良好,稳定的系统调用接口是关键。因此,代码库的划分边界应该以是否存在稳定的协议和接口为前提。

其次, Github 作为世界上最大的同性社交平台, 解决的是个体开源程序爱好者的需求问题。因此,在管理模型上,Github 不支持“单体代码树,不是单体代码库” 这种大型开源项目需要的模式也不奇怪。作为产品的定位来说,或许当前 Github 的设计,正是它成功的一个原因。正是它才让 Git 从少数 Linux 内核开发者手里迅速传播到整个程序员群体。

最后,以 KISS (keep it simple stupid) 的原则看,对主流用户足够傻瓜化,是 Github 的最大优势。但随着 Github 的影响越来越大,越来越多的企业和组织开始在其上托管项目,或许 Daniel 的建议值得认真考虑?至少,企业用户才有可能付出真金白银呢。

看来,不单在技术上我们面临各种 tradeoff,在产品的发展方向上,也是一样的。谁知道这篇文章所诟病的 Github 的缺点,不是当初 Github 产品经理的深度思考后的决定呢?而 Daniel 的建议,说不定又是新形势下满足大企业需求的一个需要呢?

原文链接
本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512451.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

表单提交连续点击html,通过提交“点击”触发器提交两次HTML表单

对于发布类似于SO近100个问题的问题,我很抱歉。我读了很多,尝试了几个解决方案,但无法解决我的问题,或者完全将答案与我的问题联系起来。通过提交“点击”触发器提交两次HTML表单我有一个form与一个动作,键入帖子。我有…

mybatis转义反斜杠_mybatis参数格式化异常:NumberFormatException: For input string:xx

使用mybatis注解开发的时候,总会遇到很多问题,但是mybatis的注解并不是那么的美好,一些问题或者错误根本不能给出准确的定位,有时候,甚至会给出Unknow Source的错误,获取就是一个关闭标签没有关上。此类问题…

如何避免出现SQL注入漏洞

简介: 本文将针对开发过程中依旧经常出现的SQL编码缺陷,讲解其背后原理及形成原因。并以几个常见漏洞存在形式,提醒技术同学注意相关问题。最后会根据原理,提供解决或缓解方案。 作者 | 阿里云安全团队 来源 | 阿里技术公众号 ‍‍…

「CSDN 2021年度 IT 技术影响力之星评选」活动报名倒计时!

“CSDN 2021年度IT技术影响力之星评选”活动自2021年12月6日启动以来受到了行业各界的关注以及企业和个人的积极响应,截止目前,已收到上千份参评报名。本次评选活动的第一阶段——企业/个人参与提名将于2022年1月30日结束,以真实数据为基础&a…

技术人员的一点产品思维思考

简介: 作为一线的开发人员,大家是不是都经历过和产品吵得不可开焦,甚至最后谁也无法说服谁,最后只能由老板出面解决的经历。而大多数情况老板还真能以某种方法去解决,并且是一个双方都能接受的方案。然而这不全是因为老…

北语18春《计算机网络技术》作业4,北语18春《计算机网络技术》作业4

------------------------------------------------------------------------------------------------------------------------------ (单选题) 1: 在数据链路层对局域网进行扩展使用的是_,它根据MAC帧的目的地址对收到的帧进行转发。A: 转发器B: 集线器C: 网桥D:…

chrome插件上传csv_Chrome插件推荐

从 IE 到 Chrome ,期间使用了很多浏览器,搜狗、360、2345、傲游等等,最后选择了 Chrome ,一直到现在,在使用的过程中发现一些好用的插件(扩展程序),在此推荐给大家。PS:使…

OpenKruise v0.10.0 版本发布:新增应用弹性拓扑管理、应用防护等能力

简介: 阿里云开源的云原生应用自动化管理套件、CNCF Sandbox 项目 -- OpenKruise,今天发布 v0.10.0 新版本,这也会是 OpenKruise v1.0 之前的最后一个 minor 版本。 本文将带你一览 v0.10.0 的新变化,其中新增的 WorkloadSpread、…

极验创始人吴渊:恶意流量威胁新趋势,洞察网络黑产3大核心本质

天下没有免费的午餐,更没有免费的流量。以电商为例,最疯狂的时候,某电商平台单个获客成本接近400元。作为互联网的稀缺资源,流量的成本不断冲击着企业运营红线。 而就当企业盯着成本、守着转化时,网络黑产已完成对平台…

来啊,来魔改啊,人生重开模拟器一键托管上线

简介: 云开发平台将“人生重开模拟器”fork到了云开发的仓库了,用户只需要直接fork到自己的仓库以后就可以在云开发平台上进行快速魔改和一键部署,绑定自己的域名就能够让小伙伴们一起来感受你的魔改创意哦。 人生无法重来,游戏可…

内大计算机学院,内蒙古大学:计算机学院

计算机学院是全区高等学校中最早建立的专门培养计算机专业技术中高级人才的教学与科研单位。学院由计算机科学系、软件工程系、信息工程管理系、计算(实验)中心等教学单位组成,设有计算机网络与信息安全、人工智能与蒙古文信息处理、计算机软件与理论和管理科学与工…

python动态类型的坑_python进阶教程之动态类型详解

动态类型(dynamic typing)是Python另一个重要的核心概念。我们之前说过,Python的变量(variable)不需要声明,而在赋值时,变量可以重新赋值为任意值。这些都与动态类型的概念相关。动态类型在我们接触的对象中,有一类特殊的对象&…

从边缘到云,万物互联时代Aruba的技术经

作者 | 宋慧 出品 | CSDN 云计算 网络,是重要的 IT 基础设施之一。在 2021 年底,国际分析机构 Gartner 发布了本年度企业有线和无线局域网基础设施魔力象限,HPE 旗下公司 Aruba 连续第十六年被列入领导者象限。更早一些的 2021 年 Gartner 广…

Apache Hudi 在 B 站构建实时数据湖的实践

简介: B 站选择 Flink Hudi 的数据湖技术方案,以及针对其做出的优化。 本文作者喻兆靖,介绍了为什么 B 站选择 Flink Hudi 的数据湖技术方案,以及针对其做出的优化。主要内容为: 传统离线数仓痛点数据湖技术方案Hudi…

计算机谭音乐同桌的你,同桌的你_Ava_clover_新浪博客

写这个是因为杨傻傻同学那天让我看他听得那首歌《同桌的你》让本人感受颇多虽然开玩笑的问他“我是你的同桌吗?”但是,我还是很感谢杨傻傻(虽然他非要喊我喊他杨哥,但是我还是喜欢这个名字)回想自己所有的同桌但是真正能够记住的其实也就只有…

表格存储 SQL 查询多元索引

简介: 多元索引是表格存储产品中一个重要的功能,多元索引使用倒排索引技术为表格存储提供了非主键列上的快速检索功能,另外也提供了统计聚合功能。表格存储近期开放了SQL查询功能,SQL引擎默认从原始表格中读取数据,非主…

oom 如何避免 高并发_【面试】如何避免OOM的发生

小编基础薄弱,发的内容不算是抄袭,但也基本都是借鉴,若有不足的地方还望点评。内存泄漏(Out Of Memory)俗称OOM,翻了网上一些资料,发生OOM的情况大致有两种,一种是Activity当中对象的引用故障,另…

好难啊……一个 try-catch 问出这么多花样

作者 | 阿Q来源 | 阿Q说代码刚刚面试回来的B哥又在吐槽了:现在的面试官太难伺候了,放着好好的堆、栈、方法区不问,上来就让我从字节码角度给他分析一下try-catch-finally(以下简称TCF)的执行效率.....今天我们就来好好…

数据是如何被保护的?高质量存储告诉你

简介: 作为关键信息基础设施运营者,阿里云提供了全方位的数据安全保护方案。今天,我们就从数据存储的角度来聊一聊数据是如何被保护的。 原文链接 本文为阿里云原创内容,未经允许不得转载。

无法启动此程序因为计算机丢失dtlui,电脑缺少dll文件_电脑开机总是出来DLL文件丢失,...

最佳答案如果您的电脑开机出现“加载C:/WIND/SYSTEM32.UKWIEG96.DLL时出错”之类的加载dll文件出错或提示dll文件丢失,但又可以正常进入系统,那么这篇文章或许可以给您带来解决办法。碰到这种情况我们可以肯定是dll因为某些原因出错或丢失了&…