Git diff mengatakan subproyek itu kotor

227

Saya baru saja menjalankan git diff, dan saya mendapatkan output berikut untuk semua sekitar 10 submodul saya

diff --git a/.vim/bundle/bufexplorer b/.vim/bundle/bufexplorer
--- a/.vim/bundle/bufexplorer
+++ b/.vim/bundle/bufexplorer
@@ -1 +1 @@
-Subproject commit 8c75e65b647238febd0257658b150f717a136359
+Subproject commit 8c75e65b647238febd0257658b150f717a136359-dirty

Apa artinya ini? Bagaimana saya memperbaikinya?

mrwooster
sumber

Jawaban:

268

Seperti yang disebutkan dalam posting blog Mark Longair, Git Submodules Dijelaskan ,

Versi 1.7.0 dan yang lebih baru dari git berisi perubahan yang mengganggu dalam perilaku submisi git.
Submodules sekarang dianggap kotor jika mereka memiliki file yang dimodifikasi atau file yang tidak terlacak , sedangkan sebelumnya hanya akan menjadi kasus jika KEPALA dalam submodule menunjuk komit yang salah.

Arti tanda tambah ( +) dalam output dari submitule git telah berubah, dan pertama kali Anda menemukan ini, perlu sedikit waktu untuk mencari tahu apa yang salah, misalnya dengan melihat melalui changelogs atau menggunakan git bisect pada git .git untuk menemukan perubahannya. Akan jauh lebih baik bagi pengguna untuk memperkenalkan simbol yang berbeda untuk "pada versi yang ditentukan, tetapi kotor".

Anda dapat memperbaikinya dengan:

  • baik melakukan atau membatalkan perubahan / evolusi dalam setiap submodul Anda, sebelum kembali ke induk repo (di mana diff seharusnya tidak melaporkan file "kotor" lagi). Untuk membatalkan semua perubahan pada submodule Anda, cdmasuk ke direktori root dari submodule Anda dan lakukangit checkout .

    komentar dotnetCarpenter yang dapat Anda lakukan:git submodule foreach --recursive git checkout .

  • atau tambahkan --ignore-submoduleske git diff, untuk sementara waktu mengabaikan submodul yang "kotor" itu.

Baru di Git versi 1.7.2

Seperti komentar Noam di bawah , pertanyaan ini menyebutkan bahwa, sejak git versi 1.7.2, Anda dapat mengabaikan submodul kotor dengan:

git status --ignore-submodules=dirty
VONC
sumber
2
Juga hal yang baik untuk diketahui: Anda masih dapat mengeksekusi git commit -atanpa harus khawatir menambahkan perubahan ini. Meskipun mereka ditandai dengan Mdi depan, mereka tidak akan berakhir di komit Anda.
gitaarik
1
Bagi saya, saya harus masuk ke setiap submodule kotor dan lari git clean -id.
GDP2
1
@ GDP2 Yang Anda dapat don dalam satu baris, dengan git submodule foreach --recursive git clean -id(untuk diuji dalam repo cadangan pertama;))
VonC
1
Kasus saya terus melihat ini secara tidak dapat dijelaskan, apa yang terjadi adalah bahwa saya memiliki file yang tidak terlacak yang tidak ada dalam submodule .gitignore. Menambahkannya di sana atau ke daftar abaikan global saya memperbaiki hal-hal.
Ben
21

Juga menghapus submodule dan kemudian berjalan git submodule initdan git submodule updatejelas akan melakukan trik, tetapi mungkin tidak selalu sesuai atau mungkin.

pengguna1178907
sumber
1
Ini bekerja untuk saya ketika saya mengkonversi beberapa folder yang ada ke submodules dan kemudian menarik ke komputer lain yang masih memiliki folder lama.
Roger Lipscombe
18

Untuk mengabaikan semua file yang tidak dilacak dalam submodule apa pun, gunakan perintah berikut untuk mengabaikan perubahan itu.

git config --global diff.ignoreSubmodules dirty

Ini akan menambahkan opsi konfigurasi berikut ke konfigurasi git lokal Anda:

[diff]
  ignoreSubmodules = dirty

Informasi lebih lanjut dapat ditemukan di sini

Devpool
sumber
16

EDIT : Jawaban ini (dan sebagian besar yang lain) sudah usang; lihat jawaban Devpool sebagai gantinya .


Awalnya, tidak ada opsi konfigurasi untuk dibuat "git diff --ignore-submodules " dan " git status --ignore-submodules" default global (tetapi lihat juga Menetapkan flag default git pada perintah ). Alternatifnya adalah dengan menetapkan ignoreopsi konfigurasi default pada setiap submodule yang ingin Anda abaikan (untuk keduanya git diffdan git status), baik dalam .git/configfile (hanya lokal) atau .gitmodules(akan diversi oleh git). Sebagai contoh:

[submodule "foobar"]
    url = [email protected]:foo/bar.git
    ignore = untracked

ignore = untrackeduntuk mengabaikan hanya file yang tidak dilacak, ignore = dirtyjuga mengabaikan file yang dimodifikasi, dan ignore = allmengabaikan juga komitmen. Tampaknya tidak ada cara untuk wildcard itu untuk semua submodula.

Ralph Versteegen
sumber
13

Ini terjadi karena pointer yang Anda miliki untuk submodule bukan apa yang sebenarnya ada di direktori submodule. Untuk memperbaiki ini, Anda harus menjalankan git submodule updatelagi:

Robin Ren
sumber
9
git submodule foreach --recursive git checkout .

Ini tidak melakukan trik untuk saya tetapi memberi saya daftar file (dalam kasus saya hanya satu) yang telah diubah dalam submodule (tanpa saya melakukan apa pun di sana).

Jadi saya bisa menuju ke submodule dan status git menunjukkan kepada saya bahwa KEPALA saya terlepas -> master checkout git, status git untuk melihat file yang dimodifikasi sekali lagi, git checkout> nama file <, git pull dan semuanya baik-baik saja.

Hanya sedikit
sumber
9

Saya akhirnya menghapus direktori submodule dan menginisialisasi sekali lagi

cd my-submodule
git push
cd ../
rm -rf my-submodule
git submodule init
git submodule update
Szymon Wygnański
sumber
4
Saya lebih suka mengerti apa yang terjadi, tetapi ini juga satu-satunya hal yang berhasil untuk saya ...
smilebomb
6

Sebuah submodule dapat ditandai sebagai kotor jika pengaturan filemode diaktifkan dan Anda mengubah izin file di subtree submodule.

Untuk menonaktifkan filemode dalam submodule, Anda dapat mengedit /.git/modules/path/to/your/submodule/config dan menambahkan

[core]
  filemode = false

Jika Anda ingin mengabaikan semua status kotor, Anda dapat menyetel ignore = dirtyproperti di file /.gitmodules , tapi saya pikir lebih baik menonaktifkan saja file mode .

dryobs
sumber