ฉันจะคำนวณจำนวนบรรทัดที่เปลี่ยนแปลงระหว่างสองคอมมิตในคอมไพล์ได้อย่างไร?


746

มีวิธีง่าย ๆ ในการคำนวณจำนวนบรรทัดที่มีการเปลี่ยนแปลงระหว่างสองคอมมิตในคอมไพล์หรือไม่?

ฉันรู้ว่าฉันสามารถทำgit diffและนับบรรทัด แต่ดูเหมือนน่าเบื่อ ฉันต้องการทราบว่าฉันสามารถทำสิ่งนี้ได้อย่างไรรวมถึงการกระทำของตัวเองในจำนวนบัญชี


3
คุณดูที่ BitBucket
Alex78191

คำตอบ:


1112

คุณต้องการ--statตัวเลือกgit diffหรือถ้าคุณต้องการแยกวิเคราะห์ในสคริปต์--numstatตัวเลือก

git diff --stat <commit-ish> <commit-ish>

--statสร้างเอาต์พุตที่มนุษย์อ่านได้ที่คุณเคยเห็นหลังจากการผสาน --numstatสร้างเลย์เอาต์ตารางที่ดีที่สคริปต์สามารถตีความได้อย่างง่ายดาย

ฉันอย่างใดพลาดที่คุณกำลังมองหาที่จะทำเช่นนี้ในกระทำหลายอย่างในเวลาเดียวกัน - git logที่งานสำหรับ Ron DeVera ได้สัมผัสกับสิ่งนี้ แต่จริงๆแล้วคุณสามารถทำได้มากกว่าสิ่งที่เขาพูดถึง ตั้งแต่git logภายในเรียกเครื่องจักร diff เพื่อพิมพ์ข้อมูลที่ต้องการคุณสามารถให้ตัวเลือกใด ๆ สถิติ diff - --shortstatไม่เพียง สิ่งที่คุณต้องการใช้คือ:

git log --author="Your name" --stat <commit1>..<commit2>

แต่คุณสามารถใช้--numstatหรือ--shortstatเช่นกัน git logยังสามารถเลือกกระทำในหลากหลายวิธีการอื่น ๆ - มีลักษณะที่เป็นเอกสาร คุณอาจสนใจในสิ่งต่าง ๆ เช่น--since(แทนที่จะระบุช่วงการกระทำเพียงเลือกการกระทำตั้งแต่สัปดาห์ที่แล้ว) และ--no-merges(การรวมการกระทำไม่แนะนำการเปลี่ยนแปลงจริง ๆ ) รวมถึงตัวเลือกผลลัพธ์ที่น่ารัก ( --pretty=oneline, short, medium, full...)

ต่อไปนี้เป็นหนึ่งบรรทัดเพื่อรับการเปลี่ยนแปลงทั้งหมดแทนการเปลี่ยนแปลงที่กระทำต่อจากบันทึกการคอมไพล์ (เปลี่ยนตัวเลือกการเลือกการส่งตามที่ต้องการ - คุณยอมรับจาก comm1 ถึง commit2):

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

(คุณต้องให้ log git พิมพ์ข้อมูลที่ระบุบางอย่างเกี่ยวกับการคอมมิตฉันเลือก hash โดยพลการจากนั้นใช้ awk เพื่อเลือกเฉพาะบรรทัดที่มีสามฟิลด์ซึ่งเป็นข้อมูลที่มีสถิติ)


2
สิ่งนี้ไม่ได้ตอบคำถามเดิมเกี่ยวกับ "สายที่เปลี่ยนแปลง" การเปลี่ยนแปลงหนึ่งบรรทัดจะถูกคำนวณทั้งการแทรกและลบบรรทัด การคำนวณจำนวนบรรทัดที่เปลี่ยนแปลงต้องใช้งานมากกว่าที่อธิบายไว้ที่นี่
Ville Laitila

12
@VilleLaitila: นี่ใกล้เคียงที่สุดเท่าที่จะทำได้โดยไม่ต้องใช้ความพยายามอย่างไร้สาระและมันก็ดีพอสำหรับ OP และอีก 15 คน (คุณจะกำหนดได้อย่างไรเมื่อบรรทัดที่ถูกเปลี่ยนกลายเป็นบรรทัดที่เพิ่มและบรรทัดที่ถูกลบโดยการแก้ไขระยะห่างระหว่าง - และ + บรรทัดเป็นเศษส่วนของความยาวบรรทัด?) เราทุกคนรู้ว่าการเปลี่ยนแปลงเพิ่มขึ้นเป็นสองเท่า เราสามารถเรียกสิ่งนั้นว่าเมตริกที่มีประโยชน์ของจำนวนการเปลี่ยนแปลงและดำเนินชีวิตของเราต่อไป
Cascabel

