vlambda博客
学习文章列表

对挖掘GitHub的前景和风险的深入研究

摘要: GitHub拥有超过1000万个git存储库,正成为互联网上最重要的软件产品来源之一。 研究人员挖掘存储在GitHub事件日志中的信息,以了解用户是如何利用该网站进行软件协作的,但迄今为止还没有研究描述GitHub可用数据的质量和属性。 我们记录了一项旨在理解GitHub中存储库和用户特征的实证研究的结果,我们将看到用户如何利用GitHub的主要功能,以及他们的活动如何在GitHub和相关数据集上被追踪,以指出真实数据和挖掘数据之间的不一致。 我们的结果表明,虽然GitHub是软件开发方面丰富的数据来源,但出于研究目的挖掘GitHub应该考虑到各种潜在的危险。 例如,我们发现大多数的项目都是私人的和不活跃的,几乎40%的Pulll Request即使合并了也没有显示出来。 此外,大约一半的GitHub注册用户没有公开活动,而GitHub用户在存储库中的活动并不总是那么容易确定。 我们用我们确定的危险来看看它们是否会构成有效威胁,我们回顾了2014年MSR录用的论文,看看是否有潜在的影响需要考虑。 对于如何在GitHub中获取数据,我们为软件工程研究人员提供了一组建议。

关键词:挖掘软件库  git  GitHub  代码审核

1 引言

GitHub是一个流行的基于git版本控制系统的协作式代码托管站点。截至2014年1月,它托管了超过1060万个存储库。它包括各种各样的特点,鼓励团队合作。GitHub使用Pulll式模型,在这个模型中,开发人员创建他们自己的存储库副本,并在他们希望项目维护者将他们的更改拉到主分支时提交Pulll Request,从而提供了一个人们可以轻松地进行代码审查的环境。每个存储库都可以选择使用GitHub的问题跟踪系统来报告和讨论bug和其他问题。GitHub还包含了集成的社交功能:用户可以通过watch项目和follow其他用户来订阅信息。该系统支持用户配置文件,提供个人最近在站点内活动的摘要,例如他们的提交、他们所分支的项目或他们报告的问题。

前景一:GitHub是软件工程研究丰富的数据来源

软件工程研究人员被GitHub所吸引是因为它的受欢迎程度,以及它集成的社交功能和可以通过API访问的元数据。定性研究集中在开发者如何使用GitHub的社交功能来形成对开发者和项目活动的印象并得出结论,从而评估成功、性能和可能的合作机会。定量研究试图系统地归档GitHub的公开数据,并利用它来调查GitHub环境中的开发实践和网络结构。

我们进行了一项探索性的在线调查,以评估开发者为什么使用GitHub,以及GitHub如何支持他们与他人合作,这是我们研究GitHub合作的一部分。在分析调查数据时,我们注意到GitHub存储库也被用于严格意义上的软件开发之外的目的:许多受访者使用存储库来归档数据,来托管个人项目,或者用于软件工程之外的活动。这表明,将GitHub数据原样用于软件工程研究可能存在重大的未被发现的危险。如果不首先确定数据是否符合研究目的,那么存储库内容和活动的多样性以及开发人员的意图可能会改变研究结论。

先前的研究已经发现,在从SourceForge挖掘数据时,可能会产生误解。此外,还描述了与利用存储在分散版本控制系统git中的信息相关的前景和风险。沿着这条研究路线,我们制定了以下研究问题:

RQ: 挖掘GitHub用于软件工程研究的前景和风险是什么?

这项研究强调了依赖GitHub作为软件工程开发主要数据来源的研究的有效性的潜在威胁。我们通过对240个GitHub用户进行的调查来发现潜在的危险,并且根据对GHTorrent数据集的定量分析以及对434个GitHub存储库的手动检查,我们提供了这些危险的证据。我们列出了一些需要避免的分析风险,并就研究人员如何最好地利用GitHub提供了建议。为了证明这些危险的有用性,我们分析了来自MSR14年的四篇论文。我们将描述这些危险如何出现在数据集中,并对这些论文的结果产生潜在的有效性威胁。

本文是一个扩展版本,发表在国际工作会议采矿软件库,MSR 2014。扩展分为两类。首先,我们确定了另外四种危险:两种与GitHub用户信息有关,另两种与GitHub提供的信息有关。其次,我们评估了危险的潜在影响,威胁有效性的研究。

2 背景及相关工作

由于GitHub上托管的许多项目都是公开的,任何一个能上网的人都可以查看这些项目中的活动,包括问题、Pulll Request、提交、评论和订阅等信息。GitHub上的大量公开数据以及通过API提供的可用性,使得研究人员可以轻松挖掘项目数据,也有各种工具和数据集来协助研究人员完成这项任务。

2.1 背景

由于数据的丰富性和可用性,像GitHub这样的代码托管服务引起了许多软件工程研究人员的兴趣。来自许多项目的数据的公开可用性简化了数据收集和处理问题,这些问题在研究中经常遇到。然而,仍存在一些实际困难,可能会改变从数据中得出的结论。

另一个流行的代码托管站点SourceForge在GitHub被广泛采用之前达到了流行的顶峰。Howison和Crowston注意到,在SourceForge上托管的项目经常被放弃,他们的数据经常被从以前的系统导入的数据所污染。他们还发现,由于项目数据托管在SourceForge空间之外,信息经常会丢失。类似地,Weiss总结道,并不是所有的SourceForge数据都是完美的:类别的名称在SourceForge中经常变化,项目经常被启动,然后停止。通过将他的数据与FLOSSMole的数据进行比较,Weiss强调了关于不活跃和无法进入的项目的信息完全缺失。Rainerand Gale对SourceForge数据的质量进行了深入分析。他们注意到只有1%的SourceForge项目实际上是活跃的,正如他们的度量标准所表明的那样。作者建议在使用SourceForge数据时要谨慎,并且建议研究团体应该对从诸如SourceForge这样的门户网站获取的数据的质量进行评估。在本文中,我们展示的研究结果强调了潜在的风险,让研究人员在从GitHub数据中得出结论时注意。

