Bagaimana cara mengkonfigurasi git untuk mengabaikan beberapa file secara lokal?

1351

Bisakah saya mengabaikan file secara lokal tanpa mencemari konfigurasi global git untuk semua orang? Saya memiliki file yang tidak terlacak yang merupakan spam dalam status git saya, tetapi saya tidak ingin melakukan perubahan konfigurasi git untuk setiap file acak kecil tunggal yang saya miliki di cabang lokal saya.

Bjorn
sumber

Jawaban:

1864

Dari dokumentasi Git yang relevan :

Pola yang khusus untuk repositori tertentu tetapi yang tidak perlu dibagi dengan repositori terkait lainnya (misalnya, file tambahan yang hidup di dalam repositori tetapi khusus untuk alur kerja satu pengguna) harus masuk ke $GIT_DIR/info/excludefile.

The .git/info/excludeberkas memiliki format yang sama seperti setiap .gitignoreberkas. Pilihan lain adalah mengatur core.excludesFilenama file yang berisi pola global.

Catatan, jika Anda sudah memiliki perubahan yang tidak bertahap, Anda harus menjalankan yang berikut setelah mengedit pola abaikan Anda:

git update-index --assume-unchanged <file-list>

Catatan tentang$GIT_DIR : Ini adalah notasi yang digunakan di seluruh manual git hanya untuk menunjukkan path ke repositori git. Jika variabel lingkungan diatur, maka itu akan menimpa lokasi repo mana Anda berada, yang mungkin bukan yang Anda inginkan.


Sunting : Cara lain adalah menggunakan:

git update-index --skip-worktree <file-list>

Balikkan dengan:

git update-index --no-skip-worktree <file-list>
Josh Lee
sumber
204
Sebagai catatan, pastikan untuk menjalankan git update-index --assume-unchanged [<file>...]setelah melakukan penambahan pada file yang dikecualikan. Perubahan tidak akan diambil sampai saat itu.
tollmanz
30
Saya tidak perlu menjalankan 'git update-index ...' agar perubahan diterapkan menggunakan git 1.7.9.5.
Jeffrey Martinez
39
Anda hanya perlu menggunakan indeks-pembaruan git jika Anda telah membuat perubahan pada file dan sekarang ingin diabaikan. Jika Anda mengubah kecualikan sebelum melakukan perubahan, itu tidak perlu.
Brady Emerson
13
Walaupun ini menghentikan file dari muncul sebagai diubah selama komit seperti .gitignore, tidak seperti file yang diabaikan, file akan tetap diatur ulang ke versi repo jika Anda menjalankan git reset --hard.
Brady Emerson
19
Per stackoverflow.com/questions/23097368/… dan stackoverflow.com/questions/13630849/… , skip-worktreekemungkinan akan lebih disukai assume-unchanged.
danShumway
436

Pembaruan : Pertimbangkan untuk menggunakan git update-index --skip-worktree [<file>...]sebagai gantinya, terima kasih @danShumway! Lihat penjelasan Borealid tentang perbedaan kedua opsi .


Jawaban lama:

Jika Anda perlu mengabaikan perubahan lokal untuk melacak file (kami memiliki itu dengan modifikasi lokal untuk mengkonfigurasi file), gunakan git update-index --assume-unchanged [<file>...] .

Florian Sesser
sumber
8
Sebagai catatan, saya menambahkan file ke $ GIT_DIR / info / exclude (misalnya, my-file.php) dan kemudian harus menjalankannya git update-index --assume-unchanged my-file.phpagar mulai diabaikan. Terima kasih atas tipnya!
tollmanz
78
Untuk membatalkannya: git update-index --no-assume-unchanged my-file.php
Ray
18
Hanya untuk klarifikasi: menganggap-tidak berubah adalah untuk file yang dilacak (ada di repo) ... OP meminta file yang tidak dilacak, dalam hal .git/info/excludeini yang Anda inginkan (untuk menghindari polusi yang sering dibagikan dan dilacak .gitignore)
dyodji
7
Menurut stackoverflow.com/questions/23097368/... ini dianggap tidak aman, dan file Anda mungkin masih dikomit jika Anda tidak hati-hati. Ini dimaksudkan sebagai bantuan kinerja, bukan sebagai solusi yang sangat mudah untuk masalah ini.
danShumway
3
Saya bergegas ke --assume-unchangedsebelum membaca pembaruan Anda . Aku membuka kancing dengan --no-assume-unchangeddan kemudian melakukan --skip-worktree... Am I di jelas?
Nicolas Miari
162

Tambahkan baris berikut ke bagian [alias] file .gitconfig Anda

ignore = update-index --assume-unchanged
unignore = update-index --no-assume-unchanged
ignored = !git ls-files -v | grep "^[[:lower:]]"