188
git diff --shortstat <commit1> <commit2>เป็นคนที่ฉันต้องการ
คิม

9
สำหรับการอ้างอิงรูปแบบวันที่--sinceและ--untilเป็นสิ่งที่ชอบyesterday, 1 month 2 weeks 3 days 1 hour 1 second agoหรือ1979-02-26 18:30:00
juanmirocks

4
@Bryson ใช่นั่นคือสาเหตุที่บรรทัดนั้นบอกว่า<commit-ish>- ทำงานได้กับทุกสิ่งที่แสดงถึงความมุ่งมั่นรวมถึงการกระทำตามตัวอักษร, กิ่ง, แท็กและการอ้างอิง ดูstackoverflow.com/questions/23303549/…
Cascabel

193

git log --statสำหรับคนขี้เกียจใช้


14
ฉันพบว่ามีประโยชน์นี้เพิ่ม a -10เพื่อแสดงการกระทำที่สิบก่อนหน้านี้
Choylton B. Higginbottom

2
เมื่อคุณดูประวัติการส่งข้อมูลเสร็จแล้วให้พิมพ์Qเพื่อกลับไปที่เทอร์มินัล
Stevoisiak

180
git diff --shortstat

ให้เพียงจำนวนบรรทัดที่มีการเปลี่ยนแปลงและเพิ่ม สิ่งนี้ใช้ได้กับการเปลี่ยนแปลงที่ไม่มีการกำหนดระยะเวลาเท่านั้น เพื่อเปรียบเทียบกับสาขา:

git diff --shortstat some-branch

3
เย็น! แต่ .. โปรดทราบว่านี่จะใช้ได้กับการเปลี่ยนแปลงที่ไม่มีการ
กำหนดเวลาเท่านั้น

3
หากคุณทำการเปลี่ยนแปลงด้วยgit addให้แน่ใจว่าได้ทำgit diff --shortstat --cached
TomNash

เปลี่ยนไฟล์ 2463 ไฟล์แทรก 39745 (+), ลบ 21383 (-) ฉันได้ลบประมาณ 5k ถึง 10k ในเดือนที่แล้ว มันเกือบทั้งหมดที่ฉันได้ทำนอกเหนือจากการเคลื่อนไหวสิ่งต่าง ๆ บางสิ่งบางอย่างที่ไม่ถูกต้อง. มันไม่รวมไฟล์ที่ถูกลบหรืออะไรบางอย่าง?
jgmjgm

46
git diff --stat commit1 commit2

แก้ไข: คุณต้องระบุการกระทำเช่นกัน (ไม่มีพารามิเตอร์มันเปรียบเทียบไดเรกทอรีการทำงานกับดัชนี) เช่น

git diff --stat HEAD^ HEAD

เพื่อเปรียบเทียบแม่ของกับHEADHEAD


1
ไม่จำเป็นต้องใช้จริงๆdiff-index- diffส่วนหน้าสามารถจัดการทุกอย่างได้ กรณีที่diff-indexถูกปกคลุมด้วย--cached/--stagedผมเชื่อว่า (และไม่มีทางที่จะใช้diff-indexเพื่อเปรียบเทียบการกระทำสองอย่างตามอำเภอใจตามที่ OP ขอ)
Cascabel

ผลลัพธ์ของสิ่งนี้คืออะไรสำหรับฉัน
Mike

@ Mike: คุณเลิกกะรัตหรือไม่? การคอมมิชชันล่าสุดของคุณเป็นการคอมมิชชันหรือไม่? ถ้า git บอกว่าไม่มีความต่างก็เป็นเพราะมันไม่ต่างกัน
Cascabel

6
หรือถ้าปราศจากข้อผูกมัดgit diff --stat HEAD
wieczorek1990

1
นอกจากนี้คุณสามารถเปรียบเทียบย้อนกลับไปได้มากกว่าเพียงแค่ผู้ปกครองโดยใช้HEAD~nซึ่งnเป็นวิธีที่คุณต้องการกลับไปไกลแค่ไหน git diff --stat HEAD~5 HEADจะแสดงสถิติรวมสำหรับ 5 การกระทำล่าสุดที่สัมพันธ์กับ HEAD
Nathan Beck

18

สมมติว่าคุณต้องการเปรียบเทียบข้อผูกพันทั้งหมดระหว่าง abcd123 (การส่งครั้งแรก) กับ wxyz789 (การส่งครั้งสุดท้าย) รวม:

