Bu, okuyucunun yararı için, onu özetlemeye ve işler beklendiği gibi çalışmazsa nasıl yapılacağına dair adım adım bir kılavuz vermeye çalışır. Aşağıda test edilmiş ve güvenli bir yol için gitsürümüne 2.17ve üzeri bir altmodülün kurtulmak için :
submodule="path/to/sub" # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
- Bu sizin için işe yaramazsa aşağıya bakın.
- Seçenek yok. Tehlikeli bir şey yok. Ve daha fazlasını yapmayı bile düşünmeyin!
- Debian Buster
2.20.1ve Ubuntu 18.04 ile test edildi 2.17.1.
"$submodule" sadece adı nereye koyacağınızı ve boşluklara ve benzerlerine dikkat etmeniz gerektiğini vurgulamaktır
- Windows üzerinde ise, ilk satırı yok sayın
"$submodule"ve alt modüle doğru şekilde belirlenmiş bir yolun Windows yoluyla değiştirin . (Ben Windows değilim)
Uyarı!
Asla .gitdizinin iç kısımlarına dokunmayın ! İçeride düzenleme .gitkaranlık tarafa girer. Ne pahasına olursa olsun uzak dur!
Ve evet, bunun gitiçin suçlayabilirsiniz , çünkü gitgeçmişte birçok kullanışlı şey eksikti . Alt modülleri tekrar çıkarmanın uygun bir yolu gibi.
Dokümantasyonunda çok tehlikeli bir kısım olduğunu düşünüyorum git submodule. $GIT_DIR/modules/<name>/Kendinizi çıkarmanızı önerir .
Anladığım kadarıyla bu sadece basit bir yanlış değil, son derece tehlikelidir ve gelecekte büyük baş ağrılarına neden olur! Aşağıya bakınız.
Bunu not et
git module deinit
doğrudan ters
git module init
fakat
git submodule deinit -- module
git rm -- module
ayrıca oldukça ters
git submodule add -- URL module
git submodule update --init --recursive -- module
çünkü bazı komutların temelde tek bir şeyden daha fazlasını yapması gerekir:
git submodule deinit -- module
- (1) güncelleme
.git/config
git rm
- (2) modülün dosyalarını kaldırır
- (3) böylece alt modülün alt modüllerini tekrar tekrar kaldırır
- (4) güncelleme
.gitmodules
git submodule add
- verileri içine çeker
.git/modules/NAME/
- (1) yapar
git submodule init, bu yüzden güncellemeler.git/config
- (2)
git submodule update, modülü tekrar tekrar kontrol etmez
- (4) güncelleme
.gitmodules
git submodule update --init --recursive -- module
- gerekirse daha fazla veri çeker
- (3) alt modülün alt modüllerini tekrar tekrar kontrol eder
Bu tamamen simetrik olamaz, çünkü kesinlikle simetrik tutmak pek mantıklı değildir. İkiden fazla komuta gerek yoktur. Ayrıca, "veriyi çekmek" örtüktür, çünkü buna ihtiyacınız vardır, ancak önbelleğe alınmış bilgilerin kaldırılması yapılmaz, çünkü bu hiç gerekli değildir ve değerli verileri silebilir.
Bu gerçekten yeni gelenler için şaşırtıcı, ama temelde iyi bir şey: gitsadece açık bir şey yapar ve bunu doğru yapar ve daha fazlasını yapmaya bile çalışmaz. gitbaşka bir "Eierlegende Wollmilchsau" olmak yerine güvenilir bir iş yapması gereken bir araçtır ("Eierlegende Wollmilchsau" benim için "İsviçreli bir ordu bıçağının kötü versiyonuna" çevirir).
Bu yüzden insanların şikayetlerini anlıyorum, "Neden gitbenim için açık olanı yapmıyor ". Çünkü buradaki "açık" bakış açısından bağlıdır. Her durumda güvenilirlik çok daha önemlidir. Bu nedenle, sizin için açık olan şey, olası tüm teknik durumlarda doğru olan şey değildir. Lütfen unutmayın: AFAICS gitsosyal yolu değil, teknik yolu izler. (Dolayısıyla akıllı isim: git)
Bu başarısız olursa
Yukarıdaki komutlar aşağıdakiler nedeniyle başarısız olabilir:
- Sizin
gitçok eski. Sonra daha yenisini kullanın git. (Nasıl yapılacağı konusunda aşağıya bakın.)
- Onaylanmamış verileriniz var ve verilerinizi kaybedebilirsiniz. O zaman ilk önce onları halletsen iyi olur.
- Alt modülünüz bir
git cleananlamda temiz değil . Ardından önce bu komutu kullanarak alt modülünüzü temizleyin. (Aşağıya bakınız.)
- Geçmişte desteklenmeyen bir şey yaptınız
git. O zaman karanlık taraftasın ve işler çirkinleşiyor ve karmaşıklaşıyor. (Belki başka bir makine kullanmak sorunu düzeltir.)
- Belki de bilmediğim başarısız olmanın daha fazla yolu var (Ben sadece biraz
gitgüç kullanıcısıyım.)
Olası düzeltmeler takip edilir.
Daha yeni bir tane kullanın git
Makineniz çok eskiyse hayır vardır submodule deinitGözlerinde farklı git. Güncellemenizi istemiyorsanız (veya yapamıyorsanız) git, daha yeni bir makine kullanın git! gittamamen dağıtılmak içindir, bu nedenle gitişi yapmak için başka bir tane kullanabilirsiniz :
workhorse:~/path/to/worktree$ git status --porcelain hiçbir şey çıktı olmamalıdır ! Varsa, önce şeyleri temizleyin!
workhorse:~/path/to/worktree$ ssh account@othermachine
othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
- Şimdi alt modül işlerini yapın
othermachine:~/TMPWORK$ git commit . -m . && exit
workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD. Bu işe yaramazsa,git reset --soft FETCH_HEAD
- Şimdi bir şeyleri
git statustemizle, tekrar temiz olana kadar . Bunu yapabilirsiniz, çünkü ilk adım sayesinde daha önce temizlediniz.
Bu othermachine, bir VM veya Windows altındaki bazı Ubuntu WSL olabilir. Hatta bir chroot(ama kök olmayan olduğunu varsayıyorum, çünkü eğer öyleyse rootyenisine güncellemek daha kolay olmalı git).
Not açamıyorsa sshüzere ulaşım yolları trainloads vardır gitdepoları. Çalışma ağacınızı bazı USB çubuklara ( .gitdizin dahil ) kopyalayabilir ve çubuktan klonlayabilirsiniz. Sadece temiz bir şekilde bir şeyler almak için kopyayı kopyalayın. Alt modüllerinize doğrudan diğer makineden erişilememesi durumunda, bu bir PITA olabilir. Ancak bunun için de bir çözüm var:
git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX
Bu çarpımı kullanabilirsiniz ve bu içine kaydedilir $HOME/.gitconfig. Gibi bir şey
git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/
gibi URL'leri yeniden yazar
https://github.com/XXX/YYY.git
içine
/mnt/usb/repo/XXX/YYY.git
Böyle güçlü gitözelliklere alışmaya başlarsanız çok kolaydır .
Önce şeyleri temizle
Elle temizlemek iyidir, çünkü bu şekilde unuttuğunuz bazı şeyleri tespit edebilirsiniz.
- Git kaydedilmemiş şeylerden şikayet ederse, taahhüt edin ve güvenli bir yere itin.
- Git bazı yemeklerden şikayetçiyse
git statusve git clean -ixfdarkadaşınsa
- Seçenekler kaçınmak için deneyin
rmve deinitolabildiğince sürece. Eğer bir Pro iseniz seçenekleri (gibi -f) gitiyidir. Ama buraya geldiğiniz gibi, muhtemelen submodulebölgede çok deneyimli değilsiniz . Bu yüzden üzülmektense güvende olsan iyi olur.
Misal:
$ git status --porcelain
M two
$ git submodule deinit two
error: the following file has local modifications:
two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
NEW
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each
5: quit 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'
Bakın, buna -fgerek yok submodule deinit. İşler temizse, bir git cleanbakıma. Ayrıca git clean -xgerekli olmadığını da unutmayın . Bu git submodule deinit, yoksayılan izlenmemiş dosyaları koşulsuz olarak kaldırdığı anlamına gelir . Bu genellikle istediğiniz şeydir, ancak unutmayın. Bazen yok sayılan dosyalar, yeniden hesaplanması saatler veya günler süren önbelleğe alınmış veriler gibi değerli olabilir.
Neden asla çıkarmıyorsunuz $GIT_DIR/modules/<name>/?
Muhtemelen insanlar önbelleğe alınmış depoyu kaldırmak istiyorlar, çünkü daha sonra bir sorunla karşılaşmaktan korkuyorlar. Bu doğrudur, ancak bu "problem" ile karşılaşmak onu çözmenin doğru yoludur! Düzeltme kolay ve doğru yapıldığından sonsuza dek mutlu yaşayabileceksiniz. Bu, verileri kendiniz kaldırdığınızdan daha zahmetli bir sorunu önler.
Misal:
mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two
Son satır şu hatayı verir:
A git directory for 'two' is found locally with remote(s):
origin https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
Neden bu hata? Çünkü .git/modules/two/daha önce https://github.com/hilbix/empty.git adresinden dolduruldu ve şimdi başka bir şeyden, yani https://github.com/hilbix/src.git olarak yeniden doldurulacak . Https://github.com/hilbix/empty.git adresinden yeniden doldurursanız bunu görmezsiniz
Şimdi ne yapmalı? Peki, aynen söylendiği gibi yapın! kullanım--name someunusedname
git submodule add --name someunusedname https://github.com/hilbix/src.git two
.gitmodules sonra benziyor
[submodule "someunusedname"]
path = two
url = https://github.com/hilbix/src.git
ls -1p .git/modules/ verir
someunusedname/
two/
Bu şekilde size dalları geçiş yapabilirsiniz gelecekte / ileri ve geri işlemek ve yeniden herhangi belaya asla nedeniyle, two/iki farklı (ve muhtemelen uyumsuz) memba depoları sahip. Ve en iyisi: Her ikisini de yerel olarak önbelleğe al.
- Bu sadece sizin için geçerli değil. Deponuzu kullanan diğer herkes için de geçerlidir.
- Ve tarihi kaybetmezsiniz. Eski alt modülün en son sürümünü aktarmayı unuttuysanız, yerel kopyayı girebilir ve daha sonra yapabilirsiniz. Birisinin bazı alt modülleri itmeyi unutmasının oldukça yaygın olduğuna dikkat edin (çünkü bu alışmaya başlayana kadar yeni gelenler için bir PITA'dır
git).
Ancak önbelleğe alınan dizini kaldırdıysanız, --nameseçenekleri kullanamayacağınız için her iki farklı ödeme birbiri üzerine rastlar , değil mi? Yani her ödeme yaptığınızda, .git/modules/<module>/dizini tekrar tekrar kaldırmanız gerekebilir . Bu son derece hantaldır ve benzeri bir şeyi kullanmayı zorlaştırır git bisect.
Bu nedenle bu modül dizinini yer tutucu olarak tutmak için çok teknik bir neden var. Aşağıdaki bir şeyi kaldırmayı öneren kişiler .git/modules/daha iyi bilmezler veya git bisectbu tür bir alt modül uyumsuzluğunu geçerse bunun neredeyse imkansız gibi güçlü özellikleri kullanmasını söylemeyi unuturlar .
Başka bir neden yukarıda gösterilmiştir. Şuna bak ls. Orada ne görüyorsun?
Modülün 2. varyantı two/altında .git/modules/two/değil, altında .git/modules/someunusedname/! Yani gibi şeyler git rm $module; rm -f .git/module/$moduletamamen yanlış! Çıkarmanız module/.gitveya .gitmoduleskaldırmanız gereken doğru şeyi bulmanız gerekir !
Yani sadece diğer çoğu cevap bu tehlikeli tuzağa düşmekle kalmıyor, çok popüler gituzantılar bile bu hatayı aldı ( şimdi orada düzeltildi )! .git/Eğer tam olarak yapmazsanız çok daha iyi dizin, ne yaptığınızı!
Felsefi açıdan bakıldığında, tarihi silmek her zaman yanlıştır!
Kuantum mekaniği hariç , her zamanki gibi, ama bu tamamen farklı bir şey.
Muhtemelen tahmin ettiniz : hilbix benim GitHub hesabım.
git rm modulenameverm -rf .git/modules/modulename