计算 git 存储库中每位作者的代码行数
Counting lines of code per author in a git repository
所以我和其他几个程序员在一个团队中,需要在我们的 git 存储库中获取每个作者的代码行数。这不仅仅意味着作者修改的行,因为那将包括空白行和注释行。理想情况下,我可以创建一个仅包含特定作者的提交的新分支(--author="BtheDestroyer"
我自己),然后使用 cloc
分别获取评论行数和代码行数。我试过使用
git log --author="BtheDestroyer" --format=%H > mycommits
git checkout --orphan mycommits
tac mycommits| while read sha; do git cherry-pick --no-commit ${sha}; done
然而,在最后一行中,我收到了大量以下错误:
filepath: unmerged (commit-id-1)
filepath: unmerged (commit-id-2)
error: your index file is unmerged.
fatal: cherry-pick failed
我也不确定这是否会通过过程中的其他提交结束快进。有什么想法吗?
回答我自己的问题:
我最终使用 git blame
和 Bourne shell 脚本循环遍历源文件夹中的不同文件,使用 grep
和 cut
将它们转换回代码,将输出组织到临时文件中,然后 运行 cloc
就可以了。
这是我的 shell 脚本,供任何想做类似事情的人使用(我在 ./Blame/
中有它,所以适当地更改 SOURCE
!):
#!/bin/bash
#Name of user to check
# If you have multiple usernames, separate them with a space
# The full name is not required, just enough to not be ambiguous
USERS="YOUR USERNAMES HERE"
#Directories
SOURCE=../source
for USER in $USERS
do
#clear blame files
echo "" > $USER-Blame.h
echo "" > $USER-Blame.cpp
echo "" > $USER-Blame.sh
echo "Finding blame for $USER..."
#C++ files
echo " Finding blame for C++ files..."
for f in $SOURCE/*.cpp
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.cpp"
done
#Header files
echo " Finding blame for Header files..."
for f in $SOURCE/*.h
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.h"
done
#Shell script files
echo " Finding blame for shell script files..."
for f in ./GetUSERBlame.sh
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.sh"
done
done
for USER in $USERS
do
#cloc
echo "Blame for all users found! Cloc-ing $USER..."
cloc $USER-Blame.* --quiet
#this line is for cleaning up the temporary files
#if you want to save them for future reference, comment this out.
rm $USER-Blame.* -f
done
这是我的单线:
function gitfilecontributors() { local perfile="false" ; if [[ = "-f" ]]; then perfile="true" ; shift ; fi ; if [[ $# -eq 0 ]]; then echo "no files given!" >&2 ; return 1 ; else local f ; { for f in "$@"; do echo "$f" ; git blame --show-email "$f" | sed -nE 's/^[^ ]* *.<([^>]*)>.*$/: /p' | sort | uniq -c | sort -r -nk1 ; done } | if [[ "$perfile" = "true" ]]; then tee /tmp/gitblamestats.txt ; else tee /tmp/gitblamestats.txt >/dev/null ; fi ; echo ; echo "total:" ; awk -v FS=' *: *' '/^ *[0-9]/{sums[] += } END { for (i in sums) printf("%7s : %s\n", sums[i], i)}' /tmp/gitblamestats.txt | sort -r -nk1 ; fi ; }
或换行符:
gitfilecontributors ()
{
local perfile="false";
if [[ = "-f" ]]; then
perfile="true";
shift;
fi;
if [[ $# -eq 0 ]]; then
echo "no files given!" 1>&2;
return 1;
else
local f;
{
for f in "$@";
do
echo "$f";
git blame --show-email "$f" | sed -nE 's/^[^ ]* *.<([^>]*)>.*$/: /p' | sort | uniq -c | sort -r -nk1;
done
} | if [[ "$perfile" = "true" ]]; then
tee /tmp/gitblamestats.txt;
else
tee /tmp/gitblamestats.txt > /dev/null;
fi;
echo;
echo "total:";
awk -v FS=' *: *' '/^ *[0-9]/{sums[] += } END { for (i in sums) printf("%7s : %s\n", sums[i], i)}' /tmp/gitblamestats.txt | sort -r -nk1;
fi
}
可使用您选择的四个文件夹。
选项 -f 显示每个文件,否则仅显示总数:
$ gitfilecontributors $(fd --type f '.*' source)
total:
139 : somebody@somewhere.de
29 : else.user@somewhere.de
9 : just.another@somewhere.de
gitfilecontributors -f $(fd --type f '.*' source)
source/040_InitialSetup.md
80 : somebody@somewhere.de
29 : else.user@somewhere.de
6 : just.another@somewhere.de
README.md
59 : somebody@somewhere.de
5 : whosthat@somewhere.de
3 : just.another@somewhere.de
total:
139 : somebody@somewhere.de
29 : else.user@somewhere.de
9 : just.another@somewhere.de
5 : whosthat@somewhere.de
所以我和其他几个程序员在一个团队中,需要在我们的 git 存储库中获取每个作者的代码行数。这不仅仅意味着作者修改的行,因为那将包括空白行和注释行。理想情况下,我可以创建一个仅包含特定作者的提交的新分支(--author="BtheDestroyer"
我自己),然后使用 cloc
分别获取评论行数和代码行数。我试过使用
git log --author="BtheDestroyer" --format=%H > mycommits
git checkout --orphan mycommits
tac mycommits| while read sha; do git cherry-pick --no-commit ${sha}; done
然而,在最后一行中,我收到了大量以下错误:
filepath: unmerged (commit-id-1)
filepath: unmerged (commit-id-2)
error: your index file is unmerged.
fatal: cherry-pick failed
我也不确定这是否会通过过程中的其他提交结束快进。有什么想法吗?
回答我自己的问题:
我最终使用 git blame
和 Bourne shell 脚本循环遍历源文件夹中的不同文件,使用 grep
和 cut
将它们转换回代码,将输出组织到临时文件中,然后 运行 cloc
就可以了。
这是我的 shell 脚本,供任何想做类似事情的人使用(我在 ./Blame/
中有它,所以适当地更改 SOURCE
!):
#!/bin/bash
#Name of user to check
# If you have multiple usernames, separate them with a space
# The full name is not required, just enough to not be ambiguous
USERS="YOUR USERNAMES HERE"
#Directories
SOURCE=../source
for USER in $USERS
do
#clear blame files
echo "" > $USER-Blame.h
echo "" > $USER-Blame.cpp
echo "" > $USER-Blame.sh
echo "Finding blame for $USER..."
#C++ files
echo " Finding blame for C++ files..."
for f in $SOURCE/*.cpp
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.cpp"
done
#Header files
echo " Finding blame for Header files..."
for f in $SOURCE/*.h
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.h"
done
#Shell script files
echo " Finding blame for shell script files..."
for f in ./GetUSERBlame.sh
do
git blame "$f" | grep "$USER" | cut -c 70- >> "$USER-Blame.sh"
done
done
for USER in $USERS
do
#cloc
echo "Blame for all users found! Cloc-ing $USER..."
cloc $USER-Blame.* --quiet
#this line is for cleaning up the temporary files
#if you want to save them for future reference, comment this out.
rm $USER-Blame.* -f
done
这是我的单线:
function gitfilecontributors() { local perfile="false" ; if [[ = "-f" ]]; then perfile="true" ; shift ; fi ; if [[ $# -eq 0 ]]; then echo "no files given!" >&2 ; return 1 ; else local f ; { for f in "$@"; do echo "$f" ; git blame --show-email "$f" | sed -nE 's/^[^ ]* *.<([^>]*)>.*$/: /p' | sort | uniq -c | sort -r -nk1 ; done } | if [[ "$perfile" = "true" ]]; then tee /tmp/gitblamestats.txt ; else tee /tmp/gitblamestats.txt >/dev/null ; fi ; echo ; echo "total:" ; awk -v FS=' *: *' '/^ *[0-9]/{sums[] += } END { for (i in sums) printf("%7s : %s\n", sums[i], i)}' /tmp/gitblamestats.txt | sort -r -nk1 ; fi ; }
或换行符:
gitfilecontributors ()
{
local perfile="false";
if [[ = "-f" ]]; then
perfile="true";
shift;
fi;
if [[ $# -eq 0 ]]; then
echo "no files given!" 1>&2;
return 1;
else
local f;
{
for f in "$@";
do
echo "$f";
git blame --show-email "$f" | sed -nE 's/^[^ ]* *.<([^>]*)>.*$/: /p' | sort | uniq -c | sort -r -nk1;
done
} | if [[ "$perfile" = "true" ]]; then
tee /tmp/gitblamestats.txt;
else
tee /tmp/gitblamestats.txt > /dev/null;
fi;
echo;
echo "total:";
awk -v FS=' *: *' '/^ *[0-9]/{sums[] += } END { for (i in sums) printf("%7s : %s\n", sums[i], i)}' /tmp/gitblamestats.txt | sort -r -nk1;
fi
}
可使用您选择的四个文件夹。
选项 -f 显示每个文件,否则仅显示总数:
$ gitfilecontributors $(fd --type f '.*' source)
total:
139 : somebody@somewhere.de
29 : else.user@somewhere.de
9 : just.another@somewhere.de
gitfilecontributors -f $(fd --type f '.*' source)
source/040_InitialSetup.md
80 : somebody@somewhere.de
29 : else.user@somewhere.de
6 : just.another@somewhere.de
README.md
59 : somebody@somewhere.de
5 : whosthat@somewhere.de
3 : just.another@somewhere.de
total:
139 : somebody@somewhere.de
29 : else.user@somewhere.de
9 : just.another@somewhere.de
5 : whosthat@somewhere.de