> * 原文地址：[Why I close PRs (OSS project maintainer notes)](http://www.jeffgeerling.com/blog/2016/why-i-close-prs-oss-project-maintainer-notes)
* 原文作者：[Jeff Geerling](http://www.jeffgeerling.com/)
* 译文出自：[掘金翻译计划](https://github.com/xitu/gold-miner)
* 译者：[cdpath](https://github.com/cdpath)
* 校对者：[Zhiw (Zhiwei Yu)](https://github.com/Zhiw), [Luolc (LoLo)](https://github.com/Luolc)

# 为什么我关闭了你的 PR （开源软件维护者笔记）

![GitHub 上 geerlingguy/drupal-vm 的 PRs 提醒](http://www.jeffgeerling.com/sites/jeffgeerling.com/files/images/github-project-notifications-prs.jpg) 

我在 GitHub 以及类似的平台上维护了许多开源项目（写就本文时有超过 160 个项目）。这几年我合并或关闭了数千个拉取请求（PR）和补丁（patch），这里我想总结一下**不合并** PR 的理由。

我有些项目有共同维护者，但是大部分都是我维护的。我通过授予非常开放的开源协议并鼓励复刻（fork）来弥补[巴士因子](https://zh.wikipedia.org/wiki/%E5%B7%B4%E5%A3%AB%E5%9B%A0%E5%AD%90)较低的不足。。我还投入了固定的时间（平均每周 5 到 10 小时）来维护我的开源软件项目，并且计划每年花一千美元在基础设施上来支持我的项目（很遗憾这已经比大多数用了我的项目的盈利性公司贡献给开源软件的还要多了）。

我并不喜欢不合并就直接关闭 PR，因为 PR 本身就表示有人非常喜欢我的项目甚至愿意做出贡献。但有时候我不得不这样做。我不是想做个混蛋（我通常会先感谢贡献者的付出，好让我关闭 PR 时不会对他造成太大打击），我只是想保证项目能持续健康地发展下去。下面是我维护自己项目时所遵循的原则，真希望读者通过本文可以理解我为什么关闭 PR 而不是合并它。

## 评估 PR 的原则

对于我维护的项目而言（实际上，对于大多数我参与开发的软件而言），我认为以下原则是最重要的。如果 PR 没能遵循这些原则我就会关闭它。

### 所有东西都要经过完整的自动化测试

我维护过的大多数项目都要经过 Travis CI、Jenkins 或其他持续集成系统组成的成功路径（happy path）。[如果你破坏我的测试我会打烂你的脸](https://www.amazon.com/SmartSign-Lyle-K2-0113-AL-12x18-Breaka-Aluminum/dp/B01KIYWD70/ref=as_li_ss_tl?ie=UTF8&amp;qid=1482861696&amp;sr=8-1-fkmr0&amp;keywords=if+you+taka+my+space+i+breaka+your+face&amp;linkCode=ll1&amp;tag=mmjjg-20&amp;linkId=71ba06c689653589697ff5c93c95491f)。除非极个别的情况，我不会合并没有通过全部测试的 PR。如果 PR 新增了大量未经测试的功能，我也不会合并。我不要求 100% 的单元测试覆盖率，但是所有的测试都必须通过。

### 可维护性比完整性更重要

我不会迎合任何人，我通常只迎合自己。我 98% 的开源软件项目都会真正用在生产环境中（差不多有几十甚至几百个项目）。所以我总体上对它们的现状都很满意。我不会随意去加一些东西加重自己的维护负担，除非它是非常有吸引力的功能，或者是一个明显的错误修正。我无法维护一个连自己都无法完全理解的系统，所以我喜欢让东西保持简单，去掉特殊情况而不是引入[技术债](http://martinfowler.com/bliki/TechnicalDebt.html)，我知道我没时间偿还。

### 适用于 80% 的用例

我见过许多为了一次性功能而提的 PR，我个人都没在真实环境中见过这些功能。当然，的确有一些凤毛麟角的系统需要在一些晦涩的应用中配置很多麻烦的细节。但我不打算在我的项目中引入这些代码。首先，我用不到，所以没法保证正确性。其次，这增加了维护成本，哪怕只是「简单」的加法。如果你在用这些罕见的系统，请复刻（fork）我的项目。我没有什么意见！我公开的项目大都用来解决[最常见的问题](https://zh.wikipedia.org/wiki/%E5%B8%95%E9%9B%B7%E6%89%98%E6%B3%95%E5%88%99)；我也试着让别人可以更简单地通过复刻（fork）或者是拓展来进一步开发我的项目。

### 使用规范的语法

通常我会在自动测试系统中内置自动语法检查工具。但是如果我忘了，请确保基本遵从项目的总体风格
，涉及到间距、变量命名规范、断行、[用空格代替 tab](https://www.youtube.com/watch?v=SsoOG6ZeyUI) 等等。我经常需要合并代码之后再去修正代码风格，如果能省了这工夫就太好不过了。我也更愿意合并没有奇怪风格的代码。

### 不要修改架构

（除非事先在 issue 中讨论过。）

我见过将整个项目架构或测试架构都推翻重建的 PR。除非事先在 issue 中进行过全面的讨论（并得到我的同意），否则我永远不会合并这种 PR 。一切都事出有因（而且实际上有**很多**原因）。我不是说我的架构或测试框架永远是**正确**的，但我不会合并那些会引入翻天覆地变化的代码，不然我自己都会难以理解自己的项目。

### 不要在一次 PR 中修改超过 50 行代码

（除非理由充分。）

我收到过太多次 PR 通知然后发现有 12 个提交（commit）修改了 20 个文件的 800 行代码。如果这是上面提到的涉及架构调整的 PR，而且事先在 issue 中讨论过，我会花时间看完所有的修改。可是如果改动超过 50 行，我就没有办法在一个小时内好好地审核完代码。

## 结论：默认就是「拒绝」

在这一过程中最讽刺的事之一，就是那些最固执、烦人、难搞的 issue 和 PR 的发起者在我解决了他们项目中出现的问题之后马上就会消失。他们意识到（通常不那么**直接**）如果他们能说服**我**维护他们的雪花代码（译者注：这个梗来自 No two snowflakes are alike. snowflake code 强调不用大家约定俗成的写法，刻意使用奇葩的写法。），他们就可以摆脱正在折磨他们的技术债。

如果贡献者愿意和项目建立长期的关系，我愿意给他们控制代码架构部分权力。但是他们必须证明我可以信任他们。我的项目中最好的一些贡献者正是那些在自己的盈利性工作中使用这些项目的人，但是他们每周会贡献一到两小时帮助整理 issue 队列，关闭无效的 issue，提 PR 修正简单的错误（尤其是那些他们最为熟悉的项目）。

我要对任何维护开源软件项目的人说：要保证自己有一套完整的评估 PR 的原则。要对不能符合原则的 PR **坚决说不**。有太多项目偏离正轨的原因就是接受了太多新特性却没有考虑到长期的可维护性，这个问题非常容易解决，说不就行了。
