Perintah Git untuk menampilkan file spesifik mana yang diabaikan oleh .gitignore

645

Saya mulai basah dengan Git dan memiliki masalah berikut:

Pohon sumber proyek saya:

/
|
+--src/
+----refs/
+----...
|
+--vendor/
+----...

Saya memiliki kode (saat ini MEF) di cabang vendor saya yang akan saya kompilasi di sana dan kemudian memindahkan referensi ke /src/refsmana proyek mengambilnya.

Masalah saya adalah bahwa saya memiliki .gitignoreset saya untuk mengabaikan *.dlldan *.pdb. Saya dapat melakukan git add -f bar.dlluntuk memaksa penambahan file yang diabaikan yang ok, masalahnya adalah saya tidak bisa mencari tahu daftar file apa yang ada yang diabaikan.

Saya ingin membuat daftar file yang diabaikan untuk memastikan bahwa saya tidak lupa menambahkannya.

Saya telah membaca halaman manual git ls-filesdan tidak dapat membuatnya berfungsi. Sepertinya saya yang git ls-files --exclude-standard -iharus melakukan apa yang saya inginkan. Apa yang saya lewatkan?

Andrew Burns
sumber
12
Saat ini, Anda tidak akan menggunakan file git-ls-file melainkan 'git ls-file'
wojo
7
Saya memohon kepada Anda untuk memeriksa jawaban riyad sebagai benar karena itu adalah satu-satunya yang mengakui tidak ada cara dijamin untuk melakukan ini hanya menggunakan perintah git (termasuk git cleantrik) seperti yang ditunjukkan di sini . Juga, saya sarankan terhadap contoh "kecualikan-dari" dalam ringkasan Anda karena itu sebenarnya tidak memperhatikan file .gitignore. Saya menanyakan ini terutama karena halaman ini adalah respons Google teratas.
Alexander Bird
Titik cepat pada "Ringkasan apa yang berhasil": halaman manual "Git ls-files" menjelaskan bahwa "-i" berarti menyertakan file yang dikecualikan untuk output ls. Saya memiliki kesalahpahaman yang sama, sampai saya membaca 'perlahan-lahan'. ;-)
akan
2
Jawaban harus masuk di pos jawaban dan bukan di edit untuk pertanyaan.
Flimm
Saya punya git config --global alias.ls ls-files --exclude-standard, dan itu membuat jawaban untuk pertanyaan ini git ls -i.
jthill

Jawaban:

662

Catatan:


Juga menarik (disebutkan dalam qwertymk 's jawaban ), Anda juga dapat menggunakan git check-ignore -vperintah, setidaknya pada Unix ( tidak bekerja dalam CMD Windows sesi)

git check-ignore *
git check-ignore -v *

Yang kedua menampilkan aturan aktual .gitignoreyang membuat file diabaikan di repo git Anda.
Di Unix, menggunakan " Apa yang diperluas ke semua file di direktori saat ini secara rekursif? " Dan bash4 +:

git check-ignore **/*

(atau find -execperintah)

Catatan: https://stackoverflow.com/users/351947/Rafi B. menyarankan dalam komentar untuk menghindari globstar (berisiko) :

git check-ignore -v $(find . -type f -print)

Pastikan untuk mengecualikan file dari .git/subfolder.


Jawaban asli 42009)

git ls-files -i

harus berfungsi, kecuali kode sumbernya menunjukkan:

if (show_ignored && !exc_given) {
                fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
                        argv[0]);

exc_given ?

Ternyata perlu satu parameter lagi setelah -iuntuk benar-benar daftar apa pun:

Mencoba:

git ls-files -i --exclude-from=[Path_To_Your_Global].gitignore

(tapi itu hanya akan mencantumkan objek yang di- cache (tidak diabaikan), dengan filter, sehingga tidak sesuai dengan yang Anda inginkan)


Contoh:

$ cat .git/ignore
# ignore objects and archives, anywhere in the tree.
*.[oa]
$ cat Documentation/.gitignore
# ignore generated html files,
*.html
# except foo.html which is maintained by hand
!foo.html
$ git ls-files --ignored \
    --exclude='Documentation/*.[0-9]' \
    --exclude-from=.git/ignore \
    --exclude-per-directory=.gitignore

Sebenarnya, dalam file 'gitignore' saya (disebut 'kecualikan'), saya menemukan baris perintah yang dapat membantu Anda:

F:\prog\git\test\.git\info>type exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

Begitu....

git ls-files --others --ignored --exclude-from=.git/info/exclude
git ls-files -o -i --exclude-from=.git/info/exclude

git ls-files --others --ignored --exclude-standard
git ls-files -o -i --exclude-standard

harus melakukan trik.

Seperti disebutkan dalam halaman manual ls-file , --othersadalah bagian penting, untuk menunjukkan kepada Anda file yang tidak di-cache, tidak dikomit, dan biasanya diabaikan.

--exclude_standardbukan hanya jalan pintas, tetapi cara untuk memasukkan semua pengaturan "pola yang diabaikan" standar.

exclude-standard
Tambahkan pengecualian git standar: .git/info/exclude, .gitignoredi setiap direktori, dan user's global exclusion file.

VONC
sumber
@VocC, dari pemahaman saya tentang tes ini , Jawaban yang Anda rekomendasikan di atas hanya dapat memiliki kekurangan besar. Itu sebabnya saya biasanya merekomendasikan jawaban riyad sebagai gantinya.
Alexander Bird
2
Sejak Git v2.13.2 Rilis: git status --ignoredtampaknya ia juga menampilkan file yang tidak dilacak
Pau
1
wow, git check-ignore -v *berfungsi dengan baik, karena menunjukkan di mana konfigurasi diterapkan. Terima kasih.
Hoang Tran
@MikeD Untuk membuat * / work (atau sebenarnya, Anda bisa melakukan **), Anda perlu menetapkan globstar shopt -s globstarsetelah itu akan berfungsi.
Veda
Tanpa mengaktifkan (berisiko) globstar:git check-ignore -v $(find . -type f -print)
rafi
484

Ada cara yang lebih sederhana untuk melakukannya (git 1.7.6+):

git status --ignored

Lihat Apakah ada cara untuk memberi tahu status git untuk mengabaikan efek file .gitignore?

Penghe Geng
sumber
3
Apa versi git yang Anda gunakan? Milik saya (1.7.0.4) mengatakan error: unknown option 'ignored'. Bahkan menambahkan -sseperti yang disarankan di pos tertaut tidak berfungsi.
Alexander Bird
3
Versi saya adalah 1.7.6. Versi lain 1.7.5.1 adalah yang membutuhkan -s. Anda dapat mencoba git status -hmelihat apakah --ignoreddidukung
Penghe Geng
1
Saya kira itu belum didukung di 1.7.0.4. Komputer saya yang lain memiliki 1.7.9 dan bendera --ignored ada
Alexander Bird
4
Saya mencoba setiap solusi di halaman ini. Ini yang terbaik. Ini menunjukkan file dan direktori. Fitur ini mungkin tidak tersedia kembali ketika pertanyaan ini awalnya diajukan. (Omong-omong, semua solusi tidak akan berfungsi dengan baik dengan "git init" yang baru sampai Anda setidaknya telah melakukan perubahan.)
wisbucky
12
Ini tentu jauh lebih baik daripada jawaban yang diterima. Ini juga jauh lebih aman daripada git clean -ndXsolusinya, karena situasi yang jarang terjadi ketika seseorang keliru melupakan bendera akan memiliki efek yang tidak dapat dibatalkan pada repositori, karena file yang tidak terlacak dihapus. Jadi itu berbahaya. Sebaliknya git status --ignoredselalu aman, bahkan ketika salah ketik dan wajar untuk diingat.
Ioannis Filippidis
400

Pilihan lain yang cukup bersih (No pun intended.):

git clean -ndX

Penjelasan:

$ git help clean

git-clean - Remove untracked files from the working tree
-n, --dry-run - Don't actually remove anything, just show what would be done.
-d - Remove untracked directories in addition to untracked files.
-X - Remove only files ignored by Git.

Catatan: Solusi ini tidak akan menampilkan file yang diabaikan yang telah dihapus.

ma11hew28
sumber
Bagus ... namun alasan saya mengajukan pertanyaan asli adalah agar saya dapat memastikan bahwa file vendor (* .dll) yang seharusnya ada ... jadi menghapusnya bukan hasil yang diinginkan. NAMUN: ini bagus untuk diketahui karena saya telah mengubah strategi saya dari mengabaikan * .dll untuk mengabaikan folder output build saya (tetapi tidak folder vendor saya). Ini akan menjadi alternatif yang baik make cleandan sangat membantu pada server build.
Andrew Burns
2
Saya menggunakan git versi 1.7.0.4, dan dua perintah ('git ls-files -o -i --exclude-standard', 'git clean -dXn') tidak setara. Yang pertama menunjukkan kepada saya 4 file, dan yang kedua hanya dua. (.gitignore ~, index.php ~, sql / create_users.sql ~, www / index.php ~) (Akan menghapus .gitignore ~, Akan menghapus index.php ~). Apa aku ada sesuatu di sini?
Cesar
@VonC, manis! Terima kasih! @ Caesar, saya tidak yakin. Saya tidak begitu kenal git ls-files -o -i --exclude-standard. git clean -dXnselalu menjadi apa yang saya inginkan tetapi tidak menunjukkan file yang diabaikan yang telah dihapus. git ls-files -o -i --exclude-standardmungkin melakukan itu. Jadi, mungkin itulah yang menyebabkan perbedaan.
ma11hew28
3
Satu hal kecil - mungkin ide yang baik untuk mengetik yang npertama, lebih sedikit kesempatan untuk tidak sengaja menghapusnya; git clean -ndX
Tobias Cohen
1
@TobiasCohen bagus! Saya memperbarui jawabannya dengan saran Anda. Lebih aman. Meskipun, jika Anda meninggalkan n, Git default ke fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean. Masih cukup aman, tetapi mengetik yang npertama bahkan lebih aman! :)
ma11hew28
39

Meskipun secara umum memperbaiki solusi Anda tidak bekerja dalam semua keadaan. Asumsikan dir repo seperti ini:

# ls **/*                                                                                                       
doc/index.html  README.txt  tmp/dir0/file0  tmp/file1  tmp/file2

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

dan .gitignore menyukai ini:

# cat .gitignore
doc
tmp/*

Ini mengabaikan docdirektori dan semua file di bawah ini tmp. Git berfungsi seperti yang diharapkan, tetapi perintah yang diberikan untuk daftar file yang diabaikan tidak. Mari kita lihat apa yang git katakan:

# git ls-files --others --ignored --exclude-standard                                                            
tmp/file1
tmp/file2

Perhatikan bahwa doctidak ada dalam daftar. Anda bisa mendapatkannya dengan:

# git ls-files --others --ignored --exclude-standard --directory                                                
doc/

Perhatikan --directoryopsi tambahan .

Dari pengetahuan saya tidak ada satu perintah untuk mendaftar semua file yang diabaikan sekaligus. Tapi saya tidak tahu mengapa tmp/dir0tidak muncul sama sekali.

riyad
sumber
2
Ini membuat saya mendapatkan apa yang saya inginkan, sedangkan yang lain tidak (untuk kasus khusus saya) ... terima kasih! Sangat frustasi harus menjalankan dua perintah, tetapi dengan direktori yang diabaikan, opsi --directory setidaknya menemukan saya itu, dan saya dapat menyalurkannya ke perintah find untuk menemukan file. Terima kasih!
lindes
Ini melakukan semuanya sekaligus, dan memperluas direktori:(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | perl -nle '$seen{$_}++||next;if(-d){system"find",$_,"-type","f"}else{print}'
Dee Newcum
17

Git sekarang memiliki fungsi ini bawaan

git check-ignore *

Tentu saja Anda dapat mengubah gumpalan menjadi sesuatu seperti **/*.dlldalam kasus Anda

Referensi Git

qwertymk
sumber
7
git check-ignore **/*untuk memasukkan file dalam subdirektori
mzimmer
ini hanya mencantumkan dicrectories tingkat atas.
Radon8472
13

Itu harus cukup untuk digunakan

git ls-files --others -i --exclude-standard

karena itu mencakup semua yang dicakup oleh

git ls-files --others -i --exclude-from=.git/info/exclude

oleh karena itu yang terakhir adalah mubazir.


Anda dapat mempermudah ini dengan menambahkan alias ke ~/.gitconfigfile Anda :

git config --global alias.ignored "ls-files --others -i --exclude-standard"

Sekarang Anda bisa mengetik git ignored untuk melihat daftar. Jauh lebih mudah diingat, dan lebih cepat mengetik.

Jika Anda lebih suka tampilan solusi Jason Geng yang lebih ringkas, Anda dapat menambahkan alias untuk itu seperti ini:

git config --global alias.ignored "status --ignored -s"

Namun, semakin banyak keluaran verbose lebih berguna untuk mengatasi masalah dengan file .gitignore Anda, karena ini mencantumkan setiap file pemetik kapas tunggal yang diabaikan. Anda biasanya menyalurkan hasilnya grepuntuk melihat apakah file yang Anda harapkan diabaikan ada di sana, atau jika file yang tidak ingin Anda abaikan ada di sana.

git ignored | grep some-file-that-isnt-being-ignored-properly

Kemudian, ketika Anda hanya ingin melihat tampilan pendek, cukup mudah untuk mengingat dan mengetik

git status --ignored

( -sBiasanya dapat ditinggalkan.)

iconoclast
sumber
Ini tidak pernah berhasil bagi saya, karena Anda harus mendaftar secara manual file-file itu. git status --ignoredbekerja di sisi Debian tetapi mungkin sangat baru ... tetapi tampaknya itu ditambahkan karena permintaan populer ;-)
mirabilos
1
Dengan "berfungsi di sisi Debian" Saya menganggap maksud Anda "berfungsi dengan versi Git yang terinstal secara default di sisi Debian"? Anda harus benar-benar menghindari membiarkan diri Anda disandera oleh versi utilitas yang termasuk dalam distro Anda. Anda dapat memutakhirkannya secara independen dari distro itu sendiri.
iconoclast
12

Berikut cara mencetak daftar lengkap file di pohon kerja yang cocok dengan pola yang terletak di mana saja di banyak sumber gitignore Git (jika Anda menggunakan GNU find):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose

Ini akan memeriksa semua file di cabang repositori saat ini (kecuali Anda telah menghapusnya secara lokal).

Dan itu mengidentifikasi baris sumber gitignore tertentu, juga.

Git terus melacak perubahan pada beberapa file yang cocok dengan pola gitignore, hanya karena file-file itu sudah ditambahkan. Berguna, perintah di atas menampilkan file-file itu juga.

Pola gitignore negatif juga cocok. Namun, ini mudah dibedakan dalam daftar, karena mereka mulai dengan !.

Jika Anda menggunakan Windows, Git Bash menyertakan GNU find(seperti yang diungkapkan oleh find --version).

Jika daftar panjang (dan sudah rev ), Anda dapat menampilkannya dengan ekstensi (agak), juga:

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose \
| rev | sort | rev

Untuk lebih jelasnya, lihat man find,man git-check-ignore , man rev, danman sort .

Inti dari keseluruhan pendekatan ini adalah bahwa Git (perangkat lunak) berubah dengan cepat dan sangat kompleks. Sebaliknya, GNUfind adalah sangat stabil (setidaknya, di fitur-fiturnya yang digunakan di sini). Jadi, siapa pun yang ingin menjadi kompetitif dengan menampilkan pengetahuan mendalam mereka tentang Git akan menjawab pertanyaan dengan cara yang berbeda.

Apa jawaban terbaik? Jawaban ini sengaja meminimalkan ketergantungannya pada pengetahuan Git, menuju pencapaian tujuan stabilitas dan kesederhanaan melalui modularitas (isolasi informasi), dan dirancang untuk bertahan lama .

MarkDBlackwell
sumber
Terimakasih banyak! Saya telah berjuang untuk mencari tahu mengapa beberapa file sumber baru saya kadang-kadang hilang dari komitmen saya. Ternyata saya memiliki pola: bin *, yang saya pikir hanya cocok dengan nama file / direktori yang dimulai dengan bin tetapi justru cocok dengan apa pun yang menyertakan bin di path lengkap file / direktori! Saya kira, masalah saya berasal dari kesalahpahaman tentang semantik yang tepat dari pencocokan pola di .gitignore. Skrip 2-baris Anda membantu saya menemukan kesalahan ini!
Nicolas Rouquette
1

(memperluas jawaban lain)

Catatan, git check-ignoregunakan yang berkomitmen .gitignoredan bukan yang di pohon kerja Anda! Untuk memainkannya tanpa mencemari riwayat git Anda, Anda dapat dengan bebas mencoba mengeditnya, dan kemudian berkomitmen dengan a git commit --amend.

Masalah ini terjadi terutama jika Anda memerlukan penyelesaian masalah, bahwa git tidak mengikuti direktori. Masukkan di .gitignore:

dirtokeep/**
!dirtokeep/.keep

.keepharus berupa file nol panjang dirtokeep.

Hasilnya adalah semua yang ada di dalamnya akan dirtokeepdiabaikan, kecuali dirtokeep/.keep , yang akan menghasilkan bahwa dirtokeepdirektori juga akan dibangun di clone / checkout.

peterh - Pasang kembali Monica
sumber
0

Dengan asumsi ada beberapa direktori abaikan, mengapa tidak menggunakan "git status node / logs" yang akan memberi tahu Anda file apa yang akan ditambahkan? Dalam direktori saya memiliki file teks yang bukan bagian dari output status, misalnya:

Pada master cabang Cabang
Anda up-to-date dengan 'asal / master'.
File yang tidak dilacak:
(gunakan "git add ..." untuk memasukkan apa yang akan dikomit)

    node/logs/.gitignore 

.gitignore adalah:

*

! .gitignore

pikknz
sumber