其他最近的研究已经发现了错误修正数据集的偏差,这可能会影响使用数据集的研究的有效性和普遍性。研究人员经常依赖于在提交日志中bug和提交之间的链接,但是链接的bug只占全部修复bug的一小部分。伯德等人发现,这组bug是整个种群的一个有偏见的样本。Bachmann等人发现,bug跟踪系统本身的bug集合可能是有偏差的,因为并非所有的bug都是通过这些系统报告的。Nguyen等人发现,即使在采用严格指导方针和流程的商业项目中,也存在类似的偏见。然而,Rahman等人表明,大样本容量可以抵消偏见的影响。在我们的工作中,我们证明了在大型GitHub数据集中存在偏见,并提供了如何避免这种偏见的建议。

Bird等人描述了挖掘git给软件工程研究带来的问题。他们的工作表明,集中式版本控制系统和git之间的差异给那些使用git存储库进行研究的人带来了一定的挑战。

2.2 相关工作

在代码托管网站中引入社交功能已经引起了研究者的广泛关注。一些定性研究采访了GitHub用户,以更好地了解这些社交功能是如何被使用的。他们的发现对开发商和项目的活动和潜力形成印象并得出结论。然后用户将这些结论内在化,以决定跟踪谁、跟踪什么,或者下一步在哪里做出贡献。这些社交特性带来的透明性似乎也允许团队保持对成员活动的意识,并利用这种意识来组织他们的工作。Phametal研究了GitHub社交功能所赋予的开发者行为的高可见性是否会影响开发者的测试行为。通过访谈和在线调查,他们强调了在贡献者中推广理想的测试文化所面临的挑战,并提出了相应的策略。Tsayetal 对5000个项目的影响进行了定量研究。他们的研究发现,项目成员将GitHub的社交功能视为贡献增加的驱动因素。

对GitHub的研究已经超越了它的社交功能。Thung为参与10万个GitHub项目的开发者建立了社交网络,以展示GitHub生态系统的社交结构。Takhteyev和Hilts研究了GitHub开发者的地理位置,方法是在GitHub档案中查看他们自己报告的位置信息。Gousios研究了GitHub上的Pulll Request是如何工作的。他们发现Pulll Request模型提供了快速的周转,增加了社区参与的机会,并减少了合并贡献的时间。他们发现,影响合并Pulll Request的决定和处理时间的因素相对较少。他们还定性地检查了Pulll Request被拒绝的原因,发现技术原因占少数。他们还演示了许多看起来在GitHub中未合并的Pulll Request实际上被合并了。这篇论文扩展了他们的工作。

几个研究项目通过GitHub API提供了更方便的数据访问。ghtorrent项目提供了一个GitHub API data的镜像,它通过监控和记录GitHub事件的发生,并应用基于依赖的递归检索相关资源来获得API data。在独立运行模式下,GHTorrent还可以检索单个存储库的历史。Gousios和Zaidman将这个数据集与他们在Gousios等人的研究结合起来,为GitHub项目提供了一个Pulll Request数据集。

GitHub档案提供了GitHub历史事件的数据集。它还通过监控GitHub时间轴来获取数据。然而,由于GitHub档案从2011年开始收集数据,这是一个不完整的镜像,相比之下,GHTorrent检索了GitHub的完整历史。此外,还可以使用Gitminer等工具提取特定存储库的事件历史。Gitminer为任何想要的项目抓取GitHub API,并生成一个图形数据集。

Tsay等人使用GitHub的API挖掘了他们研究所需的数据。他们表示,为了得出有意义的结论,他们必须过滤掉GitHub中的大多数项目,因为很多项目不活跃,贡献者很少,或者没有使用GitHub的问题跟踪系统。

研究人员利用GitHub和GHTorrent、GitHub archive和Gitminer等工具提供的大量数据,在大量的项目中进行研究。研究调查了测试模式、编程语言、问题报告、项目成功等等。Takhteyev和Hilts研究了GitHub开发者的地理位置,方法是在GitHub档案中查看他们自己报告的位置信息。

3 研究设计

在一个正在进行的项目中,我们发现选择哪个基于github的协作软件工程项目来研究并不是一项简单的任务。项目经常是空的,只有很少的文件,或者已经不活动很长时间了。找到唯一贡献者是其所有者的存储库也很常见。

这些案例激发了我们对GitHub存储库内容和GitHub内部协作的进一步分析,如4.3节和4.4节所述。然后,我们对GitHub的数据进行了定量和定性分析,以确定和衡量危险的程度和频率。出于本文的目的,我们将危险定义为可以从GitHub检索到的数据的特征,它可能威胁到使用这些数据的软件工程研究的有效性。

我们的流程划分如下:

  • 项目元数据的定量分析。我们使用GHTorrent 2014年1月的数据集进行研究。GHTorrent是GitHub存储库、它们的用户和事件的综合集合,如第1节所述。我们还使用了MSR 14 Mining Challenge数据集,并在GitHub中克隆了许多存储库,以便将GHTorrent数据与当前存储库进行比较。

  • 手工分析434个项目样本。为了补充我们的定量分析,我们还对GHTorrent数据集中存在的300万个项目中的434个随机样本进行了深入的手工分析。这个样本量提供了95%的置信水平和5%的置信区间。

4 结果

我们使用混合研究方法,确定了13种危险对在GitHub中托管的软件项目的研究有潜在的威胁。在本节中,我们描述并提供了各种威胁的支持证据,并提出了如何避免它们的建议。

4.1 存储库是项目的一部分

威胁一:存储库不一定是一个项目

典型的Pulll Request开发模型是在分布式软件开发中协作的一种更新方法。有了这个模型,项目的主存储库并不能由潜在的贡献者执行。相反,贡献者将存储库进行fork,并使它们的更改相互独立。当一组更改准备提交给主存储库时,它们创建一个Pulll Request,该Pulll Request指定一个本地分支,以与主存储库中的一个分支合并。项目核心团队的成员将负责检查更改并将其拉入项目的主分支。如果更改被认为不令人满意,则可能要求更多的更改。在这种情况下,贡献者需要通过新的提交更新它们的本地分支。

