Ingin mengecualikan file dari "git diff"

229

Saya mencoba mengecualikan file ( db/irrelevant.php) dari Git diff. Saya telah mencoba meletakkan file di dbsubdirektori yang disebut .gitattributesdengan baris irrelevant.php -diff dan saya juga mencoba membuat file bernama .git/info/attributesmengandung db/irrelevant.php.

Dalam semua kasus, db/irrelevant.phpfile tersebut disertakan dalam diff sebagai tambalan biner Git. Yang saya inginkan adalah agar perubahan pada file itu diabaikan oleh perintah diff. Apa yang saya lakukan salah?

Michael
sumber

Jawaban:

325

Omg, driver dan awk untuk mengecualikan file yang buruk? Sejak git 1.9 Anda bisa:

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

Ah, elegan! Lihat jawaban yang dikutip dan untuk perincian jawaban ini oleh @torek

Mr_and_Mrs_D
sumber
4
CATATAN: Jika Anda ingin mengecualikan nama file tertentu Anda harus awalan dengan asterisk, berbeda dari .gitignoresintaksis file. Misalnya :!*shrinkwrap.yamlbukannya :!shrinkwrap.yaml.
Vaughan
7
Kecualikan lebih banyak file, Misalnya saya memiliki file * .min.css dan * .min.js untuk menghindari dari git diff. Jadi, saya menggunakan perintahgit diff -- . ':(exclude)*.min.js' ':(exclude)*.min.css'
maheshwaghmare
4
sintaks windows : git diff -- . ":(exclude)db/irrelevant.php"(tanda kutip ganda bukannya tanda kutip tunggal)
cnlevy
4
Terima kasih! Sintaksis esoteris yang demikian .. Saya harus mencarinya setiap waktu.
Daniel Waltrip
1
@cnlevy atau tidak ada kutipan! git diff -- . :(exclude)db/irrelevant.php
Matthias
62

Anda bisa mengatur pengandar diff khusus dengan perintah no op dan menetapkannya ke file-file yang harus diabaikan.

Buat driver diff spesifik repositori dengan perintah ini

git config diff.nodiff.command /bin/true

atau untuk semua repo Anda dengan --global.

(Jika /bin/truetidak ada di MacOS, alternatif akan menggunakan /usr/bin/trueatau echo).

Kemudian, tetapkan driver diff baru untuk file yang ingin Anda abaikan dalam .git/info/attributesfile Anda .

irrelevant.php    diff=nodiff

Jika keadaan ini seharusnya dibagikan dengan pengembang lain, Anda dapat menggunakan .gitattributesalih-alih .git/info/attributesdan berbagi git configperintah dengan rekan-rekan Anda (melalui file dokumentasi atau sesuatu).

Logam Kurzed
sumber
2
Ini persis apa yang saya cari - seperti yang dijelaskan dalam kerneltrap.org/mailarchive/git/2008/10/17/3711254 Saya mengedit ~ / .gitconfig menambahkan: [diff "nodiff"] `command = / bin / true` dan kemudian saya membuat file bernama .git / info / atribut yang saya tambahkan: irrelevant.php diff=nodiff
Michael
12
Jawaban ini bekerja lebih baik bagi saya: stackoverflow.com/questions/1016798/…
Neil Forrester
3
Menariknya pendekatan ini tidak berhasil git diff --stat. Dalam hal ini, seseorang dapat menggunakan git diff ... | diffstatsolusi.
ddkilzer
@Michael tautan itu tampaknya borked, apakah ada yang lain?
DickieBoy
3
hanya tambahan: jika Anda ingin memaksa git diff untuk menampilkannya, gunakan--no-ext-diff
Florian Klein
35

Anda juga dapat menggunakan program filterdiff dari koleksi program patchutils untuk mengecualikan beberapa bagian dari diff. Sebagai contoh:

git diff | filterdiff -p 1 -x db/irrelevant.php
Szilárd Pfeiffer
sumber
4
Perhatikan bahwa -p, dari halaman manual (1), adalah "-pn, --strip-match = n Saat mencocokkan, abaikan komponen n pertama dari pathname." Butuh beberapa saat untuk menangkap yang -p 1menghapus dbbagian dari jalur OP. Jika Anda hanya ingin menentukan nama file dan mengabaikan semua kemungkinan jalur / dir, Anda dapat menggunakan -p 99.
Tyler Collier
32

Metode ini lebih pendek dari jawaban yang diterima.

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

Untuk informasi lebih lanjut tentang kemungkinan inklusi / pengecualian yang berbeda, baca pos lain ini

Chiel ten Brinke
sumber
Ketahuilah bahwa filter hanya berlaku untuk semua file di bawah direktori Anda saat ini.
Chiel ten Brinke
Ini jawaban terbaik. Saya dapat menyederhanakannya sedikit lebih: stackoverflow.com/a/58845608/3886183
dlsso
2
Saya akan menghapus bagian --stat, atau setidaknya menjelaskan apa fungsinya, karena tidak ada jawaban lain yang memasukkannya.
mix3d
Bendera stat menunjukkan kepada Anda file dan total diff-nya, yang memungkinkan Anda untuk memeriksa dengan mudah jika filter bekerja sesuai keinginan Anda.
Chiel ten Brinke
17

