ต้องการยกเว้นไฟล์จาก“ git diff”


229

ฉันกำลังพยายามแยกไฟล์ ( db/irrelevant.php) จาก Git diff ฉันได้พยายามวางแฟ้มในที่dbไดเรกทอรีย่อยที่เรียกว่า.gitattributesเส้นirrelevant.php -diff และผมยังมีความพยายามในการสร้างไฟล์ที่เรียกว่ามี.git/info/attributesdb/irrelevant.php

ในทุกกรณีdb/irrelevant.phpไฟล์จะรวมอยู่ใน diff เป็น Git binary patch สิ่งที่ฉันต้องการสำหรับการเปลี่ยนแปลงในไฟล์นั้นจะถูกละเว้นโดยคำสั่ง diff ผมทำอะไรผิดหรือเปล่า?

คำตอบ:


325

OMG ไดรเวอร์และ awk เพื่อแยกไฟล์หมัด? ตั้งแต่git 1.9คุณสามารถทำสิ่งต่อไปนี้:

git diff -- . ':(exclude)db/irrelevant.php' ':(exclude)db/irrelevant2.php'

อ่าสง่างาม! ดูคำตอบที่ยกมาและรายละเอียดคำตอบนี้โดย @torek


4
หมายเหตุ: หากคุณต้องการแยกชื่อไฟล์เฉพาะคุณจะต้องใส่คำนำหน้าด้วยเครื่องหมายดอกจันซึ่งแตกต่างจาก.gitignoreไวยากรณ์ไฟล์ เช่นแทน:!*shrinkwrap.yaml :!shrinkwrap.yaml
vaughan

7
ยกเว้นไฟล์เพิ่มเติมเช่นฉันมีไฟล์ * .min.css และ * .min.js เพื่อหลีกเลี่ยงความแตกต่างของ git ดังนั้นฉันใช้คำสั่งgit diff -- . ':(exclude)*.min.js' ':(exclude)*.min.css'
maheshwaghmare

4
หน้าต่างไวยากรณ์ : git diff -- . ":(exclude)db/irrelevant.php"(ราคาคู่แทนราคาเดียว)
cnlevy

4
ขอบคุณ! ไวยากรณ์ที่ลึกลับเช่นนี้ .. ฉันต้องค้นหามันทุกครั้ง
Daniel Waltrip

1
@cnlevy หรือไม่มีคำพูด! git diff -- . :(exclude)db/irrelevant.php
Matthias

62

คุณสามารถตั้งค่าไดรเวอร์ diff แบบกำหนดเองด้วยคำสั่ง no op และกำหนดให้กับไฟล์ที่ควรละเว้น

สร้างไดรเวอร์ diff ของที่เก็บเฉพาะด้วยคำสั่งนี้

git config diff.nodiff.command /bin/true

หรือสำหรับทุก Repos --globalของคุณด้วย

(หาก/bin/trueไม่มีอยู่ใน MacOS ทางเลือกอื่นจะใช้/usr/bin/trueหรือecho)

จากนั้นกำหนดไดรเวอร์ diff ใหม่ให้กับไฟล์ที่คุณต้องการละเว้นใน.git/info/attributesไฟล์ของคุณ

irrelevant.php    diff=nodiff

หากสถานะนี้ควรจะถูกแบ่งปันกับนักพัฒนาอื่น ๆ คุณสามารถใช้.gitattributesแทน.git/info/attributesและแบ่งปันgit configคำสั่งกับเพื่อนของคุณ (ผ่านไฟล์เอกสารหรือบางสิ่ง)


2
นี่คือสิ่งที่ฉันกำลังมองหา - ตามที่อธิบายไว้ในkerneltrap.org/mailarchive/git/2008/10/17/3711254ฉันแก้ไข ~ / .gitconfig เพิ่ม: [diff "nodiff"] `command = / bin / true` แล้วฉันสร้างไฟล์ที่เรียกว่า .git / info / คุณลักษณะที่ฉันเพิ่ม: irrelevant.php diff=nodiff
ไมเคิล

12
คำตอบนี้ทำงานได้ดีขึ้นมากสำหรับฉัน: stackoverflow.com/questions/1016798/…
Neil Forrester

3
git diff --statที่น่าสนใจวิธีการนี้ไม่ได้ทำงานกับ ในกรณีนั้นเราสามารถใช้git diff ... | diffstatวิธีแก้ปัญหาได้
ddkilzer

