ยกเว้นไดเรกทอรีจาก git diff


179

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

git diff previous_release..current_release app/

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

แก้ไข: ฉันต้องการชัดเจนฉันรู้ว่าฉันสามารถสตริงพารามิเตอร์ของไดเรกทอรีทั้งหมดของฉันในตอนท้ายลบ / spec ฉันหวังว่าจะมีวิธียกเว้นไดเรกทอรีเดียวในคำสั่งอย่างแท้จริง


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

แปลกมากที่เรายังไม่มีสวิตช์ Git ดั้งเดิมสำหรับการทำเช่นนี้ในเดือนกันยายน 2559
Michael Z

คำตอบ:


138

สมมติว่าคุณใช้ bash และคุณได้เปิดใช้งานการขยายแบบวงกลม ( shopt -s extglob) คุณสามารถจัดการสิ่งนั้นได้จากด้านเปลือก:

git diff previous_release current_release !(spec)

ช่วยให้คุณต้องบันทึกรายการอื่น ๆ ทั้งหมด

หรือผู้ไม่เชื่อเรื่องพระเจ้า:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

คุณสามารถสรุปได้ในสคริปต์เชลล์หนึ่งบรรทัดเพื่อช่วยตัวเองไม่ให้พิมพ์อาร์กิวเมนต์อีกครั้ง


1
PS globbing ไม่ตรงกับไฟล์ที่ซ่อนอยู่ดังนั้นหากคุณกำลังครอบงำคุณอาจต้องการที่จะตะปูบน.!(.|)จะมีการแข่งขันทุกอย่างเริ่มต้นด้วย.นอกเหนือจากและ. ..
Cascabel

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

2
@ Graham: ฉันเชื่อว่า--ฉันเพิ่งเพิ่มควรแก้ไขที่
Cascabel

1
คำตอบที่ยอดเยี่ยม ฉันแค่ต้องการชื่อที่จะแสดง (ไม่ใช่ความแตกต่างที่เกิดขึ้นจริง) ดังนั้นฉันจึงต้องเพิ่ม--name-onlyในตอนท้ายเช่นกัน
ส.ค.

1
หลังจากเล่นไปกับมันแค่อยากจะเพิ่มว่าถ้าคุณเปลี่ยนชื่อไฟล์มันจะโยนข้อผิดพลาด แต่สิ่งที่คุณต้องทำคือเพิ่ม-- path/of/new/fileและมันจะคิดออก :)
3891414

321

จากคำตอบนี้คุณยังสามารถใช้:

git diff previous_release..current_release -- . ':!spec'

นี่คือคุณสมบัติคอมไพล์ใหม่ที่อนุญาตให้ยกเว้นเส้นทางบางอย่าง มันควรจะมีความน่าเชื่อถือมากกว่าเปลือกหอยต่าง ๆ

ฉันโพสต์ที่นี่เพราะคำถามนี้ยังคงเป็น # 1 สำหรับ "เส้นทาง diff git diff"


4
รักคำตอบนี้ หากเพิ่มตัวเลือกให้ทำก่อนขีดกลางคู่ เช่น: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor

ไม่ทราบว่าฉันสามารถใช้ชื่อสาขาสำหรับcurrent_releaseและprevious_release- ทำให้ฉันยิ้มเมื่อฉันคิดออก
trueheart78

2
git diff --stat dev -- . ':!/Mopy/Docs/*'สิ่งที่ทำงานสำหรับฉัน สิ่งที่ใช้ไม่ได้กับฉันgit diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'และรูปแบบต่าง ๆ
Mr_and_Mrs_D

มีประโยชน์จริงๆ นี่คือไวยากรณ์เพื่อดูว่ามีการเปลี่ยนแปลงไฟล์ใด ๆ นอกเหนือจาก database.yml:git diff --check -- . ':!config/database.yml'
Dan Kohn

17
นอกจากนี้ยังสามารถยกเว้นรายการหลายรายการเช่น:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise

37

หากคุณต้องการระบุมากกว่าหนึ่งพา ธ เพื่อแยกในคอมไพล์ git คุณเพียงแค่เพิ่มพารามิเตอร์การยกเว้นเพิ่มเติมไปยังจุดสิ้นสุดเช่นเพื่อแยกทุกอย่างในไดเรกทอรีผู้ขายและbinจากสถิติ: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'

33

