自己动手:bash脚本工具统计git历史, 发掘谷歌在Android项目奥秘

原创 2013年12月04日 10:25:08

和几个项目经理朋友聊到项目工作量评估,公司内部对代码量,工程师的工作量通常有集成工具记录和衡量,但是如何比对其它业界的项目效率就成立讨论焦点,比如Google的Android工程师的代码出产效率,每个项目都花费了多少人力等等。受人之托,从Android的Git历史中研究以下这些问题,于是有了这个Bash脚本工具。

最新版本的github.com下载链接 https://github.com/neokidd/ghist2db

使用这个工具的前提是你有包含完整Git历史信息的Android的代码库,一般来说,是用"repo sync"来完成的下载的代码库,可以是全部project,也可以是部分的,比如说是用"repo sync framewors/base"这样单独sync的某些project。

repo for-all -c ghist2db.sh

输出结果是在代码库顶级目录下的一个ginfo.db文件,然后就可以用sqlite3来取得许多有趣的统计信息。比如在Android 4.0.4上,谷歌工程师commit的次数一共是155416,最多的工程师是三位大神是jessewilson@google.com, hackbod@google.com (Diane Hackbod, 大名鼎鼎的framework工程师), omakoto@google.com。另外,如何假设每个谷歌工程师每周3次commit,那么Android 4.0.4共花费了51805 staff*week的工作量。
源代码如下:

#!/bin/bash

usage()
{
    echo "ghist2db -- convert Android git history to sqlite db."
    echo "Usage:"
    echo "repo forall -c ghist2db.sh"
    echo "or, run it separately for each repo project"
}

