มีคำสั่งที่ฉันสามารถเรียกใช้ซึ่งจะนับบรรทัดที่เปลี่ยนแปลงโดยผู้แต่งเฉพาะในที่เก็บ Git หรือไม่? ฉันรู้ว่าต้องมีวิธีนับจำนวนการคอมมิชชันที่ Github ทำกับกราฟผลกระทบ
มีคำสั่งที่ฉันสามารถเรียกใช้ซึ่งจะนับบรรทัดที่เปลี่ยนแปลงโดยผู้แต่งเฉพาะในที่เก็บ Git หรือไม่? ฉันรู้ว่าต้องมีวิธีนับจำนวนการคอมมิชชันที่ Github ทำกับกราฟผลกระทบ
คำตอบ:
ผลลัพธ์ของคำสั่งต่อไปนี้ควรจะง่ายต่อการส่งไปยังสคริปต์เพื่อเพิ่มผลรวมทั้งหมด:
git log --author="<authorname>" --oneline --shortstat
สิ่งนี้ให้สถิติสำหรับการกระทำทั้งหมดบน HEAD ปัจจุบัน หากคุณต้องการที่จะเพิ่มขึ้นสถิติในสาขาอื่น ๆ git log
ที่คุณจะต้องจ่ายให้เป็นข้อโต้แย้งที่จะ
สำหรับการส่งผ่านสคริปต์การลบแม้กระทั่งรูปแบบ "ออนไลน์" สามารถทำได้ด้วยรูปแบบบันทึกที่ว่างเปล่าและตามความเห็นของ Jakub Narębski --numstat
ก็เป็นอีกทางเลือกหนึ่ง มันสร้างต่อไฟล์แทนที่จะเป็นสถิติต่อบรรทัด แต่ง่ายกว่าในการแยกวิเคราะห์
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
แทน--shortstat
หากคุณต้องการเพิ่มสถิติได้ง่ายขึ้นเล็กน้อย
git help log
บอกฉันว่าบรรทัดแรกคือการเพิ่มบรรทัดบรรทัดที่สองถูกลบ
สิ่งนี้ให้สถิติบางอย่างเกี่ยวกับผู้แต่งแก้ไขตามที่ต้องการ
ใช้ Gawk:
git log --author="_Your_Name_Here_" --pretty=tformat: --numstat \
| gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }' -
ใช้ Awk บน Mac OSX:
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 }' -
มีแพ็คเกจใหม่บน github ที่ดูเนียนและใช้ bash เป็นการอ้างอิง (ทดสอบบน linux) เหมาะสำหรับการใช้งานโดยตรงมากกว่าสคริปต์
มันคอมไพล์อย่างรวดเร็วสถิติ (ลิงค์ GitHub)
คัดลอกgit-quick-stats
ไปยังโฟลเดอร์และเพิ่มโฟลเดอร์ไปยังเส้นทาง
mkdir ~/source
cd ~/source
git clone git@github.com:arzzen/git-quick-stats.git
mkdir ~/bin
ln -s ~/source/git-quick-stats/git-quick-stats ~/bin/git-quick-stats
chmod +x ~/bin/git-quick-stats
export PATH=${PATH}:~/bin
การใช้งาน:
git-quick-stats
gawk
เพื่อawk
ให้มันทำงานใน terminal OSX
git clone https://github.com/arzzen/git-quick-stats.git
ในกรณีที่ทุกคนต้องการที่จะเห็นสถิติสำหรับผู้ใช้ทุกคนใน codebase ของพวกเขาเพื่อนร่วมงานของฉันสองคนเพิ่งเกิดขึ้นกับซับในที่น่ากลัวนี้:
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";}'
(ใช้เวลาสองสามนาทีในการกระทืบผ่าน repo ของเราซึ่งมีภาระประมาณ 10-15k)
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Git fame https://github.com/oleander/git-fame-rb
เป็นเครื่องมือที่ดีในการรับจำนวนผู้เขียนทั้งหมดในครั้งเดียวรวมถึงการคอมมิทและไฟล์ที่ถูกแก้ไข:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
นอกจากนี้ยังมีเวอร์ชั่น Python ที่https://github.com/casperdcl/git-fame (พูดถึงโดย @fracz):
sudo apt-get install python-pip python-dev build-essential
pip install --user 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 มาก
git fame --branch=dev --timeout=-1 --exclude=Pods/*
ฉันพบว่าต่อไปนี้จะเป็นประโยชน์ในการดูว่าใครมีบรรทัดมากที่สุดที่อยู่ในฐานรหัสปัจจุบัน:
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 (-C -M) เพื่อให้ได้ตัวเลขที่ดีกว่าซึ่งนำการเคลื่อนไหวของไฟล์และการเคลื่อนไหวของบรรทัดระหว่างไฟล์มาพิจารณา แต่คำสั่งอาจทำงานได้นานขึ้นถ้าคุณทำ
นอกจากนี้หากคุณกำลังมองหาบรรทัดที่เปลี่ยนไปในทุกคอมมิทสำหรับคอมมิชชันทั้งหมดสคริปต์เล็ก ๆ น้อย ๆ ที่ติดตามจะมีประโยชน์
/^.*\((.*?)\s[\d]{4}/
ควร/^.*?\((.*?)\s[\d]{4}/
ป้องกันการจับคู่วงเล็บในแหล่งที่มาในฐานะผู้เขียน
ในการนับจำนวนการกระทำของผู้เขียนที่ได้รับ (หรือผู้เขียนทั้งหมด) ในสาขาที่กำหนดคุณสามารถใช้git-shortlog ; ดูโดยเฉพาะอย่างยิ่งมัน--numbered
และ--summary
ตัวเลือกเช่นเมื่อทำงานในพื้นที่เก็บข้อมูล git:
$ git shortlog v1.6.4 --numbered --summary
6904 Junio C Hamano
1320 Shawn O. Pearce
1065 Linus Torvalds
692 Johannes Schindelin
443 Eric Wong
v1.6.4
นี่ในตัวอย่างนี้เพื่อกำหนดเอาท์พุทกำหนด: มันจะเหมือนกันไม่ว่าเมื่อใดที่คุณโคลนและ / หรือดึงข้อมูลจากที่เก็บ git
v1.6.4
ให้ฉัน:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
หรือหากคุณไม่ต้องการรวมการผสานgit shortlog -sne --no-merges
-s
ถูก--summary
, -n
เป็น--numbered
และ [ใหม่] -e
คือ--email
จะแสดงอีเมลของผู้เขียน (และนับแยกผู้เขียนคนเดียวกันกับที่อยู่อีเมลที่แตกต่างกันโดยคำนึงถึง.mailmap
การแก้ไข) --no-merges
โทรดีเกี่ยวกับ
หลังจากดูคำตอบของ AlexและGerty3000ฉันได้ลองย่อขนาดหนึ่งซับ:
โดยทั่วไปการใช้ git log numstat และไม่ติดตามจำนวนไฟล์ที่เปลี่ยนแปลง
Git เวอร์ชั่น 2.1.0 บน Mac OSX:
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
ตัวอย่าง:
Jared Burrows added lines: 6826, removed lines: 2825, total lines: 4001
คำตอบจากAaronMใช้เปลือกหนึ่งซับเป็นสิ่งที่ดี แต่ที่จริงแล้วยังมีข้อผิดพลาดอีกที่ช่องว่างที่จะเสียหายชื่อผู้ใช้หากมีปริมาณที่แตกต่างกันของช่องว่างสีขาวระหว่างชื่อผู้ใช้และวันที่ ชื่อผู้ใช้ที่เสียหายจะให้หลายแถวสำหรับการนับจำนวนผู้ใช้และคุณต้องรวมพวกเขาเอง
การเปลี่ยนแปลงเล็กน้อยนี้แก้ไขปัญหาสำหรับฉัน:
git ls-files -z | xargs -0n1 git blame -w --show-email | perl -n -e '/^.*?\((.*?)\s+[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
สังเกตุเครื่องหมาย + หลัง \ s ซึ่งจะใช้ช่องว่างทั้งหมดจากชื่อจนถึงวันที่
จริงๆเพิ่มคำตอบนี้มากสำหรับความทรงจำของฉันเองเพื่อช่วยคนอื่น ๆ เนื่องจากอย่างน้อยครั้งที่สองที่ฉัน google เรื่อง :)
--show-email
เพื่อgit blame -w
รวมในอีเมลแทนเนื่องจากบางคนใช้Name
รูปแบบที่แตกต่างกันในคอมพิวเตอร์ที่แตกต่างกันและบางครั้งคนสองคนที่มีชื่อเดียวกันทำงานในคอมไพล์เดียวกันunsupported file type
อย่างอื่น แต่ดูเหมือนว่าจะทำงานได้ดีแม้กับพวกเขา
ต่อไปนี้เป็นหนึ่งบรรทัดสั้น ๆ ที่สร้างสถิติสำหรับผู้แต่งทั้งหมด มันเร็วกว่าวิธีแก้ปัญหาของ Dan ที่https://stackoverflow.com/a/20414465/1102119 (ฉันมีความซับซ้อนของเวลา O (N) แทน O (NM) โดยที่ N คือจำนวนของความมุ่งมั่นและ M จำนวนผู้เขียน )
git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = ""; next } END { for (a in ins) { printf "%10d %10d %10d %s\n", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn
--no-show-signature
มิฉะนั้นคนที่ pgp-sign จะไม่ถูกนับ
count-lines = "!f() { git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = \"\"; next } END { for (a in ins) { printf \"%10d %10d %10d %s\\n\", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn; }; f"
. (หมายเหตุผมใน Windows คุณอาจจำเป็นต้องใช้ชนิดที่แตกต่างของคำพูด)
@mmrobins @AaronM @ErikZ @JamesMishra ระบุตัวแปรที่ทุกคนมีปัญหาร่วมกัน: พวกเขาขอให้คอมไพล์สร้างข้อมูลผสมที่ไม่ได้มีไว้สำหรับการใช้สคริปต์รวมถึงเนื้อหาบรรทัดจากที่เก็บในบรรทัดเดียวกันจากนั้นจับคู่ระเบียบกับ regexp .
นี่เป็นปัญหาเมื่อบางบรรทัดไม่ถูกต้องข้อความ UTF-8 และเมื่อบางบรรทัดเกิดขึ้นเพื่อให้ตรงกับ regexp (เกิดขึ้นที่นี่)
นี่คือสายการแก้ไขที่ไม่มีปัญหาเหล่านี้ มันขอให้คอมไพล์เพื่อเอาท์พุทข้อมูลอย่างสะอาดในบรรทัดที่แยกต่างหากซึ่งทำให้ง่ายต่อการกรองสิ่งที่เราต้องการอย่างแข็งแกร่ง:
git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n
คุณสามารถ grep สำหรับสตริงอื่น ๆ เช่นผู้แต่งอีเมลผู้ส่ง ฯลฯ
บางทีอาจจะเป็นครั้งแรกexport LC_ALL=C
(สมมติว่าbash
) เพื่อบังคับการประมวลผลในระดับไบต์ (สิ่งนี้เกิดขึ้นเพื่อเร่งความเร็ว grep อย่างมากจากโลแคลที่อิง UTF-8)
วิธีการแก้ปัญหาที่ได้รับกับทับทิมอยู่ตรงกลาง, Perl จะมีน้อยมากโดยค่าเริ่มต้นที่นี่เป็นทางเลือกที่ใช้ Perl สำหรับบรรทัดปัจจุบันโดยผู้เขียน
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
นอกจากคำตอบของ Charles Baileyแล้วคุณอาจต้องการเพิ่ม-C
พารามิเตอร์ลงในคำสั่ง มิฉะนั้นการเปลี่ยนชื่อไฟล์จะนับเป็นการเพิ่มและลบจำนวนมาก (มากเท่ากับไฟล์ที่มีบรรทัด) แม้ว่าเนื้อหาไฟล์จะไม่ถูกแก้ไข
เพื่อแสดงให้เห็นนี่คือความมุ่งมั่นที่มีไฟล์จำนวนมากที่ถูกย้ายไปรอบ ๆ จากหนึ่งในโครงการของฉันเมื่อใช้git log --oneline --shortstat
คำสั่ง:
9052459 Reorganized project structure
43 files changed, 1049 insertions(+), 1000 deletions(-)
และที่นี่คอมมิทเดียวกันใช้git log --oneline --shortstat -C
คำสั่งที่ตรวจจับการคัดลอกไฟล์และเปลี่ยนชื่อ:
9052459 Reorganized project structure
27 files changed, 134 insertions(+), 85 deletions(-)
ในความคิดของฉันหลังให้มุมมองที่เป็นจริงมากขึ้นของผลกระทบต่อบุคคลที่มีต่อโครงการเนื่องจากการเปลี่ยนชื่อไฟล์เป็นการดำเนินการที่เล็กกว่าการเขียนไฟล์ตั้งแต่เริ่มต้น
คุณสามารถใช้ whodid ( https://www.npmjs.com/package/whodid )
$ npm install whodid -g
$ cd your-project-dir
และ
$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week
หรือเพียงพิมพ์
$ whodid
จากนั้นคุณสามารถเห็นผลลัพธ์เช่นนี้
Contribution state
=====================================================
score | author
-----------------------------------------------------
3059 | someguy <someguy@tensorflow.org>
585 | somelady <somelady@tensorflow.org>
212 | niceguy <nice@google.com>
173 | coolguy <coolgay@google.com>
=====================================================
-g
macOS
เพียงแค่พยายามช่วย
ต่อไปนี้เป็นสคริปต์ ruby ด่วนที่สัมพันธ์กับผลกระทบต่อผู้ใช้กับข้อความค้นหาที่ระบุ
ตัวอย่างเช่นสำหรับrubinius :
Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...
สคริปต์:
#!/usr/bin/env ruby
impact = Hash.new(0)
IO.popen("git log --pretty=format:\"%an\" --shortstat #{ARGV.join(' ')}") do |f|
prev_line = ''
while line = f.gets
changes = /(\d+) insertions.*(\d+) deletions/.match(line)
if changes
impact[prev_line] += changes[1].to_i + changes[2].to_i
end
prev_line = line # Names are on a line of their own, just before the stats
end
end
impact.sort_by { |a,i| -i }.each do |author, impact|
puts "#{author.strip}: #{impact}"
end
นี่เป็นวิธีที่ดีที่สุดและยังช่วยให้คุณเห็นภาพรวมจำนวนการกระทำทั้งหมดที่ผู้ใช้ทุกคนเห็นได้อย่างชัดเจน
git shortlog -s -n
ฉันให้การแก้ไขคำตอบสั้น ๆ ข้างต้น แต่มันก็ไม่เพียงพอสำหรับความต้องการของฉัน ฉันต้องการเพื่อให้สามารถจัดหมวดหมู่ทั้งบรรทัดที่มุ่งมั่นและบรรทัดในรหัสสุดท้าย ฉันยังต้องการแยกย่อยตามไฟล์ รหัสนี้จะไม่ทำการเรียกคืน แต่จะส่งคืนผลลัพธ์สำหรับไดเรกทอรีเดียว แต่เป็นการเริ่มต้นที่ดีถ้ามีคนต้องการไปเพิ่มเติม คัดลอกและวางลงในไฟล์และทำให้สามารถเรียกใช้หรือเรียกใช้ด้วย Perl
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $dir = shift;
die "Please provide a directory name to check\n"
unless $dir;
chdir $dir
or die "Failed to enter the specified directory '$dir': $!\n";
if ( ! open(GIT_LS,'-|','git ls-files') ) {
die "Failed to process 'git ls-files': $!\n";
}
my %stats;
while (my $file = <GIT_LS>) {
chomp $file;
if ( ! open(GIT_LOG,'-|',"git log --numstat $file") ) {
die "Failed to process 'git log --numstat $file': $!\n";
}
my $author;
while (my $log_line = <GIT_LOG>) {
if ( $log_line =~ m{^Author:\s*([^<]*?)\s*<([^>]*)>} ) {
$author = lc($1);
}
elsif ( $log_line =~ m{^(\d+)\s+(\d+)\s+(.*)} ) {
my $added = $1;
my $removed = $2;
my $file = $3;
$stats{total}{by_author}{$author}{added} += $added;
$stats{total}{by_author}{$author}{removed} += $removed;
$stats{total}{by_author}{total}{added} += $added;
$stats{total}{by_author}{total}{removed} += $removed;
$stats{total}{by_file}{$file}{$author}{added} += $added;
$stats{total}{by_file}{$file}{$author}{removed} += $removed;
$stats{total}{by_file}{$file}{total}{added} += $added;
$stats{total}{by_file}{$file}{total}{removed} += $removed;
}
}
close GIT_LOG;
if ( ! open(GIT_BLAME,'-|',"git blame -w $file") ) {
die "Failed to process 'git blame -w $file': $!\n";
}
while (my $log_line = <GIT_BLAME>) {
if ( $log_line =~ m{\((.*?)\s+\d{4}} ) {
my $author = $1;
$stats{final}{by_author}{$author} ++;
$stats{final}{by_file}{$file}{$author}++;
$stats{final}{by_author}{total} ++;
$stats{final}{by_file}{$file}{total} ++;
$stats{final}{by_file}{$file}{total} ++;
}
}
close GIT_BLAME;
}
close GIT_LS;
print "Total lines committed by author by file\n";
printf "%25s %25s %8s %8s %9s\n",'file','author','added','removed','pct add';
foreach my $file (sort keys %{$stats{total}{by_file}}) {
printf "%25s %4.0f%%\n",$file
,100*$stats{total}{by_file}{$file}{total}{added}/$stats{total}{by_author}{total}{added};
foreach my $author (sort keys %{$stats{total}{by_file}{$file}}) {
next if $author eq 'total';
if ( $stats{total}{by_file}{$file}{total}{added} ) {
printf "%25s %25s %8d %8d %8.0f%%\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}}
,100*$stats{total}{by_file}{$file}{$author}{added}/$stats{total}{by_file}{$file}{total}{added};
} else {
printf "%25s %25s %8d %8d\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}} ;
}
}
}
print "\n";
print "Total lines in the final project by author by file\n";
printf "%25s %25s %8s %9s %9s\n",'file','author','final','percent', '% of all';
foreach my $file (sort keys %{$stats{final}{by_file}}) {
printf "%25s %4.0f%%\n",$file
,100*$stats{final}{by_file}{$file}{total}/$stats{final}{by_author}{total};
foreach my $author (sort keys %{$stats{final}{by_file}{$file}}) {
next if $author eq 'total';
printf "%25s %25s %8d %8.0f%% %8.0f%%\n",'', $author,$stats{final}{by_file}{$file}{$author}
,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_file}{$file}{total}
,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_author}{total}
;
}
}
print "\n";
print "Total lines committed by author\n";
printf "%25s %8s %8s %9s\n",'author','added','removed','pct add';
foreach my $author (sort keys %{$stats{total}{by_author}}) {
next if $author eq 'total';
printf "%25s %8d %8d %8.0f%%\n",$author,@{$stats{total}{by_author}{$author}}{qw{added removed}}
,100*$stats{total}{by_author}{$author}{added}/$stats{total}{by_author}{total}{added};
};
print "\n";
print "Total lines in the final project by author\n";
printf "%25s %8s %9s\n",'author','final','percent';
foreach my $author (sort keys %{$stats{final}{by_author}}) {
printf "%25s %8d %8.0f%%\n",$author,$stats{final}{by_author}{$author}
,100*$stats{final}{by_author}{$author}/$stats{final}{by_author}{total};
}
สำหรับผู้ใช้ windows คุณสามารถใช้ชุดสคริปต์ต่อไปนี้ที่นับจำนวนเพิ่ม / ลบบรรทัดสำหรับผู้เขียนที่ระบุ
@echo off
set added=0
set removed=0
for /f "tokens=1-3 delims= " %%A in ('git log --pretty^=tformat: --numstat --author^=%1') do call :Count %%A %%B %%C
@echo added=%added%
@echo removed=%removed%
goto :eof
:Count
if NOT "%1" == "-" set /a added=%added% + %1
if NOT "%2" == "-" set /a removed=%removed% + %2
goto :eof
https://gist.github.com/zVolodymyr/62e78a744d99d414d56646a5e8a1ff4f
git-quick-stats
brew install git-quick-stats
git-quick-stats
เพียงเลือกตัวเลือกที่คุณต้องการจากรายการนี้โดยพิมพ์หมายเลขที่ปรากฏและกด Enter
Generate:
1) Contribution stats (by author)
2) Contribution stats (by author) on a specific branch
3) Git changelogs (last 10 days)
4) Git changelogs by author
5) My daily status
6) Save git log output in JSON format
List:
7) Branch tree view (last 10)
8) All branches (sorted by most recent commit)
9) All contributors (sorted by name)
10) Git commits per author
11) Git commits per date
12) Git commits per month
13) Git commits per weekday
14) Git commits per hour
15) Git commits by author per hour
Suggest:
16) Code reviewers (based on git history)
สคริปต์นี้ที่นี่จะทำมัน ใส่ไว้ใน authorship.sh, chmod + x และคุณก็พร้อมแล้ว
#!/bin/sh
declare -A map
while read line; do
if grep "^[a-zA-Z]" <<< "$line" > /dev/null; then
current="$line"
if [ -z "${map[$current]}" ]; then
map[$current]=0
fi
elif grep "^[0-9]" <<<"$line" >/dev/null; then
for i in $(cut -f 1,2 <<< "$line"); do
map[$current]=$((map[$current] + $i))
done
fi
done <<< "$(git log --numstat --pretty="%aN")"
for i in "${!map[@]}"; do
echo -e "$i:${map[$i]}"
done | sort -nr -t ":" -k 2 | column -t -s ":"
บันทึกบันทึกของคุณลงในไฟล์โดยใช้:
git log --author="<authorname>" --oneline --shortstat > logs.txt
สำหรับคนรักหลาม:
with open(r".\logs.txt", "r", encoding="utf8") as f:
files = insertions = deletions = 0
for line in f:
if ' changed' in line:
line = line.strip()
spl = line.split(', ')
if len(spl) > 0:
files += int(spl[0].split(' ')[0])
if len(spl) > 1:
insertions += int(spl[1].split(' ')[0])
if len(spl) > 2:
deletions += int(spl[2].split(' ')[0])
print(str(files).ljust(10) + ' files changed')
print(str(insertions).ljust(10) + ' insertions')
print(str(deletions).ljust(10) + ' deletions')
ผลลัพธ์ของคุณจะเป็นเช่น:
225 files changed
6751 insertions
1379 deletions
คำถามที่ถามหาข้อมูลเกี่ยวกับผู้เขียนที่เฉพาะเจาะจงแต่คำตอบจำนวนมากเป็นวิธีการแก้ปัญหาที่ส่งกลับรายชื่อผู้เขียนอันดับตามบรรทัดรหัสของพวกเขาเปลี่ยนไป
นี่คือสิ่งที่ฉันกำลังมองหา แต่โซลูชั่นที่มีอยู่ไม่ได้ค่อนข้างสมบูรณ์แบบ เพื่อประโยชน์ของผู้คนที่อาจพบคำถามนี้ผ่านทาง Google ฉันได้ทำการปรับปรุงบางอย่างและทำให้พวกเขากลายเป็นเชลล์สคริปต์ซึ่งฉันแสดงไว้ด้านล่าง หนึ่งข้อเขียน (ซึ่งผมจะยังคงรักษา) สามารถพบได้บน Github
ขณะนี้ไม่มีการอ้างอิงทั้ง Perl หรือทับทิม นอกจากนี้ช่องว่างการเปลี่ยนชื่อและการเคลื่อนไหวของเส้นจะถูกนำมาพิจารณาในการนับการเปลี่ยนแปลงบรรทัด ใส่สิ่งนี้ลงในไฟล์และส่งที่เก็บ Git ของคุณเป็นพารามิเตอร์แรก
#!/bin/bash
git --git-dir="$1/.git" log > /dev/null 2> /dev/null
if [ $? -eq 128 ]
then
echo "Not a git repository!"
exit 128
else
echo -e "Lines | Name\nChanged|"
git --work-tree="$1" --git-dir="$1/.git" ls-files -z |\
xargs -0n1 git --work-tree="$1" --git-dir="$1/.git" blame -C -M -w |\
cut -d'(' -f2 |\
cut -d2 -f1 |\
sed -e "s/ \{1,\}$//" |\
sort |\
uniq -c |\
sort -nr
fi
เครื่องมือที่ดีที่สุดที่ฉันระบุคือ gitinspector มันให้รายงานชุดต่อผู้ใช้ต่อสัปดาห์ ฯลฯ คุณสามารถติดตั้งเช่นด้านล่างด้วย npm
npm install -g gitinspector
ลิงค์เพื่อรับรายละเอียดเพิ่มเติม
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Documentation
https://github.com/ejwa/gitinspector
คำสั่งตัวอย่างคือ
gitinspector -lmrTw
gitinspector --since=1-1-2017 etc
ฉันเขียนสคริปต์ Perl นี้เพื่อทำงานให้สำเร็จ
#!/usr/bin/env perl
use strict;
use warnings;
# save the args to pass to the git log command
my $ARGS = join(' ', @ARGV);
#get the repo slug
my $NAME = _get_repo_slug();
#get list of authors
my @authors = _get_authors();
my ($projectFiles, $projectInsertions, $projectDeletions) = (0,0,0);
#for each author
foreach my $author (@authors) {
my $command = qq{git log $ARGS --author="$author" --oneline --shortstat --no-merges};
my ($files, $insertions, $deletions) = (0,0,0);
my @lines = `$command`;
foreach my $line (@lines) {
if ($line =~ m/^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\([\+|\-]\),\s(\d+)\s\w+\([\+|\-]\)$|^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\(([\+|\-])\)$/) {
my $lineFiles = $1 ? $1 : $4;
my $lineInsertions = (defined $6 && $6 eq '+') ? $5 : (defined $2) ? $2 : 0;
my $lineDeletions = (defined $6 && $6 eq '-') ? $5 : (defined $3) ? $3 : 0;
$files += $lineFiles;
$insertions += $lineInsertions;
$deletions += $lineDeletions;
$projectFiles += $lineFiles;
$projectInsertions += $lineInsertions;
$projectDeletions += $lineDeletions;
}
}
if ($files || $insertions || $deletions) {
printf(
"%s,%s,%s,+%s,-%s,%s\n",
$NAME,
$author,
$files,
$insertions,
$deletions,
$insertions - $deletions
);
}
}
printf(
"%s,%s,%s,+%s,-%s,%s\n",
$NAME,
'PROJECT_TOTAL',
$projectFiles,
$projectInsertions,
$projectDeletions,
$projectInsertions - $projectDeletions
);
exit 0;
#get the remote.origin.url joins that last two pieces (project and repo folder)
#and removes any .git from the results.
sub _get_repo_slug {
my $get_remote_url = "git config --get remote.origin.url";
my $remote_url = `$get_remote_url`;
chomp $remote_url;
my @parts = split('/', $remote_url);
my $slug = join('-', @parts[-2..-1]);
$slug =~ s/\.git//;
return $slug;
}
sub _get_authors {
my $git_authors = 'git shortlog -s | cut -c8-';
my @authors = `$git_authors`;
chomp @authors;
return @authors;
}
ผมตั้งชื่อมันและใส่ลงในgit-line-changes-by-author
/usr/local/bin
เนื่องจากมันถูกบันทึกไว้ในเส้นทางของฉันฉันสามารถออกคำสั่งgit line-changes-by-author --before 2018-12-31 --after 2020-01-01
เพื่อรับรายงานสำหรับปี 2019 ตัวอย่างเช่น. และถ้าฉันจะสะกดคำผิด git ชื่อจะแนะนำการสะกดที่เหมาะสม
คุณอาจต้องการปรับ_get_repo_slug
ย่อยเพื่อรวมเฉพาะส่วนสุดท้ายของรายการremote.origin.url
บันทึกของฉันเป็นproject/repo
และคุณอาจไม่
git://git.lwn.net/gitdm.git
ตัวอย่างเช่นพื้นที่เก็บข้อมูลอยู่ที่นี่