Sekarang Anda dapat menggunakan git ignore my_fileuntuk mengabaikan perubahan pada file lokal, dan git unignore my_fileuntuk berhenti mengabaikan perubahan.git ignoreddaftar file yang diabaikan.

Jawaban ini diperoleh dari http://gitready.com/intermediate/2009/02/18/temporently-ignoring-files.html .

Phatmann
sumber
1
"! git ls-files -v | grep" ^ [[:: lebih rendah]] "- Adakah kemungkinan Anda tahu cara melakukan ini di windows cmd?
Haohmaru
3
Instal shell asli (misalnya Babun menyediakan bash atau zsh);) Saya tahu perasaan Anda, tetapi saya baru-baru ini beralih dari Windows ke Linux dan saya tidak akan pernah menggunakan cmd lagi.
Xerus
@ Haohmaru, Anda selalu bisa menggunakan WSL (Windows Subsystem untuk Linux).
A Sz
110

Anda memiliki beberapa opsi:

  • Biarkan file kotor (atau tidak dikomit) .gitignoredi direktori kerja Anda (atau terapkan secara otomatis menggunakan topgit atau alat tambalan lain semacam itu).
  • Masukkan pengecualian ke dalam $GIT_DIR/info/excludefile Anda , jika ini khusus untuk satu pohon.
  • Jalankan git config --global core.excludesfile ~/.gitignoredan tambahkan pola ke ~/.gitignore. Opsi ini berlaku jika Anda ingin mengabaikan pola tertentu di semua pohon. Saya menggunakan ini untuk .pycdan .pyofile, misalnya.

Juga, pastikan Anda menggunakan pola dan tidak secara eksplisit menyebutkan file, jika ada.

Emil Sit
sumber
10
Saya pikir Anda perlu git config --globalmengatur opsi secara global.
Josh Lee
7
Sebenarnya, tambahkan saja .gitignore ke .gitignore;)!
Dominik George
68

Saya pikir Anda mencari:

git update-index --skip-worktree FILENAME

yang mengabaikan perubahan yang dibuat lokal

Inilah http://devblog.avdi.org/2011/05/20/keep-local-modifications-in-git-tracked-files/ penjelasan lebih lanjut tentang solusi ini!

untuk membatalkan penggunaan:

git update-index --no-skip-worktree FILENAME
Piotr Korlaga
sumber
9
Ada diskusi yang relevan antara --skip-worktreedan --assume-unchangedpada pertanyaan SO ini
Merwer
1
Bagaimana saya membatalkan ini, atau melihat daftar file / pola yang saat ini diabaikan --skipworktree, haruskah saya kemudian berubah pikiran dan ingin mulai melacak file lagi?
Anomali
1
bagaimana cara membatalkan ini?
user1735921
3
Untuk membatalkan silakan gunakangit update-index --no-skip-worktree <file>
user1735921
49

Anda dapat menginstal beberapa alias git untuk membuat proses ini lebih sederhana. Ini mengedit [alias]simpul .gitconfigfile Anda .

git config --global alias.ignore 'update-index --skip-worktree'
git config --global alias.unignore 'update-index --no-skip-worktree'
git config --global alias.ignored '!git ls-files -v | grep "^S"'

Pintasan yang dipasang untuk Anda adalah sebagai berikut:

  • git ignore config.xml
    • git akan berpura-pura bahwa itu tidak melihat perubahan apa pun config.xml- mencegah Anda dari melakukan perubahan itu secara tidak sengaja.
  • git unignore config.xml
    • git akan melanjutkan mengakui perubahan Anda ke config.xml- memungkinkan Anda lagi untuk melakukan perubahan itu.
  • git ignored
    • git akan mencantumkan semua file yang Anda "abaikan" dengan cara yang dijelaskan di atas.

Saya membangun ini dengan merujuk pada jawaban Phatmann - yang menyajikan --assume-unchangedversi yang sama.

Versi yang saya sajikan menggunakan --skip-worktreeuntuk mengabaikan perubahan lokal. Lihat jawaban Borealid untuk penjelasan lengkap tentang perbedaannya, tetapi pada dasarnya --skip-worktreetujuan pengembang adalah untuk mengubah file tanpa risiko melakukan perubahan mereka .

The git ignoredperintah disajikan di sini menggunakan git ls-files -v, dan menyaring daftar untuk menunjukkan hanya entri-entri yang diawali dengan Stag. The Stag menunjukkan file yang statusnya "skip worktree". Untuk daftar lengkap dari status file yang ditunjukkan oleh git ls-files: lihat dokumentasi untuk -topsi aktif git ls-files.

