ใช้ Git ฉันจะค้นหาสตริงในทุกสาขาได้อย่างไร


170

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

เฉพาะ GitHub: เป็นไปได้ไหมที่จะทำการค้นหาข้างต้นในทุกสาขาของ GitHub? (มีสาขาระยะไกลหลายแห่งในพื้นที่เก็บข้อมูล GitHub ระยะไกลของฉันที่นึกคิดฉันไม่ต้องนำมาลงสำหรับการค้นหานี้ ... )


1
git-grepอาจเป็นสิ่งที่คุณกำลังมองหา แต่ฉันยังไม่แน่ใจว่าตัวเลือกใดที่คุณต้องการ ...
johnny

คำตอบ:


170

คุณสามารถทำได้ในที่เก็บ Git:

git grep "string/regexp" $(git rev-list --all)

GitHub การค้นหาขั้นสูงมีความสามารถในการค้นหารหัส:

การค้นหารหัสจะดูรหัสทั้งหมดที่โฮสต์บน GitHub คุณยังสามารถกรองตาม:

  • ภาษา: language:
  • ชื่อที่เก็บ (รวมถึงชื่อผู้ใช้): repo:
  • เส้นทางไฟล์: path:

นี่ทำให้ฉันแบ่งส่วนผิด แม้ว่าอาจจะเป็น tortoisegitmerge (Windows) ก็ตาม
bean5

6
นี่ไม่ใช่วิธีที่ดีที่สุดในการทำเช่นนี้ มันไม่ได้ควบคุมปริมาณของ refs git grep ...คอมไพล์ที่มีการส่งผ่านไปยัง ดูคำตอบอื่น ๆ พวกเขาดีกว่าคำตอบนี้ถึงแม้ว่ามันจะถูกทำเครื่องหมายเป็นคำตอบที่ยอมรับ!
slm

1
มันจะดีถ้าคุณสามารถเพิ่มตัวอย่างสำหรับตัวกรองของคุณเช่นpath:เนื่องจากเอกสารอย่างรวดเร็วไม่ได้ดูชัดเจนว่าจะใช้ตัวกรองนี้ที่ไหนฉันสมมติว่ามันอยู่ก่อนคำพูดในตัวอย่างแบบสอบถามของคุณ?
blamb

3
ฉันจะแสดงชื่อสาขาได้อย่างไร ขณะนี้รายการแฮชทั้งหมดมีสตริง
harryfeng

4
ค้นหา Github เป็นสาขาต้นแบบเท่านั้น จากhelp.github.com/articles/searching-code : "เฉพาะสาขาเริ่มต้นเท่านั้นที่ได้รับการจัดทำดัชนีสำหรับการค้นหารหัสในกรณีส่วนใหญ่จะเป็นสาขาหลัก"
RedPanda

124

หากคุณใช้ @manojlds คำสั่ง Git grep และได้รับข้อผิดพลาด:

-bash: /usr/bin/git: Argument list too long" 

จากนั้นคุณควรใช้xargs :

git rev-list --all | xargs git grep "string/regexp"

ดูที่วิธีการ grep (ค้นหา) รหัสที่กำหนดในประวัติ Git


นอกจากนี้ดูเหมือนว่าจะเข้ากันได้กับคอนโซลประเภทอื่นเช่น fishshell
Daniel

1
ขอบคุณ !!! ใช้ ZSH และสิ่งนี้ทำงานในขณะที่คำสั่ง @manojlds ให้ข้อผิดพลาดที่คุณพูดถึง! แต่คำเตือนนี้อาจใช้เวลานานมากสำหรับ repo ขนาดใหญ่ที่มีประวัติยาวนาน
lacostenycoder

54

ในหลายกรณีgit rev-list --allสามารถส่งคืนข้อผูกพันจำนวนมากใช้เวลานานในการสแกน git show-ref --headsหากคุณแทนการค้นหาผ่านทุกการกระทำในทุกสาขาในประวัติศาสตร์ของพื้นที่เก็บข้อมูลของคุณเพียงแค่ต้องการค้นหาเคล็ดลับสาขาทั้งหมดคุณสามารถแทนที่ด้วย ดังนั้นทั้งหมด:

git grep "string" `git show-ref --heads`

หรือ:

git show-ref --heads | xargs git grep "string"

เคล็ดลับ:คุณสามารถเขียนผลลัพธ์ในไฟล์เพื่อดูในโปรแกรมแก้ไข:

nano ~/history.txt
git show-ref --heads | xargs git grep "search string here" >> ~/history.txt

6
git show-ref --headsแสดงรายการแฮชและชื่อผู้อ้างอิงดังนั้น (บรรทัดที่ 2) จะค้นหาสองครั้ง ดังนั้นgit show-ref --heads | cut -d' ' -f2จะดีกว่าเพราะจะแสดงรายการชื่ออ้างอิงเท่านั้น
hIpPy

4
ฉันไม่อยากเชื่อเลยว่าคำถามนี้ถูกถามและตอบมากี่ครั้ง แต่คุณเป็นคนเดียวที่ตอบถูก
Sammitch

1
git show-ref --heads -sเอาต์พุตแฮช SHA1 เท่านั้น นอกจากนี้หากมีหลายสาขาชี้ไปที่การกระทำเดียวกันคุณจะได้รับซ้ำ คุณสามารถลบออกได้ด้วยsort -uเช่นกันgit show-ref --heads -s | sort -u | xargs git grep ...
Steve

นี่คือฟังก์ชั่นที่ฉันเพิ่มลงใน bashrc ของฉัน หวังว่าจะช่วยใครบางคน:function gsearch { git grep $1 $(git show-ref --heads) | grep "refs/heads" | grep $1 } # last grep to keep grep color highlight
AFP_555

นี่ควรเป็นคำตอบที่ยอมรับได้ การใส่สตริงลงในทุกสาขาแต่สำหรับเนื้อหาล่าสุดเท่านั้นเป็นกรณีการใช้งานทั่วไป
dr_

21

มีปัญหาเล็กน้อยเกี่ยวกับวิธีแก้ไขปัญหาที่แสดงไว้ที่นี่ (ยอมรับแล้ว)

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

มันสร้างที่นี่ซึ่งคุณสามารถค้นหาสตริง"test -f /"ในหลายสาขาmasterและdevเป็น

git grep "test -f /" master dev

ซึ่งเหมือนกับ

printf "master\ndev" | xargs git grep "test -f /"

ดังนั้นที่นี่ไป

นี่เป็นการค้นหาแฮชของเคล็ดลับของสาขาท้องถิ่นทั้งหมดและค้นหาเฉพาะในคอมมิชชันเหล่านั้น:

git branch -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

หากคุณต้องการค้นหาในสาขาระยะไกลเช่นกันเพิ่ม-a:

git branch -a -v --no-abbrev | awk -F' *' '{print $3}' | xargs git grep "string/regexp"

เพิ่มเติม:

# Search in local branches
git branch | cut -c3- | xargs git grep "string"

# Search in remote branches
git branch -r | cut -c3- | xargs git grep "string"

# Search in all (local and remote) branches
git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string"

# Search in branches, and tags
git show-ref | grep -v "refs/stash" | cut -d' ' -f2 | xargs git grep "string"

5
อย่างน้อยสำหรับการค้นหาในสาขาทั้งหมดควร: git branch -a | cut -c3- | cut -d' ' -f 1 | xargs git grep "string" หรือจะล้มเหลวด้วย->สัญลักษณ์ในรายการไฟล์ซึ่งหมายถึงความสัมพันธ์ในท้องถิ่นกับสาขาระยะไกล
Ilya Sheershoff

7

คุณสามารถลองสิ่งนี้:

git log -Sxxxx  # Search all commits
git log -Sxxxx  --branches[=<pattern>]   # Search branches

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