find_repo_top()
{
    cwd=$1
    while [ "$cwd" != "" -a "$cwd" != "~" ]; do
       if [ -f $cwd/.repo/repo/main.py ]; then 
           repo_top=$cwd
           return
       fi
       cwd=${cwd%\/*}
   done
}

if [ "$repo_top"=="" ]; then
  #echo "repo_top is empty, need to call find_repo_top"
  find_repo_top `pwd`
fi

if [ "$repo_top" == "" ]; then
    echo "seems you're not in a Android repo, please cd to Android repo!"
    usage; exit 1
fi
repo_name=${repo_top##*\/}
#echo "repo_top: " $repo_top
#echo "repo_name: " $repo_name

proj=`pwd | awk -F"$repo_name"/ '{print $2}'`

echo "populating git info in $proj..."

# step 1: print git history logs in with "--pretty" format option, so that it's ready as sql sentences.
git log --pretty=format:"insert into googler_info (h, ae, ce, at, proj) values ('%h', '%ae', '%ce', '%at', '$proj');" --author=@google.com > googler_info.txt

# step 2: group all insert operations into one commit.
echo -e "begin;\n$(cat googler_info.txt)\ncommit;" > final_googler_info.sql

# step 3: add lines for creating table.
echo -e "create table if not exists googler_info(
     _id             integer primary key autoincrement,
     h               text not null,
     ae               text not null,
     ce               text not null,
     at               text not null,
     proj             text not null);
\n$(cat final_googler_info.sql)" > final_googler_info.sql

# step 4: create the db file
echo "inserting to db..."
sqlite3 "$repo_top"/ginfo.db < final_googler_info.sql
echo "done."

实现上有这么几个key points:

1. step1中,定制git log的输出历史格式,重点是--pretty参数,让输出直接是sql语句。另外--author可以指定只输出@google.com的作者,就是只看googler的代码贡献。这里取以下这些字段,更多的可以看man page (man git-log)
 %h: abbreviated commit hash
 %ae: author email
 %ce: committer email

 %at: author date, UNIX timestamp


2. step2中,把这些单独的sql语句组合成事务,目的是避免过多的插入事务对DB产生不必要的负担。


3. step3中,在开头加入创建db的语句,注意需要用到if not exists。


4. step4中,用sqlite3来执行这些sql语句。


5. Android原生的repo for-all负责遍历每个project,并运行ghist2db.sh这个脚本。所有信息被插入同一个db。


几个值得注意的细节:
1. Bash的字符串操作有许多方法。一类是用sed或者awk,比如line 36行,另一类用sh或者bash的内建方法,比如find_repo_top()中用到的子串的查找,${cwd%\/*},${repo_top##*\/}。参考资料:
Bash string manipulating:
http://tldp.org/LDP/abs/html/string-manipulation.html
SED:
http://www.doc88.com/p-0079912374852.html

2. Bash的if比较语句,[]里的语句和“[”之间需要有空格,开始是总是不习惯这样写。另外,字符串比较, 变量需要quote,比如"$cwd" != "~"。

3. 在指定行插入text,方法有多种,比如还是sed的方法,如果仅在开头或者结尾插入,可以echo源文件,在前后添加,如果step2中。sed的好用方法还可以参见这里(比如sed -i):
http://superuser.com/questions/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash
http://www.doc88.com/p-0079912374852.html

4. Bash调试:用bash -x选项,得到每行的输入参数,方便查找问题。


自己动手写操作系统——开发环境搭建

本文参考于渊老师写的《Orange S:一个操作系统的实现》一书。 参考文章: http://www.linuxidc.com/Linux/2016-10/135905.htm http://b...
  • zjdnwpu
  • zjdnwpu
  • 2017年04月16日 11:25
  • 649

终于用git上传了自己的项目

参考了一篇文章,非常感谢,参考文章。 总结一下就是先在安装一个git。 首先配置自己的身份 输入git config --global user.name "名字" git config --glo...
  • qq_23948283
  • qq_23948283
  • 2016年06月24日 15:38
  • 945

自己动手写操作系统(五)

这里开始就进入了core的启动流程(类似于linux的kernel)。core的入口函数是start_core,如何定义如何函数呢?我们这里通过编译指令就可以了。参看下面的配置文件: ENTRY (...
  • wang_sun_1983
  • wang_sun_1983
  • 2017年07月16日 21:37
  • 335

三分钟教你学Git(十六) - 统计

有时候想统计仓库的情况,比如代码量,贡献者之类的。 1 统计某人的commit数量 git log --author="$(git config --get user.name)" --oneli...
  • hongchangfirst
  • hongchangfirst
  • 2015年07月02日 16:16
  • 3694

《自己动手写操作系统》—— 工作环境搭建

最近在看《自己动手写操作系统》 于渊著,看第一页头就蒙了,书上说要准备一张空白软盘,都2010年了,上哪去找软盘啊,自从接触计算机以来我还没见过软盘呢,估计要到科技博物馆才找得到吧,呵呵。其实在第二章...
  • feixiaku
  • feixiaku
  • 2014年07月14日 00:32
  • 3051

Android项目中Git的使用

因为自己对Git命令不够熟悉,所以将学习Git的过程记录下来。 在Git文件的生命周期如下图: Android项目获取途径:自己新建项目和克隆GitLab上已有的项目 一、自己新建的项目 ...
  • DHGhh
  • DHGhh
  • 2017年03月27日 16:33
  • 430

Android之即时通讯(一)----环境搭建

最近脑子比较乱,还是静下来弄点东西心里比较踏实. 在上一家公司也有接触过即时通讯,是用xmpp协议实现的,然后使用openfire服务器,拿来直接用,今天来研究一下环信实现即时通讯 1.注册环信开...
  • ElinaVampire
  • ElinaVampire
  • 2015年05月11日 11:01
  • 2627

接入GoogleAnalytics 统计

1 将下面的依赖关系添加到您的项目一级 build.gradle 中:classpath 'com.google.gms:google-services:3.0.0'将此插件添加到应用级 build....
  • jin290
  • jin290
  • 2017年04月14日 14:22
  • 293

.NET Core跨平台的奥秘[上篇]:历史的枷锁

微软推出的第一个版本的.NET Framework是一个面向Windows桌面和服务器的基础框架,在此之后,为此微软根据设备自身的需求对.NET Framework进行裁剪,不断推出了针对具体设备类型...
  • sD7O95O
  • sD7O95O
  • 2017年11月08日 00:00
  • 115

Android 谷歌统计

Google Analytics SDK v4 for Android - Getting Started This document describes how to get started ...
  • ma969070578
  • ma969070578
  • 2014年09月15日 14:51
  • 3735
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自己动手:bash脚本工具统计git历史, 发掘谷歌在Android项目奥秘
举报原因:
原因补充:

(最多只允许输入30个字)