git log wxyz789^..abcd123 --oneline --shortstat --author="Mike Surname"

สิ่งนี้จะให้ผลลัพธ์ที่กระชับเช่น:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)

ผลลัพธ์ของสิ่งนี้คืออะไรสำหรับฉัน (ฉันได้ทำคอมมิชชันและตรวจสอบแล้ว - อนุญาตถูกต้องโดยใช้กับบันทึก git และไม่มีข้อโต้แย้งอื่น ๆ )
Mike

เรื่องนี้เกิดขึ้นกับฉันด้วย ความมุ่งมั่นทั้งสองอยู่ในลำดับที่ไม่ถูกต้องสลับพวกเขาไปรอบ ๆ แก้ไขมัน
bob esponja

1
อัปเดตคำสั่งการส่งและชี้แจงสิ่งที่ SHA ทั้งสองเป็นตัวแทน ขอบคุณที่จับมัน :)
Ron DeVera

3
--shortstatธงเป็นที่น่ากลัวจะทำงานร่วมกับgit diffแม้ว่า (ไม่ได้git log)
lucke84

จะสรุปได้อย่างไร
xpto

13

อีกวิธีหนึ่งในการรับบันทึกการเปลี่ยนแปลงทั้งหมดในช่วงเวลาที่กำหนด

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10"

เอาท์พุท:

2637cc736 Revert changed code
 1 file changed, 5 insertions(+), 5 deletions(-)
ba8d29402 Fix review
 2 files changed, 4 insertions(+), 11 deletions(-)

ด้วยเนื้อหาที่ส่งออกยาวคุณสามารถส่งออกไปยังไฟล์เพื่อให้อ่านง่ายขึ้น

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10" > /mnt/MyChangeLog.txt

2

แม้ว่าคำตอบข้างต้นจะถูกต้องด้านล่างคำตอบที่ง่ายต่อการใช้หากคุณต้องการนับจำนวนครั้งล่าสุด

ด้านล่างหนึ่งจะได้รับการนับจาก 5 ครั้งสุดท้าย

git diff $(git log -5 --pretty=format:"%h" | tail -1) --shortstat

เพื่อรับการนับ 10 คอมมิทล่าสุด

git diff $(git log -10 --pretty=format:"%h" | tail -1) --shortstat

ทั่วไป - เปลี่ยน N โดยนับจำนวนครั้งล่าสุดที่คุณต้องการ

git diff $(git log -N --pretty=format:"%h" | tail -1) --shortstat

ที่จะได้รับนับกระทำทั้งหมดตั้งแต่เริ่มต้น

git diff $(git log --pretty=format:"%h" | tail -1) --shortstat


สิ่งนี้ทำให้ "หาง" ไม่ได้รับการยอมรับว่าเป็นคำสั่งภายในหรือภายนอกโปรแกรมที่ทำงานได้หรือไฟล์แบตช์ "
Charles Roddie


1

ฉันเพิ่งแก้ไขปัญหานี้ด้วยตัวเองดังนั้นฉันจะแบ่งปันสิ่งที่ฉันคิดขึ้นมา นี่คือผลลัพธ์สุดท้าย:

> git summary --since=yesterday
total: 114 file changes, 13800 insertions(+) 638 deletions(-)

คำสั่งพื้นฐานมีลักษณะเช่นนี้:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'

หมายเหตุ$@ในคำสั่งเข้าสู่ระบบเพื่อส่งผ่านข้อโต้แย้งของคุณเช่นหรือ--author="Brian"--since=yesterday

การหลบหนี awk เพื่อใส่ลงในนามแฝงคอมไพล์นั้นยุ่งดังนั้นแทนฉันใส่มันลงในสคริปต์ปฏิบัติการบนเส้นทางของฉัน ( ~/bin/git-stat-sum) จากนั้นใช้สคริปต์ในนามแฝงใน.gitconfig:

[alias]
    summary = !git-stat-sum \"$@\"

และมันใช้งานได้ดีจริงๆ สิ่งสุดท้ายที่ควรทราบคือfile changesจำนวนการเปลี่ยนแปลงของไฟล์ไม่ใช่จำนวนไฟล์ที่เปลี่ยนแปลง นั่นคือสิ่งที่ฉันกำลังมองหา แต่อาจไม่ใช่สิ่งที่คุณคาดหวัง

นี่คืออีกตัวอย่างหรือสอง

git summary --author=brian
git summary master..dev
# combine them as you like
git summary --author=brian master..dev
git summary --all

จริงๆคุณควรจะสามารถแทนที่คำสั่งด้วยgit loggit summary

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.