ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用Git命令展示Unix管道之美

用Git命令展示Unix管道之美 Unix哲学**程序别做得太复杂一个程序做好一件事还要方便和其他程序组合起来。**一个程序把结果输出出来另一个程序接着拿这个结果继续处理。Unix里的管道|就是干这个的。在《The Unix Programming Environment》里提到过Unix真正强大的地方往往不在于某一个程序有多厉害而在于这些小程序组合起来以后能做什么。很多命令单独看都只是解决一个很小的问题。但把它们接起来就能组成一个新的工具而且这种组合方式还可以不断复用。书里讲的是这个思想。那如果把它放到Git提交记录上具体应该怎么做比如业务仓库里偶尔会有人问最近这段时间谁提交得最多当然可以专门写个脚本统计。不过按照Unix的思路通常没必要。手边已经有的几个命令接起来往往就够了。用Apache Tomcat源码作为例子实际跑一遍这个过程。先在仓库根目录执行一条命令让Git只输出每次提交的作者名。pretty格式写成format:%an这样每个提交只输出一行git -c format.prettyformat:%an log -80前几行大概是这样Christopher Schultz Mark Thomas Mark Thomas Christopher Schultz Christopher Schultz这里还是按照提交时间倒序排列同一个人会反复出现。光看这串记录很难直接看出谁提交得最多。接下来用Unix里的sort。它可以把每一行按字母顺序排好。同一个人的名字排到一起后面才方便统计git-cformat.prettyformat:%an log-80|sort排完以后Christopher Schultz会挨在一起Mark Thomas也会挨在一起。这时候再接一个uniq。它可以统计相邻的重复行。所以前面的sort不能省否则同一个人的名字如果被其他人隔开uniq就统计不完整。加上-c让uniq在每行前面显示出现次数git-cformat.prettyformat:%an log-80|sort|uniq-c结果类似这样16 Christopher Schultz 1 ChristopherSchultz 1 Dimitrios Soumis 52 Mark Thomas 10 remm现在次数已经统计出来了但还是按照作者名字的字母顺序排列。还差最后一步按照提交次数从大到小排序。sort的-n表示按照数字比较-r表示倒序排列。把它接到后面git-cformat.prettyformat:%an log-80|sort|uniq-c|sort-nr结果就变成52 Mark Thomas 16 Christopher Schultz 10 remm 1 Dimitrios Soumis 1 ChristopherSchultz这样一个简单的提交排行就完成了。整个过程没有专门写统计脚本只是把四个现成的命令接了起来Git负责取数据 → sort负责排序 → uniq -c负责计数 → sort -nr负责按次数重新排序。这其实就是Unix管道最典型的用法。前一个命令把结果交给后一个命令每个命令只负责自己那一步。命令很小但组合起来就能完成一个完整的任务。而且这里有个细节很值得注意sort和uniq的顺序不能反。uniq只统计相邻的重复行所以必须先把相同的名字排到一起才能正确计数。这条管道里每个命令到底做了什么上面那段输出本身并不复杂真正容易搞混的是中间这几步。四个命令分别负责什么可以直接看下面这张表命令单独做的事不串的话git log每个提交输出一行作者名只有提交流水看不出谁提交得多sort按字母顺序把行排好同一个人的名字可能分散uniq就会漏数uniq -c合并相邻的重复行并统计次数没有先sort统计结果就不准sort -nr按数字从大到小重新排序结果还是按作者名字排列无法形成排行榜其实还有一条现成的命令可以完成类似的事情。git shortlog -sn就能直接输出提交次数排行。不过管道的意义并不是为了替代这条命令。这里真正值得注意的是**sort和uniq**根本不需要知道Git是什么。换成一份普通的文本作者列表同样可以用这套组合。数据来源变了sort和uniq还是照样工作。如果专门给Git仓库做一个提交排行功能换一种数据来源可能又得重新写一套。而这些Unix小工具只管处理输入不关心这些文本到底来自Git、日志还是其他程序。榜单里还有一个很容易被忽略的细节。Christopher Schultz有16次另外还有一行ChristopherSchultz只有1次。人眼看上去很容易认为这是同一个人。但uniq比较的是完整的字符串中间有没有空格、名字怎么拼只要不完全一样就会被当成两个人。Git日志里出现这种署名不统一的情况并不奇怪。管道也不会替你判断两个名字是不是同一个人它只负责处理传进来的文本。还有一个实际问题如果是在Windows上操作这条命令最好放到Git Bash里运行。PowerShell里的sort和Unix的sort不是一回事而且PowerShell本身也没有Unix那个uniq命令。Git for Windows自带的usr/bin目录里有sort、uniq这些Unix工具在Git Bash里运行才能和上面的命令保持一致。所以业务里遇到类似的统计需求时不一定要马上加一个统计模块。**先看看手里的小工具能不能接起来。**很多时候几个简单命令配上一条管道就已经够用了。
返回列表