วิธีการค้นหา Git กระทำที่นำสตริงในสาขาใด?


396

ฉันต้องการที่จะหาสายบางอย่างซึ่งได้รับการแนะนำในการกระทำใด ๆ ในสาขาใดฉันจะทำเช่นนั้น? ฉันพบบางสิ่ง (ที่ฉันแก้ไขสำหรับ Win32) แต่git whatchangedดูเหมือนจะไม่ได้มองเข้าไปในสาขาที่แตกต่างกัน (ไม่สนใจก้อน py3k มันเป็นเพียง msys / win line feed fix)

git whatchanged -- <file> | \
grep "^commit " | \
python -c "exec(\"import sys,msvcrt,os\nmsvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)\nfor l in sys.stdin: print(l.split()[1])\")" | \
xargs -i% git show origin % -- <file>

ไม่สำคัญว่าทางออกของคุณช้าหรือไม่


ที่เกี่ยวข้องอย่างใกล้ชิด: วิธีการ grep คอมไพล์สำหรับคำที่แน่นอน

คำตอบ:


685

คุณทำได้:

git log -S <whatever> --source --all

เพื่อหากระทำทั้งหมดที่เพิ่มหรือลบสตริงคงที่ พารามิเตอร์หมายถึงการเริ่มต้นจากทุกสาขาและวิธีการที่จะแสดงให้เห็นว่าในสาขาเหล่านั้นจะนำไปสู่การค้นพบที่กระทำ บ่อยครั้งที่มีประโยชน์ในการเพิ่มเพื่อแสดงแพทช์ที่แต่ละคอมมิทเหล่านั้นแนะนำด้วยwhatever--all--source-p

รุ่นคอมไพล์ตั้งแต่ 1.7.4 ยังมีคล้ายตัวเลือกซึ่งจะมีการแสดงผลปกติ-G นี้ที่จริงมีแตกต่างกัน (และค่อนข้างชัดเจนมากขึ้น) ความหมายที่อธิบายไว้ในบล็อกโพสต์นี้จาก Junio Hamano

เมื่อthameeraชี้ให้เห็นในความคิดเห็นคุณจะต้องใส่เครื่องหมายคำพูดล้อมรอบข้อความค้นหาหากมีช่องว่างหรืออักขระพิเศษอื่น ๆ เช่น:

git log -S 'hello world' --source --all
git log -S "dude, where's my car?" --source --all

นี่คือตัวอย่างการใช้-Gเพื่อค้นหาสิ่งที่เกิดขึ้นfunction foo() {:

git log -G "^(\s)*function foo[(][)](\s)*{$" --source --all

19
+1 เพื่อความเป็นเลิศ การชี้ไปที่ -S เป็นสิ่งหนึ่งอธิบายสิ่งต่างๆได้ดีกว่า นอกจากนี้ฉันชอบใช้ - ตกแต่งเพื่อดูว่าสาขาต่าง ๆ มาจากไหน
sehe

7
@sehe: ขอบคุณสำหรับความคิดเห็นที่ดีของคุณ ฉันเดาว่ามันคุ้มค่าที่--decorateจะเพิ่มชื่อสาขาให้กับการกระทำที่ปลายของแต่ละสาขา ในทางปฏิบัติฉันไม่ได้ใช้จริงๆ--sourceหรือ--decorateและใช้git branch -a --contains <commit-hash>เพื่อค้นหาว่าสาขาใดมีความมุ่งมั่นที่ฉันสนใจ
Mark Longair

3
เพิ่ม -p เพื่อดูความแตกต่างของอินไลน์เช่นกัน FWIW
rogerdpack

1
@ MarkLongair ไม่แสดงการเปลี่ยนแปลงที่เกิดขึ้นในการผสาน ข้อเสนอแนะใด ๆ ที่จะแสดงสิ่งเหล่านั้นเช่นกัน?
Pahlevi Fikri Auliya

2
สำหรับฉันนี้จะทำงานเฉพาะถ้าผมเอาพื้นที่ระหว่าง -S git log -S"dude, where's my car?" --source --allและคำค้นหาเช่น @ribamar เขียนด้วยว่าในคำตอบด้านล่าง แต่อาจถูกมองข้ามได้ง่ายถัดจากคำตอบยอดนิยมนี้
bug313

69

- การย้อนกลับยังมีประโยชน์เนื่องจากคุณต้องการการคอมมิทครั้งแรกที่ทำการเปลี่ยนแปลง:

git log --all -p --reverse --source -S 'needle'

วิธีที่เก่ากว่าที่ผูกไว้จะปรากฏขึ้นก่อน


20

คำตอบของ Mark Longairนั้นยอดเยี่ยม แต่ฉันพบว่าเวอร์ชั่นที่ง่ายกว่านี้สำหรับฉัน

git log -S whatever

24
เพื่อชี้แจงให้ชัดเจนว่าใช้งานได้ดีหากคำมั่นสัญญาที่คุณกำลังมองหาอยู่HEADแต่คำถามนี้ถามโดยเฉพาะเกี่ยวกับการมองข้ามทุกสาขาในพื้นที่เก็บข้อมูล
Mark Longair

18

ล้อเล่นรอบกับคำตอบเดียวกัน:

$ git config --global alias.find '!git log --color -p -S '
  • ! เป็นสิ่งจำเป็นเนื่องจากวิธีอื่น git ไม่ผ่านการโต้แย้งอย่างถูกต้องถึง -S ดูคำตอบนี้
  • --colorและ-pช่วยแสดงว่า "whatchanged"

ตอนนี้คุณสามารถทำได้

$ git find <whatever>

หรือ

$ git find <whatever> --all
$ git find <whatever> master develop

6
git log -S"string_to_search" # options like --source --reverse --all etc

ระวังอย่าใช้ช่องว่างระหว่าง S และ "string_to_search" ในการตั้งค่าบางอย่าง (git 1.7.1) คุณจะได้รับข้อผิดพลาดดังนี้:

fatal: ambiguous argument 'string_to_search': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

2

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

ในการทำเช่นนี้ฉันใช้Git bisectซึ่งทำให้ฉันพบคนบาปได้อย่างรวดเร็ว

ฉันวิ่งgit bisect startแล้วgit bisect badเพราะการตรวจสอบการแก้ไขมีปัญหา ตั้งแต่ผมไม่ทราบว่าเมื่อเกิดปัญหาที่เกิดขึ้นผมเป้าหมายแรกกระทำสำหรับ git bisect good <initial sha>"ดี"

จากนั้นฉันก็ค้นหา repo เพื่อหารหัสที่ไม่ดี เมื่อฉันพบมันฉันก็วิ่งgit bisect badและเมื่อมันไม่อยู่ที่นั่น: git bisect good.

ใน ~ 11 ขั้นตอนฉันได้ครอบคลุม ~ 1,000 คอมมิชชันและพบการคอมมิชชันที่แน่นอนซึ่งมีการนำเสนอปัญหา เยี่ยมมาก


2

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

git log --pretty=format:"%h - %an, %ar : %s"|grep "STRING"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.