Birchlabs
sumber
1
Ini tidak berfungsi untuk file yang tidak dilacak: <(git 2.13.5 di osx)
Terra Ashley
Adalah '!' seharusnya di dalam '!git ls-files -v | grep "^S"'? Perintah tidak bekerja untuk saya dengan itu di sana .. dan tampaknya berfungsi dengan baik dengan itu dihapus.
Tiris
tanda seru di git alias memberitahu git untuk menjalankan perintah eksternal , bukan subperintah git . Saya memasukkannya ke dalam karena saya membutuhkan pipa shell, jadi saya perlu memanggil git dari luar. Saya baru saja mencoba menghapus tanda seru (sesuai rekomendasi Anda), tetapi itu tidak berhasil bagi saya. Saya mengerti Expansion of alias 'ignored' failed; 'git' is not a git command. Ini masuk akal; tanpa tanda seru: git alias perintah Anda untuk git git ls-files ….
Birchlabs
Terima kasih untuk penjelasannya. Saya tidak terbiasa dengan git alias dan hanya menjalankan shell untuk menguji sebelum membuat alias.
Tiris
Ini solusi brilian. Karena git track per direktori, ketika Anda menjalankan alias di atas git ignore <filename>, itu hanya berlaku untuk direktori itu. Dan ketika Anda akhirnya ingin membuat perubahan pada file itu dan komit serta dorong ke jarak jauh, cukup gunakan alat ini git unignore <filename>untuk sementara waktu mulai melacaknya lagi! Terima kasih!
Nickang
42

Anda cukup menambahkan file .gitignore ke direktori home Anda, yaitu $HOME/.gitignoreatau ~/.gitignore. Kemudian beri tahu git untuk menggunakan file itu dengan perintah:

git config --global core.excludesfile ~/.gitignore

Ini adalah file .gitignore normal yang mendapat referensi ketika memutuskan apa yang harus diabaikan. Karena ada di direktori home Anda, itu hanya berlaku untuk Anda dan tidak mencemari file .gitignore proyek apa pun.

Saya telah menggunakan pendekatan ini selama bertahun-tahun dengan hasil yang bagus.

JESii
sumber
Terima kasih, @EricChen. Saya telah memperbarui jawaban; coba itu dan kemudian gunakan git check-ignore <file-name>untuk memverifikasi. LMK jika itu bekerja untuk Anda
YESUS
Itu hanya bekerja untuk saya tanpa =:git config --global core.excludesfile ~/.gitignore
E. Sundin
Saya meletakkan .gitignorefile di bawah direktori home dan menyuruh git untuk menggunakan file itu, lalu menghapus file yang ingin saya undak secara lokal. Namun, setelah saya mendorong perubahan, repositori jarak jauh juga menghapus file-file itu. Apakah saya melakukan sesuatu yang salah?
zyy
Wow, @xyz; .gitignoreadalah tentang mengabaikan file yang ada di direktori lokal Anda. Apa yang seharusnya Anda lakukan adalah git rm --cachedyang menghapusnya dari repo tetapi membiarkannya di lokal Anda. Anda harus dapat kembali ke komit sebelumnya dengan sesuatu seperti git reset --soft HEAD^membatalkan komit itu dan memulihkan file Anda. Itulah keindahan dari git: semuanya masih ada dalam sejarah git Anda.
YESUS
2

Untuk mengabaikan file yang tidak dilacak terutama jika mereka berada di (beberapa) folder yang tidak dilacak, solusi sederhana adalah menambahkan .gitignorefile ke setiap folder yang tidak dilacak dan masukkan dalam satu baris yang berisi *diikuti dengan baris baru. Ini adalah solusi yang sangat sederhana dan mudah jika file yang tidak dilacak ada di beberapa folder. Bagi saya, semua file berasal dari satu folder yang tidak terlacak vendordan di atas hanya berfungsi.

aak318
sumber
1
Bagus! FYI: Ini berfungsi hanya karena git hanya melacak (dan memungkinkan Anda melakukan) file, bukan folder.
jmiserez
-2

Jika repo Anda belum memiliki file .gitignore, maka solusi sederhana adalah membuat file .gitignore, dan di dalamnya tambahkan .gitignoreke daftar file yang akan diabaikan.

Gavin S. Yancey
sumber
4
Dan bagaimana jika tim kemudian ingin menambahkan untuk menambahkan gitignore nanti? Apakah ini berhasil? Kedengarannya seperti ide yang buruk dan seperti sesuatu yang seharusnya tidak berfungsi.
Bjorn
Jawaban orang ini membuatku jengkel. Tidak mungkin ada orang yang melakukan ini.
Martyn Chamberlin
Ini adalah solusi cepat dan sederhana, asalkan ada tempat untuk meletakkannya. Repo kami memiliki .gitignorefile bersama di bagian atas. Tetapi file kotor saya ada di folder yang dalam, jadi saya baru saja menambahkan file saya sendiri di .gitignoresebelahnya. +1
joeytwiddle