Git diff,哪些开发者贡献最大

标签 git statistics git-log

我想对我的 git 存储库中的“活跃开发人员”进行度量

git shortlog --summary --numbered oldrelease..newrelease 给我一份最活跃的提交者列表,如下所示:

100  developer 1
 90  developer 2
 80  developer 3
  1  developer 4

但有时我看到某些开发人员还原其他开发人员的工作(或改进它)。

现在,我想看看哪些开发人员对该版本做出了最积极的贡献。为代码更改保留的开发人员提供更多权重,为代码在最终版本中被其他人更改的开发人员提供更少的权重。

git diff oldrelease..newrelease

可以给我版本中所有更改的行。

我想“责怪”所有这些行,以查看触及每条更改行的最后一位开发人员。如何做到这一点?

接下来,对于所有更改的行,我想对其进行汇总,以便最终得到这样的摘要。

git funky_new_command oldrelease..newrelease

developer 2    added 450, removed 200 lines
developer 3    added 500, removed 100 lines
developer 1    added 4, removed 50 lines
developer 4    added 1, removed 0 lines

我认为这将为那些随着时间的推移为源存储库做出贡献的开发人员提供一个更好的主意,而不仅仅是提交大量文件的开发人员。

最佳答案

这是一个很难正确解决的问题,因为您还(大概)想要奖励那些也删除 代码行的作者?我在下面给出的代码仅检测哪些作者在当前代码库中存在最多的代码,这些代码是自上一个时间点以来添加的。

git diff -z --name-only HEAD~5..HEAD
  | xargs -0 -n1 -- git blame HEAD~5..HEAD --
  | grep -v "\^"
  | sed 's/\(([^)]*\)([^)]*)\([^)]*)\)/\1 \2/'
  | sed 's/^[0-9a-f]* (\([^)]*\) \+[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] .*).*$/\1/'
  | sort | uniq -c | sort -nr

让我们看看这里发生了什么:

git diff -z --name-only HEAD~5..HEAD 列出自上次以来更改的所有文件。我们用 NULL 分隔它们,而不是换行符 (-z),以避免 xargs 的分词问题。

xargs -0 -n1 然后使用这些文件并为每个文件调用 git blame HEAD~5..HEAD --。需要第一个 -- 以便我们可以将 -- 交给 git blame。第二个是这样的,如果有人给我们一个以破折号开头的文件名,我们就不会崩溃。

grep -v "\^" 将只保留自给出的第一个修订版以来更改过的行。这个指示器的存在也是我们不使用机器可读的 --porcelain 输出的原因,这会使解析更容易(见下文),但没有这种指示器.一个更聪明的脚本可以提取我们开始的版本并忽略该版本之后的任何作者行,但我们希望保持“简单”。概述了类似的方法 here .

这个阶段的输出看起来像这样:

118caa41 (Jon Gjengset 2014-01-09 13:09:05 +0000 13) .FORCE:

我们想提取其中的作者部分,这很重要,因为名称可能包含空格。由于某些存储库的用户名称中包含符号 (),因此情况变得更加复杂。所以,为了简化我们的问题,我们首先用

去掉这些嵌套的括号
sed 's/\(([^)]*\)([^)]*)\([^)]*)\)/\1 \2/'

这不是很漂亮,如果一些讨厌的人在他们的名字中有不匹配的 () 就会崩溃,但我们会说现在没问题。

为了提取名称本身,我们求助于这个怪物般的正则表达式。它可以通过使用扩展的正则表达式进一步简化,但我决定尽可能地尝试保持 sed 兼容性:

sed 's/^[0-9a-f]* (\([^)]*\) \+[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] .*).*$/\1/'
       ^-- 1                 ^-- 2

我们首先确保找到第一个带括号的表达式(代码行也可能包含括号)为 1。然后我们匹配,直到我们找到看起来像上面一行中括号中间看到的日期的东西,在哪一点我们有作者的名字。之后的任何内容都可以删除。

此时唯一剩下要做的就是排序和排名,我们使用 sort | uniq-c |排序-nr.

瞧,这个命令会为您找到一个有序列表,其中列出了作者在修订列表中添加的代码行数,这些代码行数出现在最后一个修订版中。

提醒一句:您可能不想将其用于任何关键任务。众所周知,基于正则表达式的解决方案容易出现意外错误。解析 git blame--porcelain 输出可能是一个更长期的解决方案。

关于Git diff,哪些开发者贡献最大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21062695/

相关文章:

git - 我可以在不同的 ubuntu 终端或工作区有不同的 git 分支吗?

php - 按天获取统计数据 - 日期时间列 - mysql/php

r - 在 R 的 randomForest 包中,因子是否必须明确标记为因子?

c# - 检测数据的重大变化

git - 为什么 git log --cherry-pick 没有删除等效的提交?

git - 如何只获取一个分支的提交历史?

git.Run() 没有输出

github - 如何在推送到同一分支时挑选提交

asp.net-mvc - 如何将辅助角色部署到 azure 中?

git - 获取后是否有 git 命令显示新的上游提交?