由于这种流行的开发模型,存储库可以分为两种类型:基础存储库和forked存储库。forked存储库中的活动独立于它们fork的基础存储库。在提交到基础存储库之前,forked库的提交只出现在自身库的历史中。

例如,Ruby on Rails项目有8327个forks。在Rails存储库的50000个提交中,GHTorrent报告只有34000个提交在Rails基础存储库中发生,其余的16000个提交在它的分支项目中。然而,11000个提交已经在分支中进行,但没有合并到基本存储库。

本文介绍了基础存储库和它分支的活动。因此,我们使用术语项目来表示基本存储库和它的分支,并继续使用术语存储库来表示GitHub存储库(要么是基本存储库,要么是一个分支)。

在GitHub的680万公共存储库中,有300万(44%)是基础存储库。因此,这些基础存储库代表了300万个不同的项目(有60万的项目至少被fork过一次)。对于至少有一个分支的基础存储库来说,它们的分支的数量高度倾斜:80%只有1个分支,94%不超过3个分支。然而,有一些存储库被大量的fork:4111个基本存储库已经被fork了至少100次。最多被fork的repo是的octocat/Spoon-Knife,一个由GitHub管理的存储库来测试fork是如何工作的。

需要强调的是,许多分支可以独立于项目的其他部分进行操作。例如,可以使用fork来开发定制,而这些定制永远不会被贡献回主项目中。然而,很难确定还未对项目做出贡献的存储库将来是否会做出贡献。

风险规避策略:要分析托管在GitHub上的项目,需要考虑基本存储库和所有相关分支存储库中的活动。

4.2 项目活动

提交是GitHub中活动的强烈反映,提交的数量是Pulll Request或问题数量的20倍以上。因此,我们可以使用两个不同的指标来度量一个项目的活动:提交的数量和提交的时间。

威胁二:大多数项目都有较低的活动

我们计算了每个项目的提交数量,即一个给定项目的所有存储库中的所有提交。图1显示其累积分布,平均数量为6,最多为427,650。

在GitHub中,有大量的项目几乎没有活动,最活跃的项目占据了提交的大部分。这是在图2的Lorenz曲线中显示的,描述了在项目中提交的不平等。最活跃的2.5%的项目提及数量与剩下的97.5%的项目相同。

对挖掘GitHub的前景和风险的深入研究

风险规避策略:考虑一个项目最近提交的数量,以选择具有适当活动级别的项目。如果你的研究只考虑了非常活跃的项目,泛化方面会出现问题,因为这些只是GitHub上的一小部分。

威胁三:大多数项目都是不活跃的

由于许多项目很少提交,很可能许多项目也会不活动。图3显示了在过去四个月中活动的项目的累积比例。例如,在过去的6个月里,只有54%的项目是活动的。然而,在这段时间里出现了许多新项目。在2013年7月9日之前创建的12958769个项目中,只有430852个项目在过去6个月里至少有一个commit。

对挖掘GitHub的前景和风险的深入研究

项目活动也可以通过比较它在GitHub中创建的日期和它最后一次提交的日期来度量(如图4所示)。在这方面,项目活动的中值天数为9.9天。32%的项目活跃了1天,这表明他们正在被用于测试或用于档案目的。只有38%的项目活跃超过1个月。然而,许多积极的项目仍然活跃:25%的项目至少有100天的活动。

对挖掘GitHub的前景和风险的深入研究

风险规避策略:识别活动项目,考虑最近提交和Pulll Request的数量。

4.3 项目内容

威胁四:许多项目不是软件开发

我们的调查结果表明,在软件开发之外,GitHub被用于各种目的。在我们240名受访者中,有34人表示他们使用GitHub库进行实验,托管他们的网站,以及学术/班级项目。大约10%的受访者使用GitHub专门用于存储。

存储库的目的不能直接从项目元数据中自动识别。我们使用434随机选择的存储库来确定GitHub存储库是否用于软件开发或其他目的,该样本提供了95%的置信水平和一个±5%的置信区间。我们回顾了与每个存储库关联的描述和文件,并分配了一个合适的标签来标记其内容、“软件库”或“类项目”使用标准的定性编码技术。公开编码用于识别每个存储库的标签。开源编码由两个个人执行,他们每个人编码了一半的存储库。在开源编码之后,两位编码人员就一组标签达成一致,并使用轴向编码将这些标签聚合在一起,以创建专用的使用类别。如果存储库的内容是用来构建任何类型的工具的文件,我们将其目的定义为“软件开发”。网站和博客被归类为“Web”,“学术”为课程和研究项目。存储类别包括包含配置文件或其他个人使用的文档和文件,如演示幻灯片、简历等。给出错误的存储库被标记为“不再可访问”。存储库只包含一个许可证文件、一个gitignore文件、一个README文件,或者任何文件都被放置在“空”的类别中。表2显示了我们的类别和434个存储库的分布。

对挖掘GitHub的前景和风险的深入研究

值得注意的是,“Web”类已经成为GitHub的一个重要用途。GitHub允许其用户免费在其服务器上托管网站。使用这种服务的存储库通常包括github.io或github.com。有73745个项目具有这样的名称,表明这种免费服务的受欢迎程度。

风险规避策略:当试图确定要分析的软件开发项目时,不要仅仅依赖存储库中的文件类型,还要检查描述和README文件,以确保项目符合研究需要。

4.4 参与项目的用户

威胁五:大多数项目都是私人的

在我们的调查中,受访者被问及他们使用GitHub主要是为了与他人合作还是个人使用。240名受访者中有90人(38%)回答说,他们使用GitHub主要是为了自己的项目,而不是为了与他人合作。这一反应促使我们去研究GitHub项目中有多少协作和社交互动。

git提交记录作者(编写补丁的人)和提交者(提交补丁到存储库的人)。提交者是对存储库具有写访问权的人。在GitHub中,只有2.9%的提交有一个不是提交者的作者。我们可以通过计算项目所有存储库中不同提交者的数量来评估一个项目是否是个人的。

