เป็นไปได้หรือไม่ที่จะทำงานgit grep
ภายในทุกสาขาของโครงการที่มาของตัวควบคุม Git หรือมีคำสั่งอื่นให้เรียกใช้?
เป็นไปได้หรือไม่ที่จะทำงานgit grep
ภายในทุกสาขาของโครงการที่มาของตัวควบคุม Git หรือมีคำสั่งอื่นให้เรียกใช้?
คำตอบ:
คำถาม " วิธีการ grep (ค้นหา) คอมมิตโค้ดในประวัติคอมไพล์แนะนำ:
git grep <regexp> $(git rev-list --all)
ที่ค้นหาผ่านการกระทำทั้งหมดซึ่งควรรวมทุกสาขา
อีกรูปแบบหนึ่งคือ:
git rev-list --all | (
while read revision; do
git grep -F 'yourWord' $revision
done
)
คุณสามารถค้นหาตัวอย่างเพิ่มเติมได้ในบทความนี้ :
ฉันลองข้างต้นในโครงการเดียวที่ใหญ่พอที่คอมไพล์บ่นเกี่ยวกับขนาดอาร์กิวเมนต์ดังนั้นหากคุณพบปัญหานี้ให้ทำสิ่งที่ชอบ:
git rev-list --all | (while read rev; do git grep -e <regexp> $rev; done)
(ดูทางเลือกอื่นในส่วนสุดท้ายของคำตอบด้านล่าง)
อย่าลืมการตั้งค่าเหล่านั้นหากคุณต้องการ:
# Allow Extended Regular Expressions
git config --global grep.extendRegexp true
# Always Include Line Numbers
git config --global grep.lineNumber true
นามแฝงนี้สามารถช่วยได้เช่นกัน:
git config --global alias.g "grep --break --heading --line-number"
หมายเหตุ: chernjie แนะนำว่าgit rev-list --all
เป็น overkill
คำสั่งที่ละเอียดยิ่งขึ้นสามารถ:
git branch -a | tr -d \* | xargs git grep <regexp>
ซึ่งจะช่วยให้คุณค้นหาเฉพาะสาขา (รวมถึงสาขาระยะไกล)
คุณสามารถสร้างนามแฝง bash / zsh ได้ด้วย:
alias grep_all="git branch -a | tr -d \* | xargs git grep"
grep_all <regexp>
อัปเดตสิงหาคม 2559: RMแนะนำในความคิดเห็น
ฉันได้รับ "
fatal: bad flag '->' used after filename
" เมื่อลองใช้git branch
เวอร์ชันนี้ ข้อผิดพลาดนี้เกี่ยวข้องกับHEAD
สัญกรณ์นามแฝงฉันแก้ไขได้โดยการเพิ่ม
sed '/->/d'
ในท่อระหว่างtr
และxargs
คำสั่ง
git branch -a | tr -d \* | sed '/->/d' | xargs git grep <regexp>
นั่นคือ:
alias grep_all="git branch -a | tr -d \* | sed '/->/d' | xargs git grep"
grep_all <regexp>
git branch
เป็น tr หรือ sed git branch
เป็นคำสั่งเครื่องลายครามที่มีไว้สำหรับการบริโภคของมนุษย์ ดูstackoverflow.com/a/3847586/2562319สำหรับทางเลือกอื่นที่ต้องการ
git log
อาจเป็นวิธีที่มีประสิทธิภาพมากขึ้นในการค้นหาข้อความในทุกสาขาโดยเฉพาะอย่างยิ่งหากมีรายการที่ตรงกันมากและคุณต้องการดูการเปลี่ยนแปลงล่าสุด (ที่เกี่ยวข้อง) ก่อน
git log -p --all -S 'search string'
git log -p --all -G 'match regular expression'
คำสั่งบันทึกเหล่านี้แสดงรายการคอมมิตที่เพิ่มหรือลบสตริงการค้นหา / regex ที่กำหนด (โดยทั่วไป) ล่าสุดก่อน -p
ตัวเลือกที่ทำให้เกิดความแตกต่างที่เกี่ยวข้องกับการแสดงที่รูปแบบที่ถูกเพิ่มหรือลบออกเพื่อให้คุณสามารถเห็นมันในบริบท
เมื่อพบการคอมมิตที่เกี่ยวข้องซึ่งเพิ่มข้อความที่คุณกำลังมองหา (เช่น 8beeff00d) ให้ค้นหาสาขาที่มีคอมมิต:
git branch -a --contains 8beeff00d
ฉันพบว่าสิ่งนี้มีประโยชน์ที่สุด:
git grep -i foo `git for-each-ref --format='%(refname)' refs/`
คุณจะต้องปรับอาร์กิวเมนต์สุดท้ายโดยขึ้นอยู่กับว่าคุณต้องการดูเฉพาะสาขาระยะไกลเทียบกับท้องถิ่นเท่านั้นเช่น:
git grep -i foo $(git for-each-ref --format='%(refname)' refs/remotes)
git grep -i foo $(git for-each-ref --format='%(refname)' refs/heads)
นามแฝงที่ฉันสร้างขึ้นมีลักษณะดังนี้:
grep-refs = !sh -c 'git grep "$0" "$@" "$(git for-each-ref --format=\"%(refname)\"" refs/)'
git for-each-ref
ด้วย--sort=-committerdate --count=100
! ขอบคุณสำหรับแนวคิดดั้งเดิม!
เป็นไปได้ที่จะทำสองวิธีทั่วไป: Bash หรือ Git นามแฝง
นี่คือสามคำสั่ง:
git grep-branch
- ค้นหาในทุกสาขาในพื้นที่และระยะไกลgit grep-branch-local
- ค้นหาในสาขาท้องถิ่นเท่านั้นgit grep-branch-remote
- สาขาห่างไกลเท่านั้นการใช้งานจะเหมือนกับ git grep
git grep-branch "find my text"
git grep-branch --some-grep-options "find my text"
ควรเพิ่มคำสั่งลงใน~/.gitconfig
ไฟล์ด้วยตนเองเนื่องจากgit config --global alias
ประเมินโค้ดที่ซับซ้อนที่คุณเพิ่มและทำให้มันยุ่งเหยิง
[alias]
grep-branch = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | xargs git grep $@; };f "
grep-branch-remote = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' | grep '^remotes' | xargs git grep $@; };f"
grep-branch-local = "!f(){ git branch -a | sed -e 's/[ \\*]*//' | grep -v -e '\\->' -e '^remotes' | xargs git grep $@; };f "
หมายเหตุ: เมื่อคุณเพิ่มนามแฝงและไม่สามารถรันได้ให้ตรวจสอบแบ็กสแลช\
อาจต้องใช้ Escape เพิ่มเติม\\
เมื่อเทียบกับคำสั่งbash
git branch -a
- แสดงทุกสาขาsed -e 's/[ \\*]*//'
- ตัดช่องว่าง (จากbranch -a
) และ * (มีชื่อสาขาที่ใช้งานอยู่);grep -v -e '\\->'
- ละเว้นชื่อที่ซับซ้อนเช่นremotes/origin/HEAD -> origin/master
;grep '^remotes'
- รับทุกสาขาที่ห่างไกลgrep -v -e '^remotes'
- รับสาขายกเว้นสาขาห่างไกลgit grep-branch-local -n getTastyCookies
-n
นำหน้าหมายเลขบรรทัดกับบรรทัดที่ตรงกัน
[user@pc project]$ git grep-branch-local -n getTastyCookies
dev:53:modules/factory/getters.php:function getTastyCookies($user);
master:50:modules/factory/getters.php:function getTastyCookies($user)
โครงสร้างปัจจุบันคือ:
:
- ตัวคั่น
dev
53
modules/factory/getters.php
function getTastyCookies($user)
ดังที่คุณควรทราบ: คำสั่ง Bash ควรเก็บไว้ใน.sh
สคริปต์หรือเรียกใช้ในเชลล์
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' -e '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | grep '^remotes' | xargs git grep "TEXT"
git branch -a | sed -e 's/[ \*]*//' | grep -v -e '\->' | xargs git grep "TEXT"
git grep-branch "find my text"
:fatal: ambiguous argument 'client': both revision and filename
-a
ซึ่งแสดงทุกสาขา? ฉันขอแนะนำให้ใช้ตัวเลือกสำหรับgit branch
คำสั่งเพื่อแยกวงเล็บ เมื่อมองไปที่สาขาในท้องถิ่นมีเพียงสาขาเดียว*
ดังนั้นไม่จำเป็นต้องหลีกเลี่ยง ดังนั้น: git branch | sed -e 's/*/ /' | xargs git grep "TEXT"
สำหรับสาขาในพื้นที่เท่านั้นgit branch -r | grep -v -- "->" | xargs git grep "TEXT"
สำหรับสาขาที่ห่างไกลเท่านั้นและgit branch -a | grep -v -- "->" | xargs git grep "TEXT"
สำหรับทุกสาขา
นี่คือวิธีการ:
git for-each-ref --format='%(*refname)' | xargs git grep SEARCHTERM
หากคุณให้ค่าแฮช SHA-1 ใด ๆ กับgit grep
คุณให้ค้นหาในนั้นแทนการใช้สำเนาที่ใช้งานได้
ในการค้นหาทุกสาขา, คุณจะได้รับทุกgit rev-list --all
ต้นไม้ด้วย ใส่ทั้งหมดด้วย
git grep "regexp" $(git rev-list --all)
... และมีความอดทน