Solusi satu baris ini tidak memerlukan utilitas / unduhan lain:

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

Di mana file/to/exclude.txtnama file yang ingin Anda kecualikan, tentu saja.

Sunting: ksenzee kredit untuk memperbaiki file yang terhapus karena melanggar diff.

Ben Roux
sumber
Saya mencoba menyesuaikan satu liner Anda git diff --stat mastertanpa banyak hasil - dapatkah Anda membantu?
Mr_and_Mrs_D
13

Benar-benar jawaban yang baik dari KurzedMetal untuk apa yang perlu saya lakukan, yang merupakan kemampuan untuk melihat bahwa file telah berubah, tetapi tidak untuk menghasilkan diff, yang bisa sangat besar, dalam kasus saya.

Tetapi seorang kolega saya menyarankan pendekatan yang bahkan lebih sederhana dan bekerja untuk saya:

menambahkan .gitattributesfile di direktori tempat file tersebut diabaikan dengan git diffberada dengan konten berikut:

file-not-to-diff.bin -diff

Itu masih memungkinkan git status"melihat" jika file berubah. git diffjuga akan "melihat" bahwa file berubah, tetapi tidak akan menghasilkan diff.

Bahwa .binekstensi untuk file dalam contoh disengaja. Saya menyadari bahwa ini adalah perilaku default git untuk file biner, dan itu tidak memerlukan penanganan khusus .gitattributes. Tetapi dalam kasus saya, file-file ini dikenali sebagai file teks oleh git dan utilitas "file" dan ini berhasil.

pengguna3589608
sumber
11

Jawaban paling sederhana

git diff ':!db/irrelevant.php'

Itu hanya ':!<path to file>'setelah perintah diff Anda. Perintah diff bisa serumit yang Anda mau, dan Anda bisa menggunakan wildcard suka *.min.jsatau menambahkan banyak pengecualian (pisahkan blok yang dikutip) jika mau.

dlsso
sumber
5

Relatif ke direktori root git

git diff menerima pengecualian opsional

git diff -- ":(exclude)thingToExclude"

Anda mungkin ingin menambahkan beberapa kartu liar

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

Targetkan jenis file tertentu

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

Atau letakkan skrip kecil untuk dotfile Anda

Seperti .bash_profileatau.zshrc

gde() {
    # git diff exclude files or folders 
    # usage: 
    # gde fileOrFolderNameToExclude
    git diff -- ":(exclude)*/$1/*"
}
jasonleonhard
sumber
ini tidak bekerja untuk saya, saya tidak mendapatkan perbedaan sama sekali, dengan kedua sintaks, menggunakan (mengecualikan) atau! Saya memiliki git 2.21.0
Olivvv
Anda bisa mendapatkan file yang tidak dipentaskan atau dipentaskan. Jika Anda menambahkan git mereka menjadi dipentaskan. Jika mereka dipentaskan, Anda dapat melakukan git diff --stagedSemoga ini bisa membantu Anda.
jasonleonhard
Secara sintaksis, apa yang dilakukan usus besar?
Jonah
2

Ini sangat sederhana, Anda dapat mengecualikan apa yang Anda inginkan menggunakan perintah unix standar, perintah-perintah itu tersedia di bawah git bash bahkan di bawah lingkungan windows. Contoh di bawah ini menunjukkan cara mengecualikan diff untuk file pom.xml, periksa dulu diff untuk master hanya untuk nama file, kemudian gunakan file grep -v 'exclude yang tidak Anda inginkan dan kemudian jalankan lagi diff untuk master dengan daftar prepapred:

git diff master `git diff --name-only master | grep -v pom.xml`
Nieznany Anonimiec
sumber
1

mirip dengan solusi Ben Roux , tetapi tetap berbagi:

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

atau, jika perubahan sudah dilakukan secara lokal:

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

Contoh:

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
Chris Montoro
sumber
1

Saya melakukan hal berikut:

git add *pattern_to_exclude*
git diff
git reset HEAD .

Saya tahu ini bukan solusi yang elegan dan kadang-kadang tidak dapat digunakan (mis. Jika Anda sudah memiliki beberapa hal yang dipentaskan), tetapi ia berhasil tanpa harus mengetikkan perintah yang rumit

BlueMagma
sumber
0

Jika Anda ingin melakukan ini hanya untuk memeriksa diff secara visual, alat diff visual (seperti Meld ) akan memungkinkan Anda melakukannya dengan perintah singkat yang mudah diingat.

Pertama, siapkan alat diff jika Anda belum melakukannya.

$ git config --global diff.tool = meld

Kemudian, Anda dapat menjalankan direktori diff.

$ git difftool --dir-diff

Anda dapat menelusuri diff (berdasarkan file) di Meld (atau alat pilihan Anda). Cukup jangan buka file yang ingin Anda abaikan.

mkasberg
sumber