每个项目的提交者的数量非常倾斜的:67%的项目只有一个提交者,87%有2个或更少,93%有3个或更少。正如预期的那样,存储库比项目拥有更少的提交者:72%有1个提交者,91%有2个或更少,95%有3个或更少。作者数量的比例是相同的。在我们的手工样本中,提交者的数量是相似的:65%的项目只有一个提交者,83%的项目只有两个提交者或更少,90%的项目只有三个提交者或更少。

尽管GitHub的目标是社交编码,这些结果表明大多数托管项目都是由一个人使用的。只有一个提交者的大部分项目很可能是用于实验或存储目的。

风险规避策略:为了避免个人项目,考虑提交者的数量。

4.5 关于非github设备的使用

威胁六:许多活跃的项目并不只使用GitHub

很难确定GitHub中的数据是否代表了开发项目的大部分可见活动。换句话说,GitHub的项目使用其他形式的合作吗?

调查结果显示,项目讨论在GitHub之外进行。正如其中一位受访者所言:“任何公共的项目都必须有一些独立的基础设施——邮件列表、论坛、irc频道和他们的档案等等。因此,虽然GitHub和其他所有项目都是用于协作,但它们不是也不可能是一个完整的解决方案。”

这促使我们调查存储库是否使用GitHub来托管项目代码和其他内容,但在其他地方执行开发和协作活动。

镜像是托管在另一个存储库中的代码的副本。在某些情况下,镜像项目清楚地表明GitHub不用于提交代码。例如,项目postgres-xc在其描述中声明:“注意,这只是一个“镜像”——我们不接受github上的Pulll Request”。尽管如此,这个项目有14个不同的分支。

我们确定了许多镜像存储库,GitHub官方维护了许多流行项目的91个镜像。通常,存储库的描述会说明它是否是镜像。描述还可以指示镜像是否自动,并记录其更新频率。

这些结果的含义是,项目开发的一部分是在GitHub上进行的,但不一定是全部。

在GitHub上托管的镜像中进行的开发工作的标识意味着项目的一些成员使用GitHub有两个目的。一个目的是开发他们的工作,然后将其提交到外部存储库。例如,位于kgene/ Linux- samsung的Linux- samsung项目定期向Linux内核提交。第二个目的是为了不同的目的开发原始项目的自定义,独立于原始开发团队。在这个类别中,我们发现多个存储库包含了内核的变种,比如三星Galaxy S系列手机的2.6.35内核,或者为Dropad A8T修改的2.6.35.7内核等等。

有趣的是,一些已标识的镜像来自使用其他版本控制系统的存储库。这意味着,在某些情况下,贡献者更喜欢git而不是其他版本控制系统来完成他们的日常工作,但是这需要进一步的研究来证实。类似地,许多项目使用它们自己的缺陷跟踪系统来处理问题。例如,作为GitHub中最活跃的项目之一,Mozilla的Gaia (Mozilla -b2g/ Gaia)已经在GitHub中禁用了问题跟踪功能,并希望用户通过bugzilla提交问题。

对挖掘GitHub的前景和风险的深入研究

我们向100个GitHub用户发送了额外的调查问卷,询问用户是否使用GitHub的工具或外部工具集来完成特定任务,比如打开和合并Pulll Request、跟踪问题或用于沟通。调查是通过电子邮件发送的,我们收到了27个回复(27%的回复率)。尽管52%的人说他们使用GitHub来打开Pulll Request, 60%的人说他们使用该网站来接受和合并代码更改,但只有24%的人说他们使用GitHub来进行代码审查,32%的人说他们使用外部工具进行审查。这进一步验证了对于许多项目来说,并不是所有的软件开发活动都发生在GitHub本身中。

风险规避策略:避免有大量未注册GitHub用户的提交者的项目,避免明确声明他们是镜像的项目。

4.6 Pull Request

前景二:GitHub提供了一个有价值的数据来源,用于研究以Pulll Request和提交形式引用的代码审查。

分支&Pulll式开发模式在GitHub上非常流行,但是Pulll式开发并不是GitHub独有的。事实上,git包含git-Request-Pulll实用程序,它在命令行上提供相同的功能。GitHub和其他代码托管网站通过集成代码视图、讨论和问题,显著地改善了这一进程,从而有效地降低了临时贡献的准入门槛。fork和Pulll Request创建了一个新的开发模型,在这个模型中,变更被推给项目维护者,并在集成之前通过社区的代码审查。

威胁七:很少有项目使用Pulll Request

Pulll Request的使用在所有GitHub项目中并不是很普遍。Pulll Request只在开发者之间有用,因此在个人项目中不存在。在260万GitHub项目中,代表实际协作项目的只有268853至少使用过一次Pulll Request模型,剩下的240万个项目很可能使用共享存储库模型,所有开发人员都被授予提交访问权。此外,项目之间的Pulll Request分布高度倾斜,如图5所示。每个项目的Pulll Request的中位数是2。

对挖掘GitHub的前景和风险的深入研究

一些项目会收到大量的Pulll Request。例如,仅在2013年,Gaia手机应用程序框架和自制程序包管理器就分别收到了超过5000个Pulll Request。事实上,2013年有相当数量的项目(1700个)收到了超过100个Pulll Request。这些项目可以创建足够大的样本,为许多研究问题提供统计上显著的结果。

风险规避策略:在研究GitHub上的代码评审过程时,请在选择项目之前考虑Pulll Request的数量,个人项目很少包含Pulll Request。

4.6.1 Pull Request作为代码审查机制

每个GitHub Pulll Request都包含一个分支(本地或其他存储库中),核心团队成员应该从该分支进行Pulll Request。GitHub自动发现要合并的提交,并将它们附加到Pulll Request中。默认情况下,将Pulll Request提交到目标存储库进行审查。任何GitHub用户都可以参与评论。有两种类型的评论:

  • 讨论:对Pulll Request的总体内容进行评论,有关各方就Pulll Request的适用性进行技术讨论。

  • 代码评审:对代码特定部分的注释。审查员会对提交差异做笔记,通常是技术性的,以查明潜在的改进。

