Git 统计代码量

最近有一个需求是要统计 Git 仓库里每个人的代码量,于是上网搜了一下,找了一些相关命令:

指定用户名版

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

这句话可以输出当前项目内指定用户名的用户的代码量统计,结果如下:

added lines: 30400 removed lines: 21317 total lines: 9083

使用 ls-file 实现不指定用户版统计行数版

git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n

这段代码比较有意思,它扫描了当前分支的每个文件,然后用 Git 的 blame 功能输出每个人的代码行数,最后用系统命令 sort 和 uniq 实现计数。

结果如下:

   8 aaa
   9 bbb
 145 ccc
 146 ddd
 261 eee

扫描 Log 统计增删行数版

git log --shortstat --pretty="%cE" | sed 's/\(.*\)@.*/\1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/\1 0 insertions\(+\), \2/;s/\(\+\)$/\(\+\), 0 deletions\(-\)/;s/insertions?\(\+\), //;s/ deletions?\(-\)//' | awk 'BEGIN {name=""; files=0; insertions=0; deletions=0;} {if ($1 != name && name != "") { print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net"; files=0; insertions=0; deletions=0; name=$1; } name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net";}'

这段比较复杂,我也没有认真解读,直接贴结果吧:

aaa,: 353 files changed, 9359 insertions(+), 3844 deletions(-), 5515 net
aaa,bbb,: 4 files changed, 144 insertions(+), 2 deletions(-), 142 net
ccc,: 114 files changed, 2301 insertions(+), 481 deletions(-), 1820 net
ddd,: 27 files changed, 1856 insertions(+), 757 deletions(-), 1099 net
eee,: 1726 files changed, 32841 insertions(+), 22719 deletions(-), 10122 net
eee,fff,: 13 files changed, 209 insertions(+), 211 deletions(-), -2 net
ggg,: 53 files changed, 1153 insertions(+), 1170 deletions(-), -17 net
fff,: 2445 files changed, 69875 insertions(+), 62148 deletions(-), 7727 net
fff,eee,: 30 files changed, 394 insertions(+), 472 deletions(-), -78 net
bbb,: 37 files changed, 781 insertions(+), 216 deletions(-), 565 net
hhh,: 4 files changed, 34 insertions(+), 4 deletions(-), 30 net

比较奇怪的是会列出两个人同时修改,可能是 merge 操作,没有深究。

扫描 Log 单独统计每个人的增删行数加强版

git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

直接上输出:

aaa	added lines: 34, removed lines: 4, total lines: 30
bbb	added lines: 2301, removed lines: 481, total lines: 1820
ccc	added lines: 1856, removed lines: 757, total lines: 1099
ddd	added lines: 30400, removed lines: 21317, total lines: 9083
eee	added lines: 1153, removed lines: 1170, total lines: -17
fff	added lines: 1153, removed lines: 1170, total lines: -17
ggg	added lines: 72886, removed lines: 64233, total lines: 8653
hhh	added lines: 814, removed lines: 216, total lines: 598
iii	added lines: 9503, removed lines: 3846, total lines: 5657

第三方小工具版

使用这个工具可以直接输出非常漂亮的统计表格:

https://github.com/oleander/git-fame-rb

gem install git_fame
cd /path/to/gitdir && git fame
Total number of files: 2,053
Total number of lines: 63,132
Total number of commits: 4,330

+------------------------+--------+---------+-------+--------------------+
| name                   | loc    | commits | files | percent            |
+------------------------+--------+---------+-------+--------------------+
| Johan Sørensen         | 22,272 | 1,814   | 414   | 35.3 / 41.9 / 20.2 |
| Marius Mathiesen       | 10,387 | 502     | 229   | 16.5 / 11.6 / 11.2 |
| Jesper Josefsson       | 9,689  | 519     | 191   | 15.3 / 12.0 / 9.3  |
| Ole Martin Kristiansen | 6,632  | 24      | 60    | 10.5 / 0.6 / 2.9   |
| Linus Oleander         | 5,769  | 705     | 277   | 9.1 / 16.3 / 13.5  |
| Fabio Akita            | 2,122  | 24      | 60    | 3.4 / 0.6 / 2.9    |
| August Lilleaas        | 1,572  | 123     | 63    | 2.5 / 2.8 / 3.1    |
| David A. Cuadrado      | 731    | 111     | 35    | 1.2 / 2.6 / 1.7    |
| Jonas Ängeslevä        | 705    | 148     | 51    | 1.1 / 3.4 / 2.5    |
| Diego Algorta          | 650    | 6       | 5     | 1.0 / 0.1 / 0.2    |
| Arash Rouhani          | 629    | 95      | 31    | 1.0 / 2.2 / 1.5    |
| Sofia Larsson          | 595    | 70      | 77    | 0.9 / 1.6 / 3.8    |
| Tor Arne Vestbø        | 527    | 51      | 97    | 0.8 / 1.2 / 4.7    |
| spontus                | 339    | 18      | 42    | 0.5 / 0.4 / 2.0    |
| Pontus                 | 225    | 49      | 34    | 0.4 / 1.1 / 1.7    |
+------------------------+--------+---------+-------+--------------------+

 

