Git: แสดงการเปลี่ยนแปลงต่างๆทั้งหมดเป็นบรรทัดเดียวในไฟล์ที่ระบุในประวัติคอมไพล์ทั้งหมด


112

ฉันมองไปรอบ ๆ แล้วและไม่แน่ใจว่าจะเป็นไปได้หรือไม่ แต่ต่อไปนี้:

ฉันมีไฟล์ (javascript) (พูด /lib/client.js) ซึ่งฉันมีตัวระบุเฉพาะที่กำหนดให้กับตัวแปรดังนี้: var identifier = "SOME_IDENTIFIER";

คุณสามารถคิดว่าตัวระบุเป็นหมายเลขเวอร์ชัน: เราจะเปลี่ยนตัวแปรนี้เป็นตัวระบุใหม่เป็นระยะ

สิ่งที่ฉันต้องการทำคือค้นหาตัวระบุเฉพาะทั้งหมดที่เราเคยใช้ ฉันจะทำสิ่งนี้ด้วยคอมไพล์ได้อย่างไร

"var identifier ="ผมคิดว่าอาจจะมีวิธีการที่จะค้นหาผ่านประวัติศาสตร์คอมไพล์และพิมพ์การจับคู่สาย ฉันสามารถยกเลิกการหลอกลวงรายการนี้ด้วยตนเอง

อย่างไรก็ตามฉันขอขอบคุณสำหรับข้อมูลเชิงลึกที่นี่ ขอบคุณ.


คำตอบ:


106

ตั้งแต่ git 1.8.4มีวิธีตอบคำถามของคุณที่ตรงประเด็นกว่า

สมมติว่าบรรทัด110นั้นเป็นบรรทัดที่บอกvar identifier = "SOME_IDENTIFIER";จากนั้นทำสิ่งนี้:

git log -L110,110:/lib/client.js

สิ่งนี้จะส่งคืนทุกการกระทำที่แตะบรรทัดของรหัสนั้น

[ เอกสารประกอบ Git (ดูที่ paramenter บรรทัดคำสั่ง "-L")]


49

ดูหน้าคนสำหรับและgit-log gitdiffcoreฉันเชื่อว่าคำสั่งนี้ทำได้ แต่อาจไม่ถูกต้องนัก:

git log -G "var identifier =" file.js

แก้ไข:นี่คือการเริ่มต้นคร่าวๆสำหรับ bash script เพื่อแสดงเส้นจริง นี่อาจเป็นอีกสิ่งที่คุณกำลังมองหา

for c in $(git log -G "something" --format=%H -- file.js); do
    git --no-pager grep -e "something" $c -- file.js
done

ใช้git log -Gเพื่อค้นหาคอม--format=%Hมิตที่น่าสนใจโดยใช้เพื่อสร้างรายการคอมมิตแฮช จากนั้นจะวนซ้ำบนคอมมิตที่น่าสนใจแต่ละรายการโดยขอgit grepให้แสดงบรรทัดจากคอมมิตและไฟล์ที่มี regex นำหน้าด้วยคอมมิตแฮช


แก้ไข:เปลี่ยนเป็นใช้-Gแทน-Sตามที่แนะนำในความคิดเห็น


@Rob - ขอบคุณสำหรับสิ่งนี้ - การแก้ไขสคริปต์ของคุณเพียงเล็กน้อย - การใส่ชื่อไฟล์จะแสดงเฉพาะการคอมมิตที่มีผลกับไฟล์นั้นเท่านั้น - หากการกระทำที่อ้างถึงไฟล์อื่น ๆ จะไม่อยู่ในรายการ
Adrian Cornish

@AdrianCornish - ดีใจที่มีประโยชน์ ฉันคิดว่า OP ต้องการดูแค่ไฟล์เดียว แต่คุณค่อนข้างถูกต้องที่การลบชื่อไฟล์อาจเป็นสคริปต์ที่มีประโยชน์โดยทั่วไป
ปล้น