审查的结果是,Pulll Request可以用新的提交进行更新,或者Pulll Request可以被拒绝。Pull Request被拒绝的确切原因并没有记录下来,但是通常可以从评论中推断出来。

通过更新,贡献者在分支存储库中创建新的提交,在更改被推到要合并的分支后,GitHub自动更新Pull Request中的提交。然后可以在刷新提交时重复代码检查。在我们的434个项目的数据集中,17%的Pull Request收到了注释后的更新。当将这个结果解释为许多注释时,必须要小心,尤其是在讨论部分,这些注释仅仅是对贡献者工作的感激的表达,而不是正确的代码评审。

对Pull Request的讨论通常很简短:80%的Pull Request的评论少于3条。此外,代码评审中的参与者数量在0到19之间,80%的Pulll请求的参与者少于2个。每次同行评审检查的提交数量少于80%的Pulll请求中的4个。这些数字可以与其他代码评审工作相比较,这表明同行评审过程可能有更多有待探索的基础。因此,GitHub数据可能是用于同行审查的定量数据的一个非常好的来源,这是由于跨不同项目存储库的同质化。

在许多情况下,Pull Request的代码审查是隐性的,因此是不可观察的。许多被合并的Pull Request没有收到任何评论(在我们的434项目示例中有46%)。可以安全地假设执行合并的开发人员在合并前检查了Pull Request。因此,进行了代码审查,但是除了代码被合并这一事实之外,没有关于它的任何信息(项目不太可能有不审查就接受所有Pull Request的策略)。

威胁八:合并只跟踪成功的代码

还有一种可能是,所审查的提交集可能不容易观察到,可能需要进一步处理来恢复它们。通常,在提交集合与主存储库合并之前,项目需要一个提交压缩(将所有不同的提交合并为一个提交)。虽然GitHub会记录中间提交,但它不会通过API将它们报告为Pull Request的一部分。此外,如果源存储库被删除,原始提交也会被删除。这意味着在分析的时候,研究者只能观察最新的提交,这是代码审查过程的结果。

风险规避策略:要分析代码评审中涉及的全部提交,不要依赖GitHub报告的提交。

威胁九:许多合并的Pull Request以未合并的形式出现

在成功地进行代码审查并获得积极的结果后,可以合并Pull Request。git和GitHub的多功能性至少支持三种合并策略:

  • 使用GitHub中的“合并”按钮。

  • 通过合并主存储库分支和Pull Request分支来使用git,其中只有来自Pull Request分支的特定提交被合并到主分支中。

  • 通过在Pull Request和主存储库分支之间创建一个文本补丁,并将其应用到主分支。这也称为提交压缩。

根据所选择的合并策略,保存的历史记录数量(提交顺序)和作者信息将有所不同。具体来说,通过git或GitHub进行合并可以保存完整的历史信息,基于补丁的合并并不维护作者身份或历史记录。

此外,GitHub只能通过其pull request merge工具检测和报告合并发生的情况。因此,如果一个项目的策略是只使用git进行合并,那么所有的Pull Request将在GitHub中被记录为unmerge。然而,在实践中,大多数项目使用GitHub和git合并策略的组合。

GitHub提供了一种通过提交日志内容简化Pull Request和问题关闭的方法。例如,如果一个提交日志包含字符串Fixes #321和321是一个pull request或issue,那么这个pull request或issue将被关闭。fix是可以使用的九个关键字之一。例如,homebrew/homebrew项目打开了13164个Pull Request,关闭了12966个Pull Request,但只有129个Pull Request合并。但是,它的日志显示,已经从提交日志中关闭了6947个Pull Request(占总数的48%)和2013个问题(19%)。这表明,至少在一些项目中,不能依赖于Pull Request的GitHub合并属性。

合并在GitHub之外的Pull Request可以通过一组启发式识别,这些启发式识别基于GitHub提倡的约定。下面是最重要的:

  • H1: Pull Request中至少有一个提交出现在目标项目的主分支中。

  • H2: 一个提交使用它的日志关闭Pull Request(例如,如果提交的日志包含一个关闭关键字,见上面),并且提交出现在项目的主分支中。这意味着Pull Request提交被压缩到一个提交,并且这个提交被合并。

  • H3: 最后三个讨论注释中的一个(按出现的顺序)包含提交的唯一标识符,该提交出现在项目的主分支中。

  • H4: 关闭Pull Request之前的最新注释与上面提到的正则表达式匹配。

在2552868个Pull Request中,只有1145099个(44%)被报告为在GitHub上合并。在434个项目的示例中,只有37%的Pull Request是使用GitHub工具合并的。通过应用上述启发式方法,将额外的42% (H1: 32%,H2: 1%,H3: 5%,H4: 4%)的Pull Request标识为合并,而19%不能进行分类。在另一个数据集中,包含近1000个使用ullrequest的项目,58%的pullrequest被合并到github的设施中,而18%被确定为未合并。其余24%通过启发式方法标识为合并(H1: 11%,H2: 3%,H3: 3%,H4: 7%)

上面提出的启发式方法是不完整的(它们可能不能识别所有合并的Pull Request)。在其他工作中,我们一共检查了350个合并的请求,发现有65个实际上被合并了。这意味着合并请求的实际百分比可能更高。然而,事实是,只有一小部分的合并是通过github报告的,但启发式可以改善合并检测,在某些情况下效果显著。

风险规避策略:不要依赖于GitHub的合并状态,而是考虑在分析合并的Pull Request时使用启发式来改进合并检测。

4.6.2 Pull Request作为问题解决机制

前景三:开发人员、Pull Request、问题和提交之间的相互联系提供了软件开发活动的全面视图

