ฉันมีสาขาในประเทศ 57 สาขา ฉันรู้ว่าฉันได้ทำการเปลี่ยนแปลงไฟล์บางไฟล์ในไฟล์ใดไฟล์หนึ่ง แต่ไม่แน่ใจว่าไฟล์ใด มีคำสั่งบางประเภทที่ฉันสามารถเรียกใช้เพื่อค้นหาว่าสาขาใดมีการเปลี่ยนแปลงในไฟล์บางไฟล์หรือไม่
ฉันมีสาขาในประเทศ 57 สาขา ฉันรู้ว่าฉันได้ทำการเปลี่ยนแปลงไฟล์บางไฟล์ในไฟล์ใดไฟล์หนึ่ง แต่ไม่แน่ใจว่าไฟล์ใด มีคำสั่งบางประเภทที่ฉันสามารถเรียกใช้เพื่อค้นหาว่าสาขาใดมีการเปลี่ยนแปลงในไฟล์บางไฟล์หรือไม่
คำตอบ:
ค้นหาสาขาทั้งหมดที่มีการเปลี่ยนแปลง FILENAME (แม้ว่าจะอยู่ก่อนจุดสาขา (ไม่ได้บันทึก))
FILENAME="<filename>"
git log --all --format=%H $FILENAME | while read f; do git branch --contains $f; done | sort -u
ตรวจสอบด้วยตนเอง:
gitk --all --date-order -- $FILENAME
ค้นหาการเปลี่ยนแปลงทั้งหมดที่ FILENAME ไม่ได้รวมเข้ากับหลัก:
git for-each-ref --format="%(refname:short)" refs/heads | grep -v master | while read br; do git cherry master $br | while read x h; do if [ "`git log -n 1 --format=%H $h -- $FILENAME`" = "$h" ]; then echo $br; fi; done; done | sort -u
git log -Schange …หรือgit log --grep LOGMESSAGE …(โดยมี ... แทนคำสั่งที่เหลือที่ฉันกล่าวถึง)
gitk --all -- filenameซึ่งจะแสดงการเปลี่ยนแปลงทั้งหมดของไฟล์นั้นแบบกราฟิก หากคุณสามารถระบุการคอมมิตที่เป็นปัญหาได้คุณสามารถใช้git branch --containsเพื่อดูว่าการคอมมิตได้ย้ายไปสาขาใด หากคุณต้องการที่จะเห็นสิ่งสาขากระทำในคำถามถูกแต่เดิมสร้างขึ้นบนแล้วคอมไพล์ google สิ่งสาขา แต่ทราบว่าการผสานข้างหน้าอย่างรวดเร็วสามารถปิดบังข้อมูลว่า
git log --all --format='--contains %H' "$file" | xargs git branch
สิ่งที่คุณต้องการคือ
git log --all -- path/to/file/filename
หากคุณต้องการทราบสาขาทันทีคุณสามารถใช้:
git log --all --format=%5 -- path/to/file/filename | xargs -I{} -n 1 echo {} found in && git branch --contains {}
นอกจากนี้หากคุณมีการเปลี่ยนชื่อคุณอาจต้องการรวม--followไว้สำหรับคำสั่งบันทึก Git
--sourceที่นั่นและคุณเป็นสีทอง
ดูเหมือนว่านี่จะยังคงเป็นปัญหาโดยไม่มีแนวทางแก้ไขที่เหมาะสม ฉันมีเครดิตไม่เพียงพอที่จะแสดงความคิดเห็นนี่คือผลงานเล็กน้อยของฉัน
วิธีแก้ปัญหาแรกของ Seth Robertson ใช้ได้ผลสำหรับฉัน แต่ให้เฉพาะสาขาในท้องถิ่นเท่านั้นซึ่งมีผลบวกปลอมจำนวนมากอาจเป็นเพราะการรวมจากสาขาที่มั่นคง
โซลูชันที่ 2 ของ Adam Dymitruk ไม่ได้ผลสำหรับฉันเลย สำหรับผู้เริ่มต้น --format =% 5 คืออะไร คอมไพล์ไม่รู้จักฉันไม่พบอะไรเลยและไม่สามารถใช้งานกับตัวเลือกรูปแบบอื่นได้
แต่โซลูชันแรกของเขารวมกับอ็อพชัน --source และด้วย grep ง่ายๆพิสูจน์แล้วว่ามีประโยชน์:
git log --all --source -- <filename> | grep -o "refs/.*" | sort -u
สิ่งนี้ทำให้ฉันมีแท็กและสาขาระยะไกลจำนวนหนึ่งและสาขาในพื้นที่หนึ่งสาขาซึ่งฉันได้ทำการเปลี่ยนแปลงล่าสุดกับไฟล์ ไม่แน่ใจว่าสมบูรณ์แค่ไหน
อัปเดตตามคำขอของ @nealmcb เรียงลำดับสาขาตามการเปลี่ยนแปลงล่าสุด:
ขั้นแรกคุณสามารถเปลี่ยน grep เป็น "refs / head /.*" ซึ่งจะให้เฉพาะสาขาในประเทศเท่านั้น หากมีเพียงไม่กี่สาขาคุณสามารถตรวจสอบการกระทำล่าสุดของแต่ละสาขาได้ดังนี้:
git log -1 <branch> -- <filename>
หากมีสาขามากขึ้นและคุณต้องการทำให้เป็นอัตโนมัติคุณสามารถรวมสองคำสั่งโดยใช้ xargs, การจัดรูปแบบบันทึกคอมไพล์และการจัดเรียงอื่น ๆ ลงในซับเดียวนี้:
git log --all --source -- <filename> | grep -o "refs/heads/.*" | sort -u | xargs -I '{}' git log -1 --format=%aI%x20%S '{}' -- <filename> | sort -r
ซึ่งจะทำให้ได้ผลลัพธ์ดังนี้:
2020-05-07T15:10:59+02:00 refs/heads/branch1
2020-05-05T16:11:52+02:00 refs/heads/branch3
2020-03-27T11:45:48+00:00 refs/heads/branch2
ฉันรู้ว่าคำถามนี้เป็นคำถามเก่าแก่ แต่ฉันก็ยังคงกลับไปหามันก่อนที่จะพัฒนาวิธีแก้ปัญหาของตัวเอง ฉันรู้สึกว่ามันดูหรูหรามากขึ้นและต้องขอบคุณการใช้ merge base กรองกิ่งก้านที่ไม่ต้องการออกไป
#!/bin/bash
file=$1
base=${2:-master}
b=$(tput bold) # Pretty print
n=$(tput sgr0)
echo "Searching for branches with changes to $file related to the $base branch"
# We look through all the local branches using plumbing
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
# We're establishing a shared ancestor between base and branch, to only find forward changes.
merge_base=$(git merge-base $base $branch)
# Check if there are any changes in a given path.
changes=$(git diff $merge_base..$branch --stat -- $file)
if [[ ! -z $changes ]]; then
echo "Branch: ${b}$branch${n} | Merge Base: $merge_base"
# Show change statistics pretty formatted
git diff $merge_base..$branch --stat -- $file
fi
done
หากคุณวางไว้ใน PATH เป็นgit-find-changes(ด้วยสิทธิ์ที่เรียกใช้งานได้) - คุณสามารถเรียกมันด้วยไฟล์git find-changes /path
ตัวอย่างผลลัพธ์สำหรับ
git find-changes app/models/
Branch: update_callbacks | Merge base: db07d23b5d9600d88ba0864aca8fe79aad14e55b
app/models/api/callback_config.rb | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
Branch: repackaging | Merge base: 76578b9b7ee373fbe541a9e39cf93cf5ff150c73
app/models/order.rb | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
ต่อไปนี้เป็นวิธีการบังคับแบบเดรัจฉานที่ไม่สง่างาม แต่ฉันคาดว่ามันน่าจะใช้ได้ ตรวจสอบให้แน่ใจว่าคุณได้ซ่อนการเปลี่ยนแปลงที่ไม่ได้ผูกมัดไว้ก่อนเนื่องจากจะเปลี่ยนสาขาที่คุณอยู่ในปัจจุบัน
for branch in $(git for-each-ref --format="%(refname:short)" refs/heads); do
git checkout $branch && git grep SOMETHING
done
git log -S
for-each-refยังคงเคารพshortธงนั้นอยู่ ที่กล่าวว่าไม่สนใจคำตอบของฉัน คำตอบอื่น ๆ ดีกว่า