คุณสามารถลองและยกเลิกการตั้งค่าแอ็ตทริบิวต์ diff สำหรับไฟล์ใด ๆ ภายในไดเร็กทอรี lib
.gitattributes:

lib/* -diff

racl101เพิ่มในความคิดเห็น :

เพื่อเพิ่มสิ่งนี้สำหรับผู้ที่ต้องการ จำกัด การgit diffส่งออกไฟล์ประเภทเฉพาะภายในไดเรกทอรีเฉพาะและไดเรกทอรีย่อยเช่น JavaScript ทั้งหมดที่สร้างโดยการรวมกลุ่มของ.jsไฟล์ของ Webpack คุณสามารถเพิ่มสิ่งนี้ได้ ไปที่.gitattributes:

dist/js/**/*.js -diff

จากนั้นคุณจะไม่เห็นเสียงรบกวนทั้งหมดในเอาต์พุต git diff และมันแสดงให้เห็นว่า: Binary files ... differซึ่งมีประโยชน์มากกว่า


สิ่งนี้จะลบข้อมูลจำเพาะออกจาก diffs ทั้งหมดของฉัน ฉันยังต้องการเห็น diffs ของฉันในโฟลเดอร์ข้อมูลจำเพาะตามปกติไม่ใช่เมื่อฉันใช้งาน 'release' diff
Mysrt

2
@Mystr: คุณสามารถตั้งค่า.gitattributesไฟล์นั้นในสาขาพิเศษที่สร้างขึ้นสำหรับ diff 'รีลีส' ชนิดนี้เท่านั้น) รีบูทที่สาขาพิเศษด้านบนcurrent_releaseและทำ diff ต่างจากที่นั่น
VonC

สิ่งนี้ดูเหมือนจะไม่ทำงานกับไฟล์ที่ถูกลบข้ามสาขา ไฟล์ที่ถูกลบยังคงแสดงความต่างที่สมบูรณ์
Graham Christensen

ไม่ได้ผลสำหรับฉัน _ พา ธ พิเศษไหม _site/* -diff
Marius

@MariusAndreiana ไม่ '_' ไม่พิเศษ คุณสามารถตรวจสอบกฎ gitattributes ที่ใช้สำหรับไฟล์ของโฟลเดอร์นั้นด้วย: git-scm.com/docs/git-check-attr
VonC

22

Git diff ยอมรับรูปแบบการยกเว้นที่กำหนดเองแล้ว: git diff -- ':(exclude)lib/*'

ระวังถ้าคุณมีชื่อโฟลเดอร์ซ้ำ ๆ ('/ app', '/ lib' ฯลฯ ) เนื่องจากจะเป็นการยกเว้นไฟล์ที่เกี่ยวข้องกับไดเรกทอรีการทำงานปัจจุบันและไดเรกทอรีราก git


1
คุณพลาดจุดgit diff -- . ':(exclude)lib/*'ใช่หรือไม่?
Nicolas Dermine

1
@NicolasDermine ไม่แม้ว่าสิ่งที่คุณเขียนจะเทียบเท่ากัน ส่วน "รวมถึง" ของเส้นทางยังเป็นตัวเลือก นั่นเป็นเหตุผลที่คุณสามารถทำgit diffทุกอย่างที่เกี่ยวข้องกับเส้นทางปัจจุบันของคุณแทนที่จะต้องgit diff -- .
MaxPRafferty

หมายเหตุ: สำหรับเครื่องที่ใช้ windows ให้ใช้เครื่องหมายคำพูดคู่เช่นgit diff -- ":(exclude)lib/*"
cnlevy

ไม่มีความคิดว่าทำไม แต่สำหรับฉันมันใช้ได้เฉพาะกับจุดตามที่ @NicolasDermine แนะนำ ฉันใช้ Cmder กับ win10
Olivvv

3

สัมพันธ์กับไดเรกทอรีราก git

git diff ยอมรับตัวเลือกไม่รวม

git diff -- ":(exclude)thingToExclude"

คุณอาจต้องการเพิ่มไวด์การ์ดบางส่วน

git diff -- ":(exclude)*/thingToExclude/*"

กำหนดประเภทไฟล์เป้าหมายเฉพาะ

git diff -- ":(exclude)*/$1/*.png"

มีการนำน้ำตาลทรายมาใช้

git diff -- ":!/\$1/"

หรือวางสคริปต์เล็กน้อยสำหรับ dotfiles ของคุณ

เช่น.bash_profileหรือ.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}

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