对于每个打开的Pull Request,都会自动打开一个问题。因此,问题和Pull Request在GitHub上被融合在一起。提交还可以附加到问题上,将它们转换为Pull Request。Pull Request的问题部分用于跟踪任何讨论注释。我们鼓励开发人员在提交消息或发布评论中引用问题或提取请求,而GitHub会自动提取这些引用,并将它们作为讨论流的一部分呈现出来。此外,问题和Pull Request都可以链接到存储库特定的里程碑,帮助项目跟踪进度。

问题和Pull Request的紧密集成为详细研究开发人员活动提供了机会。例如,研究人员可以从报告阶段,通过源代码修改、代码审查和修复的最终集成,跟踪问题的解决。由于用户操作总是会影响问题和Pull Request,因此还可以研究特定类型的活动之间用户集群的形成,从而揭示出紧密的用户组织(团队或层次结构)。此外,问题的相互连接、Pull Request和提交创建了一个复杂的动作网络,可以使用社交网络技术对其进行分析,以发现有趣的协作模式。

尽管互连数据如此丰富,但存在两个缺点。首先,如果项目之间的记录是一致的,那么对问题跟踪存储库的存储库挖掘将大大增强。GitHub的问题跟踪器只需要一个文本描述就可以打开问题。发布属性注释被委托给存储库特定的标签。这意味着不能在项目之间统一地检查问题特征。其次,在GitHub上,只有一小部分(12%)的存储库在2013年同时使用Pull Request和问题。许多有趣的存储库,特别是那些迁移到GitHub的存储库,都有一个外部的问题数据库(见危险4,许多活动的项目并不只使用GitHub)。

4.7 用户

威胁十:并非所有的活动都是由注册用户发起的

GitHub是一个围绕git构建的服务。使用git的开发团队可以选择在所有或部分开发活动中使用GitHub。GitHub允许团队将他们的git存储库导入到GitHub中,即使开发团队的一些成员不是GitHub用户。在某些情况下,开发团队中可能没有人是注册的GitHub用户。这意味着在GitHub中记录的一些活动并不是由注册用户执行的。

  • 一小部分用户在创建GitHub用户账户之前就提交了commit(1.5%,33,227)。例如,Linus Torvalds在2011年9月3日加入GitHub,但早在2007年9月4日就提交了与他的用户帐户相关的提交。

    • 选择名字之间至少有一个空格的提交者。这个步骤选择名字中至少有两个单词的提交者(例如Linus Torvalds),并避免匹配具有相同姓或名的人。

请注意,这种方法可能会低估每个用户重复的电子邮件,因为可能存在缺少名称的电子邮件,或者他们的名称可能只包含一个单词,或者某人使用不同的方式书写他们的名称。

风险规避策略:对于需要将活动映射到特定用户的实证研究,使用启发式来统一电子邮件,以提高结果的有效性。

威胁十一:只有用户的公共活动是可见的

当我们仔细观察注册用户的活动时,我们注意到大量的不活动用户。然而,在得出结论之前,我们需要记住,我们只能看到公共活动。

让我们把提交作为GitHub上的基本活动单元。97%的情况下,提交者和作者是同一个人。因此,在此分析中,我们认为它们是等价的,并且只查看committer字段来估计提交活动。

我们发现,在GitHub上的注册用户中,53.2%的人没有一次公开提交。这个填充可以进一步分为两部分:30%的注册用户也没有公共存储库,而其余的23.2%有存储库但没有公共提交。这些存储库分为两类:空存储库和没有活动的fork。

其余46.8%的注册用户(104万)至少有一次提交。如图6所示,每个用户的提交数分布是高度倾斜的:中位数是10次提交,平均62.4次提交。每个注册用户的提交数量差别是相当大的(见图7):50%的提交由3.2%的注册用户执行,25%由0.6%的注册用户执行。这主要是由于一些注册用户看起来过于活跃,提交的次数非常多。

对挖掘GitHub的前景和风险的深入研究

但是,仅将提交作为活动的度量将排除以其他方式活动的用户。24.4%没有提交任何请求的注册用户提交了建议,或者参与了关于问题或请求的讨论。这表明,有一部分GitHub用户不公开开发代码(他们可以有自己的共享代码库),但他们通过识别bug、提交新功能请求、检查代码或为开发人员提供指导,积极地为GitHub知识库做出贡献。

风险规避策略:在使用公共网站上的数据时,这种危险是不可避免的——在讨论结果时承认这种片面的观点,并在其他情况下重复一项研究可以帮助降低其影响。

4.8 GitHub是一个不断发展的实体

GitHub不是作为用于研究目的的软件开发活动档案而运行的;它的目标是为开源和私有项目提供强大的协作、代码审查和代码管理。

威胁十二:GitHub的API不会公开所有数据

虽然托管在GitHub中的存储库在不断发展,但GitHub只报告它们的当前状态(通过它的API)。它不报告形成任何存储库当前状态的历史事件。这给研究人员带来了几个挑战:

  • GitHub不提供检索所有事件的API。GitHub已经创建了api来列出它的许多实体(如用户、存储库和提交)和事件(如打开或关闭问题,或Pull Request)。但是,它并没有使它们全部可用。例如,GitHub不会向存储库公开推送、发布的创建、克隆操作或存储库公开的时间。其中一些事件可以从存储库的events API中获得,但该API有仅列出最近300个事件。

  • 并不是所有的事件都用时间戳来报告。特别是,用于订阅和star的api不会返回启动这些操作的时间。

  • 跟踪重命名实体。重命名的存储库将其所有信息保存在新名称下(包括其分支)。GitHub会重定向重命名库的url,但不会对API请求重定向。对于用户,无法知道用户是否已被重命名。在这种情况下,URL和对旧名称的API请求都将失败。

  • 删除实体。当一个存储库被删除时,它所有的事件和元数据都会丢失,但是从它派生出来的存储库网络保持不变;它的一个分支将被选为其他分支的根。从现在开始,GitHub将报告未找到已删除的存储库。类似地,当提交被删除时,GitHub也没有机制来通知从存储库中删除了某些提交。最后,一旦用户被删除,所有关于他们的信息(包括他们是GitHub用户的事实)就会丢失。

  • 将储存库设置为私有会使它看起来好像已被删除。与删除存储库类似,GitHub将报告未找到此类存储库。在这种情况下,它的分支仍然是公共的,并且其中一个被选为根。

  • 重置提交。当重新提交时,旧的提交将从存储库中消失,并由新提交替换。

  • 传播的提交。GitHub只在使用Pull Request合并提交并且合并后没有重新基于或删除提交的情况下跟踪提交在存储库之间的移动。在这种情况下,合并的Pull Request将记录合并的提交,包括源和目标存储库。如果合并是在GitHub之外执行的,那么GitHub无法知道该委员会的真实资源是什么。

