มีวิธีในการแยกพา ธ / ไดเรกทอรี / ไฟล์บางอย่างเมื่อค้นหาที่เก็บ git git grep
หรือไม่? สิ่งที่คล้ายกับ--exclude
ตัวเลือกในgrep
คำสั่งปกติ?
ฉันต้องใช้git grep
เพราะการใช้งานgrep
โดยตรงช้าเกินไปบนที่เก็บ git ขนาดใหญ่
มีวิธีในการแยกพา ธ / ไดเรกทอรี / ไฟล์บางอย่างเมื่อค้นหาที่เก็บ git git grep
หรือไม่? สิ่งที่คล้ายกับ--exclude
ตัวเลือกในgrep
คำสั่งปกติ?
ฉันต้องใช้git grep
เพราะการใช้งานgrep
โดยตรงช้าเกินไปบนที่เก็บ git ขนาดใหญ่
คำตอบ:
มันเป็นไปไม่ได้ แต่ได้รับการกล่าวเมื่อเร็ว ๆ นี้ วิธีแก้ปัญหาที่เสนอในลิงก์:
คุณสามารถใส่
*.dll
ไฟล์. gitignoregit grep --exclude-standard
ได้
แก้ไขเห็นเพียงคำตอบของไม่มีใครตั้งแต่ git 1.9.0 เป็นไปได้
ใน git 1.9.0 มีการเพิ่ม "คำวิเศษ" ไว้exclude
ในpathspec
s ดังนั้นหากคุณต้องการค้นหาfoobar
ในทุกไฟล์ยกเว้นการจับคู่ที่*.java
คุณสามารถทำได้:
git grep foobar -- './*' ':(exclude)*.java'
หรือใช้!
"รูปแบบย่อ" เพื่อยกเว้น:
git grep foobar -- './*' ':!*.java'
โปรดทราบว่าในรุ่น git จนถึง v2.12 เมื่อใช้การยกเว้นpathspec
คุณต้องมี "รวม" อย่างน้อยหนึ่งpathspec
รายการ ในตัวอย่างข้างต้นนี่คือ./*
(รวมทุกอย่างซ้ำ ๆ ภายใต้ไดเรกทอรีปัจจุบัน) ใน v2.13 คอมไพล์ข้อ จำกัด นี้ถูกยกขึ้นและการทำงานโดยไม่ต้องgit grep foobar -- ':!*.java'
./*
คุณสามารถใช้บางสิ่งเช่น:(top)
(รูปแบบย่อ:) :/
เพื่อรวมทุกอย่างจากด้านบนของ repo แต่คุณอาจต้องการปรับการแยกของคุณpathspec
ให้เริ่มจากด้านบนด้วย: :/!*.java
(มิฉะนั้นจะเป็นการยกเว้นเฉพาะ*.java
ไฟล์จากภายใต้ไดเรกทอรีปัจจุบันของคุณ)
มีการอ้างอิงที่ดีสำหรับ "คำวิเศษ" ทั้งหมดที่ได้รับอนุญาตในpathspec
ที่git-scm.com (หรือเพียงแค่git help glossary
) ด้วยเหตุผลบางอย่างเอกสารที่kernel.org ล้าสมัยจริง ๆ แม้ว่าพวกเขามักจะปรากฏตัวครั้งแรกในการค้นหาของ Google
git grep clock.gettime -- './*' ':!arch/**' ':!drivers/**'
เพื่อยกเว้นไดเรกทอรีทั้งหมดหลายรายการ ฉันไม่คิดว่ามันจะป้องกันการเรียกซ้ำ
git config alias.mygrep '!git grep "$@" -- "${GIT_PREFIX}/*" ":!*.java*" #'
สำหรับการใช้งานบ่อยครั้งคุณสามารถทำให้นามแฝงคอมไพล์ด้วยการยกเว้น: git mygrep foobar
แล้วก็ (ใช้นามแฝงshell # trickและdir ปัจจุบัน )
git grep
และgit ls-files
จากไดเรกทอรีย่อยและชื่อไฟล์รายงานทั้งสองที่เกี่ยวข้องกับไดเรกทอรีปัจจุบัน (แม้ว่าคุณจะใช้':(top)'
pathspec รวม) ทั้งสองคำสั่งมี--full-name
ตัวเลือกในการรายงานชื่อที่สัมพันธ์กับรูท แต่จะปิดโดยปริยาย
อัปเดต:สำหรับ git> = 1.9 มีการรองรับรูปแบบที่ไม่รวมอยู่ในระบบให้ดูคำตอบของผู้ใช้เท่านั้น
สิ่งนี้อาจดูด้านหลัง แต่คุณสามารถส่งรายการไฟล์ที่ไม่ตรงกับรูปแบบการยกเว้นของคุณให้เป็นgit grep
ดังนี้:
git grep <pattern> -- `git ls-files | grep -v <exclude-pattern>`
grep -v
ส่งกลับทุกเส้นทางไม่<exclude-pattern>
ตรงกับ โปรดทราบว่าgit ls-files
ยังใช้--exclude
พารามิเตอร์ แต่จะนำไปใช้กับไฟล์ที่ไม่ได้ติดตามเท่านั้น
คุณสามารถทำเครื่องหมายไฟล์หรือไดเรกทอรีเป็นเลขฐานสองโดยการสร้างไฟล์คุณลักษณะในที่เก็บของคุณเช่น
$ cat .git/info/attributes
directory/to/ignore/*.* binary
directory/to/ignore/*/*.* binary
another_directory/to/also/ignore/*.* binary
การจับคู่ในไฟล์ไบนารีจะแสดงรายการโดยไม่มีบรรทัดการรวมเช่น
$ git grep "bar"
Binary file directory/to/ignore/filename matches
other_directory/other_filename: foo << bar - bazz[:whatnot]
ด้วยเช่นโดยการ @kynan เป็นฐานที่ผมทำสคริปต์นี้และวางไว้ในเส้นทางของฉัน ( ~/bin/
) gg
ในฐานะ มันใช้git grep
แต่หลีกเลี่ยงชนิดของไฟล์ที่ระบุ
ใน repo ของเรามีภาพจำนวนมากดังนั้นฉันจึงไม่รวม imagefiles และมันจะลดลงเหลือ 1/3 ถ้าฉันค้นหา repo ทั้งหมด แต่สคริปต์นั้นสามารถแก้ไขได้อย่างง่ายดายเพื่อไม่รวม filestypes หรือ geleralpatterns อื่น ๆ
#!/bin/bash
#
# Wrapper of git-grep that excludes certain filetypes.
# NOTE: The filetypes to exclude is hardcoded for my specific needs.
#
# The basic setup of this script is from here:
# https://stackoverflow.com/a/14226610/42580
# But there is issues with giving extra path information to the script
# therefor I crafted the while-thing that moves path-parts to the other side
# of the '--'.
# Declare the filetypes to ignore here
EXCLUDES="png xcf jpg jpeg pdf ps"
# Rebuild the list of fileendings to a good regexp
EXCLUDES=`echo $EXCLUDES | sed -e 's/ /\\\|/g' -e 's/.*/\\\.\\\(\0\\\)/'`
# Store the stuff that is moved from the arguments.
moved=
# If git-grep returns this "fatal..." then move the last element of the
# arg-list to the list of files to search.
err="fatal: bad flag '--' used after filename"
while [ "$err" = "fatal: bad flag '--' used after filename" ]; do
{
err=$(git grep "$@" -- `git ls-files $moved | grep -iv "$EXCLUDES"` \
2>&1 1>&3-)
} 3>&1
# The rest of the code in this loop is here to move the last argument in
# the arglist to a separate list $moved. I had issues with whitespace in
# the search-string, so this is loosely based on:
# http://www.linuxjournal.com/content/bash-preserving-whitespace-using-set-and-eval
x=1
items=
for i in "$@"; do
if [ $x -lt $# ]; then
items="$items \"$i\""
else
moved="$i $moved"
fi
x=$(($x+1))
done
eval set -- $items
done
# Show the error if there was any
echo $err
หมายเหตุ 1
ตามนี้มันเป็นไปได้ที่จะตั้งชื่อสิ่งgit-gg
และสามารถเรียกมันเป็นคำสั่ง git ปกติเช่น:
$ git gg searchstring
แต่ฉันไม่สามารถทำงานนี้ได้ ฉันสร้างสคริปต์ในของฉัน~/bin/
และทำให้ที่git-gg
symlink /usr/lib/git-core/
ใน
โน้ต 2
คำสั่งไม่สามารถทำเป็นsh
git-alias ปกติได้เนื่องจากมันจะถูกเรียกใช้ที่รูทของ repo และนั่นไม่ใช่สิ่งที่ฉันต้องการ!