วิธีดึงวันที่แก้ไขล่าสุดของไฟล์ทั้งหมดในที่เก็บ git


64

ฉันรู้วิธีดึงวันที่แก้ไขล่าสุดของไฟล์เดียวในที่เก็บ git:

git log -1 --format="%ad" -- path/to/file

มีวิธีที่ง่ายและมีประสิทธิภาพในการทำเช่นเดียวกันสำหรับไฟล์ทั้งหมดที่มีอยู่ในพื้นที่เก็บข้อมูลหรือไม่?

คำตอบ:


74

คำตอบง่ายๆคือการวนซ้ำในแต่ละไฟล์และแสดงเวลาการแก้ไขเช่น

git ls-tree -r --name-only HEAD | while read filename; do
  echo "$(git log -1 --format="%ad" -- $filename) $filename"
done

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

Fri Dec 23 19:01:01 2011 +0000 Config
Fri Dec 23 19:01:01 2011 +0000 Makefile

เห็นได้ชัดว่าคุณสามารถควบคุมสิ่งนี้ได้เนื่องจากเป็นเพียงสคริปต์ทุบตี ณ จุดนี้ - อย่าลังเลที่จะปรับแต่งให้เข้ากับเนื้อหาหัวใจของคุณ!


2
ฉันหวังว่าจะมีตัวเลือกในการรับเอาต์พุตที่รวมกันในการเรียกใช้ git log เพียงครั้งเดียว แต่คำตอบของคุณดีกว่าคำตอบที่ฉันใช้ในการค้นหา ฉันไม่รู้จัก git-ls-tree ซึ่งมีข้อได้เปรียบในการแสดงรายการเฉพาะไฟล์ที่เก็บในที่เก็บข้ามโฟลเดอร์. git และข้ามไฟล์ ขอบคุณ
Eric Bréchemier

ไม่มีปัญหา Eric; คุณกำลังติดตามเส้นทางเดียวกับที่ฉันทำ - คือทำการค้นหาและเพิกเฉยไดเรกทอรี. git! :) อาจมีบางตัวเลือกที่ใช้คำสั่ง git plumbing แต่ค่อนข้างตรงไปตรงมามันใช้งานได้ดี หากคุณสามารถหาวิธีรับข้อมูลแบบต่อไฟล์ได้ในคราวเดียวนั่นจะเป็นการดีที่สุด - แต่อย่าลืมว่าคอมไพล์ทำงานในสถานะของการกระทำไม่ใช่สถานะของไฟล์แต่ละไฟล์
Andrew M.

11
ฉันขอแนะนำให้ใช้ --format = "% ai" ถ้าคุณต้องการให้การประทับเวลาเรียงได้แทนที่จะเป็นวันที่มนุษย์อ่านได้
ThorSummoner

2
เนื่องจาก "HEAD" เป็นเพียงการอ้างอิงคุณสามารถใช้การอ้างอิงใด ๆ ที่คุณต้องการไม่ว่าจะเป็นแท็กสาขากระทำการแฮช ฯลฯ
Andrew M.

1
ตามที่ @ThorSummoner กล่าวว่าให้ใช้รูปแบบ% ai สำหรับวันที่แล้วเพียงไปที่ท่อเพื่อเรียงลำดับผลลัพธ์:git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort
John Hunt

21

วิธีการนี้ยังใช้งานได้กับชื่อไฟล์ที่มีช่องว่าง:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {}

ตัวอย่างผลลัพธ์:

2015-11-03 10:51:16 -0500 .gitignore
2016-03-30 11:50:05 -0400 .htaccess
2015-02-18 12:20:26 -0500 .travis.yml
2016-04-29 09:19:24 +0800 2016-01-13-Atlanta.md
2016-04-29 09:29:10 +0800 2016-03-03-Elmherst.md
2016-04-29 09:41:20 +0800 2016-03-03-Milford.md
2016-04-29 08:15:19 +0800 2016-03-06-Clayton.md
2016-04-29 01:20:01 +0800 2016-03-14-Richmond.md
2016-04-29 09:49:06 +0800 3/8/2016-Clayton.md
2015-08-26 16:19:56 -0400 404.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-bradycardia-algorithm.htm
2015-12-23 17:03:51 -0500 _algorithms/acls-pulseless-arrest-algorithm-asystole.htm
2016-04-11 15:00:42 -0400 _algorithms/acls-pulseless-arrest-algorithm-pea.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-secondary-survey.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-suspected-stroke-algorithm.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-tachycardia-algorithm-stable.htm
...

เอาต์พุตสามารถเรียงลำดับตามการประทับเวลาการแก้ไขโดยการเพิ่ม| sortที่ส่วนท้าย:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort

มีวิธีใดบ้างที่จะจัดเรียงสิ่งนี้โดยแก้ไขเวลาประทับ
Amelio Vazquez-Reina

1
@ AmelioVazquez-Reina: เพียงแค่เพิ่ม `| จัดเรียง `ถึงจุดสิ้นสุดของคำสั่ง
dotancohen

2
ใช้งานได้ แต่ต้องใช้เวลานาน ...
Guillochon

5

นี่เป็นคำตอบเล็ก ๆ ของ Andrew M. (ฉันไม่สามารถแสดงความคิดเห็นกับคำตอบของเขา)

ใส่ชื่อไฟล์ $ ชื่อแรกด้วยเครื่องหมายคำพูดคู่เพื่อรองรับชื่อไฟล์ที่มีช่องว่างในตัว

git ls-tree -r --name-only HEAD | while read filename; do
    echo "$(git log -1 --format="%ad" -- "$filename") $filename"
done

ตัวอย่างผลลัพธ์:

Tue Jun 21 11:38:43 2016 -0600 subdir/this is a filename with spaces.txt

ฉันซาบซึ้งที่ทางออกของแอนดรูว์ (บนพื้นฐานของls-tree ) ทำงานได้กับที่เก็บเปลือย! (นี่ไม่เป็นความจริงสำหรับโซลูชันที่ใช้ ls-files)


นอกจากนี้คุณยังสามารถข้าม echo: git log -1 --format = "% ad $ filename"
Kevin Lyda

0

นี่คือคำตอบของ Andrew M สำหรับรุ่นที่ใช้ปลา

git ls-tree -r --name-only HEAD | while read -l filename
    printf '%s %s\n' (git log -1 --format="%ai" -- $filename) $filename
end

ฉันเก็บสิ่งนี้เป็นฟังก์ชั่นปลาเพื่อให้เข้าถึงได้ง่าย


0

สำหรับพวกเราที่ใช้ Windows และ PowerShell คำตอบของ Andrew M พร้อมกับปรับแต่งคอมพิวเตอร์ที่อ่านได้:

git ls-tree -r --name-only HEAD | ForEach-Object { "$(git log -1 --format="%ai" -- "$_")`t$_" }

ตัวอย่างผลลัพธ์:

2019-05-07 12:00:37 -0500   .editorconfig
2016-07-13 14:03:49 -0500   .gitattributes
2019-05-07 12:00:37 -0500   .gitignore
2018-02-03 22:01:17 -0600   .mailmap
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.