ฉันมีสถานการณ์ที่ยากลำบากมากขึ้น ไฟล์ที่เป็นปัญหาย้ายจาก paht_a / file ไปยัง path_b / file ตอนนี้เมื่อฉันทำใน path_b มันจะแสดงเฉพาะการเปลี่ยนแปลงเมื่อไฟล์ย้ายจาก path_a ไปยัง path_b ถ้าฉันทำใน path_a มันจะบอกฉันว่าร้ายแรง: อาร์กิวเมนต์ที่คลุมเครือ 'file': การแก้ไขที่ไม่รู้จักหรือเส้นทางที่ไม่ได้อยู่ในโครงสร้างการทำงาน
Andy Song

@AndySong - หากสตริงที่คุณกำลังค้นหาไม่ซ้ำกันมากพอบางทีคุณอาจละชื่อไฟล์ไว้และยังคงได้รับสิ่งที่คุณต้องการ
ปล้น

สะดวกกว่าสำหรับฉัน - วางบรรทัดว่างหลังการคอมมิตแต่ละครั้งระบุบรรทัด:sfile=path/to/some_file; sfind='string_to_find'; for c in $(git log -G $sfind --format=%H -- $sfile); do git --no-pager grep -e $sfind -n $c -- $sfile; echo; done
John_West

14

คุณสามารถทำได้ด้วย gitk:

gitk file.js

ในเมนูแบบเลื่อนลง "กระทำ" ให้เลือก "การเพิ่ม / การลบสตริง:" และในกล่องข้อความถัดจากนั้นให้ป้อน "var identifier =" และการคอมมิตที่เพิ่มหรือลบบรรทัดที่มีสตริงนั้นจะถูกไฮไลต์


สิ่งนี้ช่วยระบุการคอมมิตที่เพิ่มบรรทัดที่มี "var identifier =" แต่ไม่แสดงคอมมิตที่แก้ไขบรรทัดนี้ในภายหลัง
findchris

2
คุณเคยลองgit blame file.jsหรือยังgit gui blame file.js?
Ethan Brown

1
ฉันรู้ว่าคำตำหนิทำอะไร; ฉันกำลังมองหาประวัติการแก้ไขทั้งหมดไม่ใช่ความแตกต่างเพียงครั้งเดียว
findchris

1
git gui blame file.jsจะทำเช่นนั้น ... มันจะแสดงการแก้ไขทั้งหมดของไฟล์และใครเป็นผู้เปลี่ยนแปลง คุณสามารถคลิกย้อนกลับผ่านประวัติ
Ethan Brown

ฉันลงเอยด้วยการก้าวผ่านสายตาด้วย gitk ฉันคิดว่ามีเทคนิคการคอมไพล์ที่ยอดเยี่ยมในการทำสิ่งนี้ แต่ gitk ก็ดีพอ ขอบคุณ.
findchris

9

หากคุณปรับคำตอบของ @ rob เพียงเล็กน้อยgit logโดยพื้นฐานแล้วจะทำเพื่อคุณหากสิ่งที่คุณต้องการคือการเปรียบเทียบด้วยภาพ:

git log -U0 -S "var identifier =" path/to/file

-U0หมายถึงเอาต์พุตในโหมดแพทช์ ( -p) และแสดงบริบทเป็นศูนย์รอบ ๆ แพตช์

คุณสามารถทำได้ในทุกสาขา:

git log -U0 -S "var identifier =" branchname1 branchname2 -- path/to/file

อาจมีวิธีระงับส่วนหัว diff แต่ฉันไม่รู้อย่างใดอย่างหนึ่ง


ทำงานให้ฉัน! ขอบคุณ.
Roberto Bonini

3

ในmagitคุณสามารถทำได้ด้วย

l, =L

จากนั้นจะขอไฟล์และเริ่มต้นและสิ้นสุดบรรทัด

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