风险规避策略:从GitHub API存档数据的服务中获取数据可以帮助避免这种危险。然而,研究人员应该知道,这些服务包含了他们自己对收集数据的假设。

威胁十三:Github在不断发展

随着时间的推移,GitHub改变了一些特性和界面。例如,GitHub的watch功能最初是为那些想要接收自己选择的任何存储库的活动通知的用户设计的。2012年8月,GitHub决定改进他们的通知系统。第一个变化是引入了“star”。star存储库相当于书签。为了保持与使用这些信息的外部应用程序的向后兼容性,GitHub目前会返回其watch API下的star项目列表。这给研究人员带来了两个潜在的问题。首先,2012年8月前后,watch的意义有所不同。其次,GitHub的接口和API之间存在不协调。

最近,GitHub悄悄地禁用了为特定存储库检索协作者的功能。现在检索此信息的唯一方法是查询和跟踪特定存储库、设置或项目的实时事件流。

上述两项更改都对API有直接影响。GitHub接口也有频繁的变化,不会留下API占用空间,但它们有可能改变用户的行为。例如,GitHub的问题跟踪系统在2014年7月28日得到了显著的改进。界面的变化与改进搜索和过滤、显示与问题相关的活动的时间线以及改进里程碑和问题标签的编辑有关。虽然创建和存储的用户数据没有受到影响,但研究人员仍应跟踪GitHub界面何时发生了变化,以及改进了哪些。捕捉和测量界面变化对用户行为的实际影响将是一项独立的研究工作,因为它超出了本文的范围。然而,我们希望让研究人员注意到,数据中看到的模式可以通过考虑界面的变化来解释,反映用户行为的变化,即使这些变化没有在API中捕捉到。

风险规避策略:了解GitHub API和网站是如何随着时间的推移而发展的。网站的变化通常会发布到GitHub的博客上,但这并不能保证。

5 2014年矿业挑战MSR分析

在2014年的MSR挖掘挑战赛中,研究人员得到了GHTorrent数据集的一个子集来分析并获得新的见解。比赛结果有九篇论文被录用。鉴于提出的威胁,我们分析了数据集和接受的论文,以确定我们的威胁是否可能对这些论文中提出的结果的有效性构成潜在威胁。

采矿挑战的组织者认为整个GHTorrent数据集太大了。我们选择了90个存储库,如下所示:对于前10种编程语言中的每一种,最初选择的是2013年处理Pull Request最多的前10个最活跃的存储库。然后手工清除原始的选择以删除那些不是软件开发的存储库。

下面我们将讨论已识别的威胁如何对从该数据集获得的见解产生影响。

威胁一:一个存储库不一定是一个项目。数据包含90个项目,但不幸的是,数据集的架构将存储库称为项目,而不包括项目的实体。必须通过递归地遍历Projects表的派生项目来推断项目,以标识存储库所属的项目。

威胁二:大多数项目的活动性都很低。有3个项目提交量小于100次,有3个项目提交量超过40000次,10个存储库占提交的50%。

威胁三:大多数项目都不活动。这种危险的影响很小:在过去的6个月里只有4个仓库处于闲置状态。相比之下,上周有65个存储库处于活动状态,两周前有71个存储库处于活动状态。

威胁四:许多项目不是软件开发。这种威胁的影响也很小:一个存储库是个人网站(vinc/vinc.cc),另一个存储库是关于R编程的书(mavam/stat-cookbook)。另一个是图标的集合(FontAwesome/Font-Awesome)。

威胁五:大多数项目都是私人的。其中一个项目只有一个提交者(vinc/vinc.cc),还有一个项目有三个提交者(mavam/stat-cookbook)。同样,这种威胁的影响是很小的。

威胁六:许多活跃的项目并不只使用GitHub。jquery/jquery, mono/mono, ServiceStack/ServiceStack, django/django, clojure/clojure不使用GitHub解决问题。

威胁七:很少有项目使用Pull Request。在这个数据集中,大多数项目使用Pull Request:90个存储库中的88个。每个项目请求的中位数是393。然而,3个存储库占Pull Request的34%, 7个存储库占50%。

威胁八:合并只跟踪成功的代码。由于GitHub报告合并的Pull Request及其包含的提交的方式,这是GitHub数据所固有的首要威胁。

威胁九:许多合并的Pull Request以未合并的形式出现。有些项目并不会使用GitHub的Merge按钮关闭许多Pull Request。相反,它们通过本地存储库中的提交来实现。其中一个项目,mxcl/homebrew,如果我们假设没有标记为“合并”的Pull Request没有实际合并,就会对有效性构成重要威胁。这个项目是拥有最多Pull Request的项目(它占数据集中Pull Request的17%),其中只有0.9%被标记为合并。但是,作为开发过程的一部分,它们通过提交的日志关闭Pull Request。django/django也并不总是通过Merge按钮关闭Pull Request。在这种情况下,我们发现有819个Pull Request被合并(多41%,总共63%,而在MSR数据集中发现的是23%)。

威胁十:并非所有的活动都是由注册用户发起的。这种威胁的影响是有限的:数据集中只有1.1%的提交者不是注册用户。

威胁十一:只有用户的公共活动是可见的。这是GitHub数据集所固有的主要威胁,因为它们包含了来自公共存储库的数据。

威胁十二:GitHub的API不会公开所有数据。数据集中的一些项目已经移动并且不再是活动的。homebrew的根库从mxcl/homebrew重命名为homebrew/homebrew,尽管所有的信息都被移走了,仍然可用。

