Kecualikan direktori dari git diff

179

Saya bertanya-tanya bagaimana saya bisa mengecualikan seluruh direktori dari Git diff saya. (Dalam hal ini / spesifikasi). Saya membuat diff untuk seluruh rilis perangkat lunak kami menggunakan perintah git diff. Namun perubahan pada spesifikasi tidak relevan untuk prosedur ini, dan hanya membuat sakit kepala. sekarang saya tahu saya bisa melakukannya

git diff previous_release..current_release app/

Ini akan membuat perbedaan untuk semua perubahan dalam direktori aplikasi, tetapi tidak misalnya, di direktori lib /. Adakah yang tahu bagaimana menyelesaikan tugas ini? Terima kasih!

Sunting: Saya hanya ingin menjadi jelas, saya tahu saya bisa merangkai parameter dari semua direktori saya di akhir, minus / spec. Saya berharap ada cara untuk benar-benar mengecualikan direktori tunggal dalam perintah.

Mysrt
sumber
4
Saya menemukan pertanyaan luar biasa ini karena saya bermaksud mengabaikan submodul . Dalam hal ini, jika Anda sama naifnya dengan saya, pertanyaan ini bisa lebih membantu.
brandizzi
Aneh bahwa kita masih belum memiliki saklar Git asli untuk melakukan ini pada Sep 2016
Michael Z

Jawaban:

138

Dengan asumsi Anda menggunakan bash, dan Anda telah mengaktifkan globbing diperpanjang ( shopt -s extglob), Anda bisa mengatasinya dari sisi shell:

git diff previous_release current_release !(spec)

Menghemat Anda harus daftar semua hal lain.

Atau, shell-agnostik:

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

Anda bisa membungkusnya dalam skrip shell satu liner untuk menyelamatkan diri Anda dari mengetik ulang argumen.

Cascabel
sumber
1
PS globbing tidak cocok dengan file yang tersembunyi, jadi jika Anda terobsesi, Anda mungkin ingin memperbaiki .!(.|)agar cocok dengan semua yang dimulai dengan .selain .dan ...
Cascabel
Tampaknya ini tidak berfungsi untuk file yang baru atau dihapus di seluruh cabang. Saya mendapatkan kesalahan yang menghentikan eksekusi script, mengatakan itu tidak bisa berbeda dengannya.
Graham Christensen
2
@ Bahama: Saya percaya bahwa --saya baru saja menambahkan harus memperbaikinya.
Cascabel
1
Jawaban yang luar biasa. Saya hanya ingin nama ditampilkan (bukan perbedaan sebenarnya) jadi saya harus menambahkan --name-onlydi bagian paling akhir juga.
Agustus
1
Setelah bermain-main dengannya, hanya ingin menambahkan bahwa jika Anda mengubah nama file, itu akan menimbulkan kesalahan tetapi semua yang perlu Anda lakukan adalah menambah -- path/of/new/filedan itu akan mengetahuinya :)
Agustus
321

Berdasarkan jawaban ini, Anda juga dapat menggunakan:

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

Ini adalah fitur git yang agak baru yang memungkinkan mengecualikan jalur tertentu. Itu harus lebih dapat diandalkan daripada berbagai oneliners shell.

Saya memposting ini di sini karena pertanyaan ini masih menjadi hit # 1 untuk "git diff exclude path".

cdleonard
sumber
4
Sukai jawaban ini. Jika menambahkan opsi maka lakukan sebelum dasbor ganda. Contoh: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor
Tidak sadar saya bisa menggunakan nama cabang untuk current_releasedan previous_release- membuat saya tersenyum ketika saya menemukan jawabannya.
trueheart78
2
Apa yang berhasil untuk saya git diff --stat dev -- . ':!/Mopy/Docs/*'. Apa yang tidak berhasil untuk saya git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'dan variasi
Mr_and_Mrs_D
Sangat membantu. Berikut ini sintaks untuk melihat apakah ada file yang diubah, selain database.yml:git diff --check -- . ':!config/database.yml'
Dan Kohn
17
Dapat juga mengecualikan beberapa item seperti:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise
37

Jika Anda ingin menentukan lebih dari satu jalur untuk dikecualikan dalam git diff, Anda cukup menambahkan parameter pengecualian tambahan sampai akhir, misalnya untuk mengecualikan semua yang ada di direktori vendor dan bin dari statistik: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'
David Graham
sumber
33

Anda dapat mencoba dan menghapus atribut diff untuk file apa pun dalam direktori lib.
.gitattributes:

lib/* -diff

racl101 menambahkan dalam komentar :

Hanya untuk menambah ini, bagi Anda yang ingin membatasi git diffoutput file dari jenis tertentu, dalam direktori tertentu dan subdirektori, seperti semua JavaScript yang dihasilkan oleh bundel .jsfile Anda oleh Webpack , misalnya, Anda dapat menambahkan ini untuk .gitattributes:

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

Maka Anda tidak melihat semua kebisingan di keluaran git diff Anda dan itu hanya menunjukkan sebagai: Binary files ... differmana yang lebih bermanfaat.

VONC
sumber
ini akan menghapus spec dari semua diff saya. Saya masih ingin melihat diff saya di folder spec secara normal, hanya saja tidak ketika saya menjalankan diff 'release' ini
Mysrt
2
@Mystr: Anda dapat mengatur .gitattributesfile itu di cabang khusus yang dibuat hanya untuk jenis 'rilis';) Rebase cabang khusus di atas current_releasedan lakukan diff Anda dari sana.
VonC
Ini juga tampaknya tidak berfungsi untuk file yang dihapus di seluruh cabang. File yang dihapus masih menunjukkan perbedaan komplit.
Graham Christensen
Tidak bekerja untuk saya. Apakah _ jalur khusus? _site/* -diff
Marius
@MariusAndreiana Tidak, '_' tidak istimewa. Bisakah Anda memeriksa aturan gitattributes yang berlaku untuk file folder itu dengan: git-scm.com/docs/git-check-attr
VonC
22

Git diff sekarang menerima format pengecualian khusus: git diff -- ':(exclude)lib/*'

Berhati-hatilah jika Anda memiliki banyak nama folder yang berulang ('/ app', '/ lib', dll.), Karena ini akan mengecualikan file relatif terhadap direktori kerja saat ini DAN direktori root git.

MaxPRafferty
sumber
1
apakah Anda melewatkan satu titik, bukankah seharusnya begitu git diff -- . ':(exclude)lib/*'?
Nicolas Dermine
1
@ NicolasDermine Tidak, meskipun apa yang Anda tulis adalah setara. Bagian "termasuk" dari path juga opsional. Itu sebabnya Anda hanya dapat melakukan git diffuntuk segala hal relatif terhadap jalan Anda saat ini, daripada membutuhkangit diff -- .
MaxPRafferty
Catatan: pada mesin windows, gunakan tanda kutip ganda, sepertigit diff -- ":(exclude)lib/*"
cnlevy
Tidak tahu mengapa, tetapi bagi saya itu hanya bekerja dengan titik, seperti yang disarankan oleh @NicolasDermine. Saya menggunakan Cmder pada win10.
Olivvv
3

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"

Beberapa gula sintaksis diterapkan

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

Atau letakkan skrip kecil untuk dotfile Anda

Seperti .bash_profileatau.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}
jasonleonhard
sumber
-6
git diff app lib
Jed Schneider
sumber