@Michael ลิงก์นั้นดูเหมือนว่าจะถูกบอร์กมีอีกไหม
DickieBoy

3
เพียงแค่เพิ่ม: ถ้าคุณต้องการบังคับให้คอมไพล์ diff แสดงมันต่อไปให้ใช้--no-ext-diff
Florian Klein

35

คุณยังสามารถใช้โปรแกรมfilterdiffของการรวบรวมโปรแกรมpatchutilsเพื่อแยกบางส่วนของ diff ตัวอย่างเช่น:

git diff | filterdiff -p 1 -x db/irrelevant.php

4
โปรดทราบว่า-pจาก manpage (1) คือ "-pn, --strip-match = n เมื่อจับคู่ให้ละเว้นองค์ประกอบ n แรกของชื่อพา ธ " ฉันใช้เวลาสักครู่หนึ่งเพื่อตรวจจับที่-p 1กำลังเอาชิ้นdbส่วนออกจากเส้นทางของ OP หากคุณเพียงแค่ต้องการที่จะระบุชื่อไฟล์และไม่สนใจเส้นทาง / เป็นไปได้ทั้งหมด dir -p 99คุณสามารถใช้
Tyler Collier

32

วิธีนี้สั้นกว่าคำตอบที่ยอมรับ

git diff 987200fbfb 878cee40ba --stat -- ':!*.cs'

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความเป็นไปได้ในการรวม / ไม่รวมอ่านโพสต์นี้


โปรดทราบว่าตัวกรองจะใช้กับไฟล์ทั้งหมดที่อยู่ใต้ไดเรกทอรีปัจจุบันของคุณเท่านั้น
Chiel ten Brinke

นี่คือคำตอบที่ดีที่สุด ฉันสามารถทำให้มันง่ายขึ้นอีกเล็กน้อย: stackoverflow.com/a/58845608/3886183
dlsso

2
ฉันจะลบส่วนเริ่มต้นหรืออย่างน้อยก็อธิบายว่ามันทำอะไรเพราะไม่มีคำตอบอื่นใดรวมอยู่
mix3d

แฟล็ก stat แสดงให้คุณเห็นไฟล์และผลรวมต่าง ๆ ซึ่งจะช่วยให้คุณตรวจสอบได้ง่ายว่าตัวกรองทำงานตามที่คุณต้องการหรือไม่
Chiel ten Brinke

17

โซลูชันบรรทัดเดียวนี้ไม่จำเป็นต้องใช้อุปกรณ์ / ดาวน์โหลดอื่น ๆ :

git diff `git status -s |grep -v ^\ D |grep -v file/to/exclude.txt |cut -b4-`

แน่นอนfile/to/exclude.txtชื่อของไฟล์ที่คุณต้องการยกเว้นอยู่ที่ไหน

แก้ไข: เครดิตksenzeeสำหรับการแก้ไขไฟล์ที่ถูกลบทำลายความแตกต่าง


ฉันกำลังพยายามปรับสายการบินหนึ่งของคุณให้git diff --stat masterประสบความสำเร็จ - คุณช่วยได้ไหม?
Mr_and_Mrs_D

13

คำตอบที่ดีจริงๆจากKurzedMetalสำหรับสิ่งที่ฉันต้องทำซึ่งก็คือความสามารถในการดูว่าไฟล์มีการเปลี่ยนแปลง แต่ไม่ให้สร้างความแตกต่างซึ่งอาจเป็นเรื่องใหญ่ในกรณีของฉัน

แต่เพื่อนร่วมงานของฉันแนะนำวิธีที่ง่ายยิ่งขึ้นและทำงานให้ฉัน:

การเพิ่ม.gitattributesไฟล์ในไดเร็กทอรีที่ไฟล์นั้นถูกละเว้นโดยgit diffอยู่กับเนื้อหาต่อไปนี้:

file-not-to-diff.bin -diff

ที่ยังช่วยให้git status"ดู" ถ้าไฟล์มีการเปลี่ยนแปลง git diffนอกจากนี้ยังจะ "เห็น" ว่าไฟล์การเปลี่ยนแปลง diffแต่มันจะไม่สร้าง

ที่.binส่วนขยายสำหรับไฟล์ในตัวอย่างเป็นเจตนา .gitattributesฉันจะรู้ว่านี่เป็นพฤติกรรมปกติของคอมไพล์สำหรับไฟล์ไบนารีและมันไม่จำเป็นต้องมีการจัดการพิเศษกับ แต่ในกรณีของฉันไฟล์เหล่านี้จำได้ว่าเป็นไฟล์ข้อความโดย git และยูทิลิตี้ "file" และนี่ก็เป็นเคล็ดลับ