威胁十三:Github在不断发展。在MSR的数据集中,watchers与今天的star相符。这是因为watchers现在是一种订阅机制,如第4.8节所述。

6 比较SourceForge和GitHub之间的威胁

对研究人员来说,公开的存储库是很有吸引力的数据源,但也并非没有风险。之前有一些研究对公共资源数据的数量和质量进行了批判性的研究,其中最著名的例子就是从SourceForge上托管的项目中挖掘数据的威胁和陷阱(Howison和Crowston 2004)。这些危险与三个方面有关:数据收集、解释和分析,以及研究设计。在表5中,我们强调了我们的结论的相似性。

在这篇文章中,我们关注了我们自己与数据冲突,因为我们使用了一个已经存在的数据集,GHTorrent。

关于从SourceForge挖掘的数据的解释和分析,Howison和Crowston认识到两个具有挑战性的子领域:清理脏数据和扭曲数据。在清理脏数据,类似于我们的结论,作者观察到手动检查是至关重要的,因为有很多匿名数据(类似于我们的危险十:并不是所有的活动都是由于注册用户)。我们的危险IV和V(许多项目不是软件开发,大多数项目是个人的)也与清理脏数据有关,因为存储库需要手动检查来正确地对它们进行分类。

解读SourceForge数据的另一个危险是数据的扭曲程度,这也是我们在查看GitHub数据后观察到的。研究人员需要注意数据的偏态,他们需要使用筛选变量相关的数据和属性,而且筛选变量的使用将大大减少仓库的数量。我们对五种危险也做了同样的观察,见表5。

最后,Howison和Crowston对使用SourceForge数据设计研究的研究者提出了警告;该网站提供了一些易于计算的项目变量(作者都是现成的),但研究人员却无法对复杂的理论构建得出结论。这本身就是一个有效性威胁,由于不同的文献领域可能使用相同的变量作为不同概念的代理,这一事实变得更加复杂。同样的警告也适用于GitHub数据。我们还得出结论,度量标准的简单性可能隐藏了危险。例如,一个Pull Request中的提交数可以是一个简单的计算指标,但是,考虑到GitHub没有报告导致合并的Pull Request的中间提交,对于成功合并中的工作来说可能是有问题的。

令人惊讶的是,十多年前对从公共存储库中提取的数据的解读,以及基于这些数据的研究设计的威胁,如今同样适用。即使数据源可能已经改变了,研究人员仍然必须小心地选择如何提取数据,如何分析和解释数据,以及如何对软件开发做出结论。

7 讨论与结论

挖掘的数据并不总是能说明问题的全貌。在这个实证研究中,我们对GitHub的公开数据进行了批判性的审视,并评估了它是否适合作为软件工程研究的数据源。这些数据可以很容易地用于报告几个项目属性。如果研究人员想要了解编程语言使用的趋势、构建的工具类型、贡献的数量和规模等等,那么公开的数据可以提供关于GitHub环境描述特征的可靠信息。然而,使用GitHub来综合信息,从而对更抽象的构造得出结论,这需要一些考虑。我们展示了关于存储库活动和内容的假设,以及开发和协作实践如何被挑战的证据。我们建议有兴趣使用GitHub数据进行研究的研究人员首先评估其适用性,然后针对能够真正提供信息的数据来回答他们的研究问题。

与存储库活动相关的一些潜在危险已经显现。不加区分地使用GitHub数据的研究,其有效性面临的最大威胁之一是对个人使用的偏见。虽然GitHub上正在积极开发许多存储库,但其中大多数只是个人的非活动存储库。因此,在使用GitHub数据时,需要考虑的最重要的问题之一是研究需要哪种类型的存储库,然后相应地取样合适的存储库。

虽然我们认为有必要根据GitHub项目的目的对其进行识别和自动分类,但我们建议一个经验法则。根据我们自己的经验,识别活跃的软件开发项目的最好方法是考虑在最近的一段时间内,提交和Pull Request的数量有一个很好的平衡,并且提交者和作者的数量大于2的项目。问题的数量也可以作为一个指标,但不是所有的活动项目都使用GitHub的问题跟踪器,比如几个Mozilla项目。特别是那些每个提交者都有大量提交的,指向自动机器人。

当研究任何特定项目时,研究人员需要记住项目中可能存在其他储存库,其中一些储存库是为了一个共同的目标而工作的,而另一些可能是永远不会做出贡献的独立版本。根据我们的工作,我们认为判断一个存储库是否积极地与另一个存储库协作的一个简单方法可能是识别提交是否从一个存储库转移到另一个存储库,但是这个策略需要进一步验证。

除了是一个令人兴奋的数据源,GitHub也是一个不断发展的实体。它的功能范围和它们之间的集成经常变化,这意味着API也在变化。这不能被认为是GitHub的缺陷,也不能将其归罪于GitHub,这只是让研究人员承担了更多的责任,让他们保持对变化的意识,并在分析中考虑到这些变化。

最后的结论是提倡定量研究与定性数据相辅相成。根据我们提出的所有证据,数据中存在的缺陷可能会对任何严格研究的结论构成危险。特别是考虑到威胁十二GitHub的API并没有公开所有的数据,研究人员甚至无法直接访问能够解释项目或用户活动的信息。获得关于项目和用户的额外的定性输入,可以给研究人员的假设更多的信心。例如,征求参与者意见的调查可能是可靠的信息来源。

我们在一个熟悉和适当的环境中展示了这些危险的潜在影响:2014年MSR采矿挑战。我们从中得到的信息是,数据中的风险等于假设中的风险等于结果中的风险。我们提供了来自我们自己和其他研究的例子,希望继续挖掘GitHub的研究人员能够谨慎对待潜在的假设,并了解潜在的有效性威胁。

GitHub是一个出色的资源,它继续以加速的速度增长,它的用户正在寻找创新的方法来利用它。然而,在GitHub的基础设施中,软件开发正在蓬勃发展,并且将继续成为软件工程研究的一个有吸引力的资源。