git commit 出现There was a problem with the editor ‘vi’

今天在Mac OS X 10.9.3上使用git的时候遇到这么一个问题,执行git commit操作会显示如下错误:
There was a problem with the editor ‘vi’

搜寻了一下相关的解决方案,发现好多人遇到了这个问题。似乎是因为vim的返回值有问题导致的。
所以执行一下下面这条命令:
$ git config –global core.editor /usr/bin/vim
将git使用的编辑器强制指定一下,就可以正常使用了。具体的错误分析就不翻译了,贴在下面:

I have had an annoying problem with git and vi. I like to use vim to edit my commit messages, but I’ve been hit with this annoying message every time I write the message and quit vim.

error: There was a problem with the editor ‘vi’
After a little bit of digging I found that this message is shown by git when the editor exits with a non-zero exit code. You can use $? to see the exit code of last script or application.

$ vim # then exit vim with :q immediately
$ echo $?
1
I’m still not sure why vim is exiting with non-zero exit code, but it is definitely related to my .vimrc – moving it to .vimrc.bak seemed to fix the problem. I’m using the excellent pathogen plugin to manage my vimfiles, so I plan to go through that and my installed plugins to find the cause of the problem.

There is a fix though, I’m not sure what’s causing this, but I found a post on the vim-mac mailing list which shows this:

$ vim # and exit with :q
$ echo $?
1
$ /usr/bin/vim # and exit with :q
$ echo $?
0
$ which vim
/usr/bin/vim
Running vim with /usr/bin/vim seems to make it exit cleanly. So to fix the problem with git commit you just need to run this:

$ git config –global core.editor /usr/bin/vim
I’d still like to get to the root of the problem, but this gets me my git commit messages back!

Git教程系列-详细版(转载收藏)

http://blog.enjoyrails.com/2008/12/28/git%E8%AF%A6%E8%A7%A3%EF%BC%88%E4%B8%80%EF%BC%89/

http://www.5iphp.com/node/124

 

流程:取代码 → 每次工作前更新代码到最新版本 → 修改代码 → 提交代码到服务器

取代码及修改全局设置

设置用户名与邮箱

1
2
git config --global user.name "My Name"
git config --global user.email "my@email.com"

从已有的git库中提取代码

1
git clone git@server:app.git myrepo

每次更改代码的操作

更新本地代码到最新版本(需要merge才能合到本地代码中)

1
git fetch

合并更新后的代码到本地

1
git merge

更新代码方式的另一种方法(git pull是git fetch和git merge命令的一个组合)

1
git pull

修改代码后,查看已修改的内容

1
git diff --cached

将新增加文件加入到git中

1
git add file1 file2 file3

从git中删除文件

1
2
git rm file1
git rm -r dir1

提交修改

1
git commit -m 'this is memo'

如果想省掉提交之前的 git add 命令,可以直接用

1
git commit -a -m 'this is memo'

commit和commit -a的区别, commit -a相当于:

  • 第一步:自动地add所有改动的代码,使得所有的开发代码都列于index file中
  • 第二步:自动地删除那些在index file中但不在工作树中的文件
  • 第三步:执行commit命令来提交

提交所有修改到远程服务器,这样,其它团队成员才能更新到这些修改

1
git push

其它常用命令

显示commit日志

1
git log

不仅显示commit日志,而且同时显示每次commit的代码改变。

1
git log -p

回滚代码:

1
git revert HEAD

你也可以revert更早的commit,例如:

1
git revert HEAD^

将branchname分支合并到当前分支中。(如果合并发生冲突,需要自己解决冲突)

1
git merge branchname

解决冲突

当merge命令自身无法解决冲突的时候,它会将工作树置于一种特殊的状态,并且给用户提供冲突信息,以期用户可以自己解决这些问题。当然在这个时候,未发生冲突的代码已经被git merge登记在了index file里了。如果你这个时候使用git diff,显示出来的只是发生冲突的代码信息。

在你解决了冲突之前,发生冲突的文件会一直在index file中被标记出来。这个时候,如果你使用git commit提交的话,git会提示:filename.txt needs merge

在发生冲突的时候,如果你使用git status命令,那么会显示出发生冲突的具体信息。

在你解决了冲突之后,你可以使用如下步骤来提交:

第一步(如果需要增加文件):

1
git add file1

第二步:

1
git commit