11

คำตอบที่ง่ายที่สุด

git diff ':!db/irrelevant.php'

มันเป็นเพียงแค่':!<path to file>'หลังคำสั่ง diff ของคุณ คำสั่ง diff อาจมีความซับซ้อนเท่าที่คุณต้องการและคุณสามารถใช้อักขระตัวแทนเช่น*.min.jsหรือเพิ่มการยกเว้นหลายรายการ (เว้นวรรคแยกบล็อกที่ยกมา) หากคุณต้องการ


5

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

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

git diff -- ":(exclude)thingToExclude"

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

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

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

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

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

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

gde() {
    # git diff exclude files or folders 
    # usage: 
    # gde fileOrFolderNameToExclude
    git diff -- ":(exclude)*/$1/*"
}

สิ่งนี้ไม่ได้ผลสำหรับฉันฉันไม่ต่างอะไรเลยกับทั้งไวยากรณ์ใช้ (ยกเว้น) หรือ! ฉันมีคอมไพล์ 2.21.0
Olivvv

คุณสามารถคอมไพล์ไฟล์ที่ไม่มีสเตจหรือฉากได้ หากคุณมีคอมไพล์เพิ่มพวกเขาพวกเขากลายเป็นฉาก หากพวกเขาจัดฉากคุณสามารถทำได้git diff --stagedหวังว่านี่จะช่วยคุณได้
jasonleonhard

วากยสัมพันธ์ลำไส้ใหญ่กำลังทำอะไรอยู่?
โยนาห์

2

มันง่ายมากคุณสามารถยกเว้นสิ่งที่คุณต้องการโดยใช้คำสั่ง unix มาตรฐานคำสั่งเหล่านั้นมีอยู่ภายใต้ git bash แม้ในสภาพแวดล้อมของ windows ตัวอย่างด้านล่างแสดงวิธีการแยก diff สำหรับไฟล์ pom.xml ก่อนอื่นให้ตรวจสอบ diff to master สำหรับชื่อไฟล์เท่านั้นจากนั้นใช้ไฟล์ 'grep -v' ที่คุณไม่ต้องการแล้วรัน diff to master ด้วยรายการที่เตรียมไว้ล่วงหน้า:

git diff master `git diff --name-only master | grep -v pom.xml`

1

คล้ายกับโซลูชันของ Ben Rouxแต่การแบ่งปันอยู่ดี:

git status --porcelain | grep -v $PATTERN_TO_EXCLUDE | awk '{print $2}' | xargs git diff

หรือหากการเปลี่ยนแปลงได้กระทำไปแล้วในพื้นที่:

git diff --name-only origin/master | grep -v $PATTERN_TO_EXCLUDE | xargs git diff origin/master

ตัวอย่าง:

git status --porcelain | grep -v docs | awk '{print $2}' | xargs git diff origin/master

git diff --name-only origin/master | grep -v docs | xargs git diff origin/master

1

ฉันทำต่อไปนี้:

git add *pattern_to_exclude*
git diff
git reset HEAD .

ฉันรู้ว่ามันไม่ใช่คำตอบที่สง่างามและบางครั้งมันก็สามารถใช้งานได้ (เช่นถ้าคุณมีฉากแล้ว) แต่มันก็ใช้เคล็ดลับโดยไม่ต้องพิมพ์คำสั่งที่ซับซ้อน


0

หากคุณต้องการทำสิ่งนี้เพียงเพื่อตรวจสอบความแตกต่างของสายตาเครื่องมือ diff ที่มองเห็น (เช่นMeld ) จะช่วยให้คุณทำมันด้วยคำสั่งสั้น ๆ ที่จำได้ง่าย

ก่อนอื่นให้ตั้งค่าเครื่องมือ diff ถ้าคุณยังไม่มี

$ git config --global diff.tool = meld

จากนั้นคุณสามารถเรียกใช้ไดเรกทอรีที่แตกต่างกัน

$ git difftool --dir-diff

คุณจะสามารถเรียกดูความแตกต่าง (ตามไฟล์) ใน Meld (หรือเครื่องมือที่คุณเลือก) อย่าเปิดไฟล์ที่คุณต้องการเพิกเฉย

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