पाठक के लाभ के लिए, यह यहाँ इसे समेटने की कोशिश करता है और चरण-दर-चरण मार्गदर्शिका देता है कि यह कैसे करना है यदि चीजें अपेक्षा के अनुरूप काम नहीं करती हैं। पीछा कर रहा है परीक्षण किया है और सुरक्षित तरीका के लिए git
संस्करण 2.17
और इसके बाद के संस्करण एक submodule से छुटकारा पाने के :
submodule="path/to/sub" # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
- यदि यह आपके लिए काम नहीं करता है, तो नीचे देखें।
- कोई विकल्प नहीं। कुछ भी खतरनाक नहीं। और अधिक करने पर भी विचार नहीं करते!
- डेबियन बस्टर
2.20.1
और उबंटू 18.04 के साथ परीक्षण किया गया2.17.1
।
"$submodule"
केवल इस बात पर जोर देना है कि नाम कहां रखा जाए, और आपको रिक्त स्थान और इस तरह से सावधान रहना होगा
- यदि विंडोज पर पहली लाइन को नजरअंदाज किया जाए और सबमॉड्यूल
"$submodule"
के लिए एक ठीक से निर्दिष्ट पथ के विंडोज तरीके से प्रतिस्थापित किया जाए। (मैं विंडोज नहीं हूँ)
चेतावनी!
कभी भी .git
निर्देशिका के इनडायरेक्ट को स्पर्श न करें ! अंदर संपादन.git
अंधेरे पक्ष में प्रवेश करता है। हर कीमत पर दूर रहें!
और हां, आप इसके लिए दोषी ठहरा सकते हैं git
, क्योंकि बहुत सी आसान चीजें गायब थींgit
अतीत । फिर से सबमॉड्यूल्स को हटाने के लिए एक उचित तरीके की तरह।
मुझे लगता है कि प्रलेखन में बहुत खतरनाक हिस्सा है git submodule
। यह $GIT_DIR/modules/<name>/
खुद को दूर करने की सलाह देता है ।
मेरी समझ में यह केवल सादा गलत नहीं है, यह बेहद खतरनाक है और भविष्य में प्रमुख सिरदर्द को उकसाता है! निचे देखो।
ध्यान दें कि
git module deinit
से सीधा उलटा है
git module init
परंतु
git submodule deinit -- module
git rm -- module
भी काफी उलटा है
git submodule add -- URL module
git submodule update --init --recursive -- module
क्योंकि कुछ आज्ञाओं को मूल रूप से केवल एक ही चीज़ से अधिक करने की आवश्यकता होती है:
git submodule deinit -- module
git rm
- (2) मॉड्यूल की फ़ाइलों को निकालता है
- (3) जिससे पुन: सबमॉड्यूल के सबमॉड्यूल्स को हटा दिया जाता है
- (४) अद्यतन
.gitmodules
git submodule add
- डेटा में खींचता है
.git/modules/NAME/
- (1) करता है
git submodule init
, इसलिए अपडेट करता है.git/config
- (2) करता है
git submodule update
, इसलिए, गैर-मॉड्यूल की जाँच करता है
- (४) अद्यतन
.gitmodules
git submodule update --init --recursive -- module
- यदि आवश्यक हो तो आगे डेटा में खींचता है
- (3) सबमॉड्यूल के सबमॉड्यूल्स की पुनरावृत्ति की जाँच करता है
यह पूरी तरह से सममित नहीं हो सकता है, क्योंकि इसे सख्ती से सममित रखने से बहुत अधिक समझ में नहीं आता है। बस दो से अधिक आदेशों की आवश्यकता नहीं है। इसके अलावा "डेटा में खींच" अंतर्निहित है, क्योंकि आपको इसकी आवश्यकता है, लेकिन कैश की गई जानकारी को निकालना नहीं है, क्योंकि यह बिल्कुल भी आवश्यक नहीं है और कीमती डेटा मिटा सकता है।
यह वास्तव में नए लोगों के लिए अजीब है, लेकिन मूल रूप से एक अच्छी बात है: git
बस स्पष्ट रूप से काम करता है और वह सही करता है, और अधिक करने की कोशिश भी नहीं करता है। git
एक उपकरण है, जो एक विश्वसनीय काम करना चाहिए, बजाय केवल एक और "Eierlegende Wollmilchsau" ("Eierlegende Wollmilchsau" मेरे लिए "एक स्विस सेना के चाकू के कुछ बुरे संस्करण") का अनुवाद करता है।
इसलिए मैं लोगों की शिकायतों को समझता हूं, " git
मेरे लिए स्पष्ट काम क्यों नहीं करता है"। ऐसा इसलिए है क्योंकि यहाँ "स्पष्ट" दृष्टिकोण से निर्भर करता है। प्रत्येक स्थिति में विश्वसनीयता कहीं अधिक महत्वपूर्ण है। इसलिए आपके लिए जो स्पष्ट है वह प्रायः सभी संभव तकनीकी स्थितियों में सही नहीं है। कृपया याद रखें कि: वायुसेनाgit
तकनीकी पथ का अनुसरण करता है, न कि सामाजिक। (इसलिए चतुर नाम: git)
यदि यह विफल रहता है
ऊपर दिए गए आदेश निम्नलिखित के कारण विफल हो सकते हैं:
- आपका
git
बहुत पुराना है। फिर एक नया प्रयोग करें git
। (नीचे देखें कि कैसे)
- आपके पास डेटा नहीं है और डेटा खो सकता है। फिर पहले उन्हें बेहतर तरीके से प्रतिबद्ध करें।
- आपका सबमॉडल एक
git clean
मायने में साफ नहीं है। फिर उस कमांड का उपयोग करके पहले अपने सबमॉड्यूल को साफ करें। (निचे देखो।)
- आपने अतीत में कुछ किया है जो कि असमर्थित है
git
। फिर आप अंधेरे की ओर हैं और चीजें बदसूरत और जटिल हो जाती हैं। (शायद किसी अन्य मशीन का उपयोग करके इसे ठीक करता है।)
- शायद विफल होने के और भी तरीके हैं जिनके बारे में मुझे जानकारी नहीं है (मैं सिर्फ कुछ
git
पावर-उपयोगकर्ता हूं ।)
संभव फिक्स का पालन करें।
एक नए का उपयोग करें git
यदि आपकी मशीन बहुत पुरानी है, तो आप में कोई भी नहीं submodule deinit
है git
। यदि आप नहीं चाहते (या कर सकते हैं) अपने अद्यतन git
, तो बस एक नए के साथ एक और मशीन का उपयोग करें git
! git
पूरी तरह से वितरित करने के लिए है, इसलिए आप git
काम पूरा करने के लिए दूसरे का उपयोग कर सकते हैं :
workhorse:~/path/to/worktree$ git status --porcelain
कुछ भी आउटपुट नहीं करना चाहिए ! यदि ऐसा होता है, तो पहले चीजों को साफ करें!
workhorse:~/path/to/worktree$ ssh account@othermachine
othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
- अब सबमॉड्यूल स्टफ करें
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
। यदि यह काम नहीं करता है, तो उपयोग करेंgit reset --soft FETCH_HEAD
- अब चीजों
git status
को साफ करें , जब तक फिर से साफ न हो जाए। आप ऐसा करने में सक्षम हैं, क्योंकि आपने पहले चरण के लिए इसे पहले साफ कर दिया है।
यह othermachine
विंडोज के तहत कुछ वीएम, या कुछ उबंटू डब्ल्यूएसएल हो सकता है, जो भी हो। यहां तक कि एक chroot
(लेकिन मुझे लगता है कि आप गैर-रूट हैं, क्योंकि यदि आप हैं root
तो नए को अपडेट करना अधिक आसान होना चाहिए git
)।
ध्यान दें कि यदि आप नहीं कर सकते हैं ssh
, तो git
रिपॉजिटरी को परिवहन करने के तरीकों के ट्रेन लोड हैं । आप कुछ USB स्टिक ( .git
डायरेक्टरी सहित ) पर अपने वर्कट्री को कॉपी कर सकते हैं और स्टिक से क्लोन कर सकते हैं। कॉपी को क्लोन करें, बस चीजों को फिर से साफ-सुथरे अंदाज में पाने के लिए। यह एक पीआईटीए हो सकता है, यदि आपका सबमॉडल्स सीधे अन्य ममीने से सुलभ नहीं हैं। लेकिन इसके लिए एक समाधान भी है:
git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX
आप इस गुणा उपयोग कर सकते हैं, और इस में सहेजा गया है $HOME/.gitconfig
। कुछ इस तरह
git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/
जैसे URL फिर से लिखते हैं
https://github.com/XXX/YYY.git
में
/mnt/usb/repo/XXX/YYY.git
यदि आप git
इस तरह शक्तिशाली सुविधाओं के आदी होने लगते हैं तो यह आसान है ।
पहले चीजों को साफ करें
मैन्युअल रूप से सफाई करना अच्छा है, क्योंकि इस तरह से आप शायद कुछ ऐसी चीजों का पता लगाते हैं जिनके बारे में आप भूल गए हैं।
- यदि गिट बिना सहेजे गए सामान के बारे में शिकायत करता है, तो उसे सुरक्षित कहीं पर धकेलें।
- अगर गिट कुछ बचे हुए के बारे में शिकायत करता है,
git status
और git clean -ixfd
आपका दोस्त है
- विकल्पों के अनुसार
rm
और deinit
जब तक आप कर सकते हैं, तब तक छोड़ने का प्रयास करें । यदि आप प्रो हैं तो विकल्प (जैसे -f
) git
अच्छे हैं। लेकिन जैसा कि आप यहां आए थे, आप शायद इस submodule
क्षेत्र में इतने अनुभवी नहीं हैं। इसलिए बेहतर है कि क्षमा करें।
उदाहरण:
$ 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'
तुम देखते हो, कोई -f
जरूरत नहीं है submodule deinit
। अगर चीजें साफ हैं, एक git clean
अर्थ में। यह भी ध्यान दें कि git clean -x
जरूरत नहीं है। इसका मतलब है git submodule deinit
बिना शर्त फाइलें हटा दी जाती हैं जिन्हें नजरअंदाज कर दिया जाता है। यह आमतौर पर आप क्या चाहते हैं, लेकिन इसके बारे में मत भूलना। कभी-कभी नजरअंदाज की गई फाइलें कीमती हो सकती हैं, जैसे कैश्ड डेटा जो फिर से गणना किए जाने में घंटों लेता है।
कभी हटाए क्यों नहीं $GIT_DIR/modules/<name>/
?
संभवतः लोग कैश्ड रिपॉजिटरी को हटाना चाहते हैं, क्योंकि वे बाद में किसी समस्या में भाग लेने से डरते हैं। यह सच है, लेकिन इसे हल करने का सही तरीका "समस्या" है! क्योंकि तय करना आसान है, और सही किया गया तो आप कभी भी खुशी से रह पाएंगे। जब आप डेटा को हटाते हैं तो यह अधिक बोझिल परेशानी से बचता है।
उदाहरण:
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
त्रुटि के बाद अंतिम पंक्ति आउटपुट:
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.
यह त्रुटि क्यों? क्योंकि .git/modules/two/
पहले से बसा हुआ था https://github.com/hilbix/empty.git और अब कुछ और से फिर से आबादी की जाएगी, अर्थात् https://github.com/hilbix/src.git । यदि आप इसे https://github.com/hilbix/empty.git से पुन: आबाद करते हैं, तो आप इसे नहीं देख पाएंगे
अब क्या करे? खैर, जैसा बताया गया है वैसा ही करें! उपयोग--name someunusedname
git submodule add --name someunusedname https://github.com/hilbix/src.git two
.gitmodules
फिर जैसा दिखता है
[submodule "someunusedname"]
path = two
url = https://github.com/hilbix/src.git
ls -1p .git/modules/
देता है
someunusedname/
two/
इस तरह से भविष्य में आप शाखाओं को बदल सकते हैं / आगे और पीछे कर सकते हैं औरtwo/
दो अलग (और संभवतः असंगत) अपस्ट्रीम रिपॉजिटरी होने के कारण फिर से किसी भी परेशानी में नहीं पड़ेंगे। और सबसे अच्छा है: आप दोनों को स्थानीय रूप से कैश्ड भी रखते हैं।
- यह केवल आपके लिए सच नहीं है। यह आपके रिपॉजिटरी का उपयोग करके अन्य सभी के लिए भी सही है।
- और आप इतिहास नहीं खोते हैं। यदि आप पुराने सबमॉड्यूल के नवीनतम संस्करण को आगे बढ़ाना भूल गए हैं, तो आप स्थानीय कॉपी में प्रवेश कर सकते हैं और बाद में ऐसा कर सकते हैं। ध्यान दें कि यह काफी सामान्य है कि कोई व्यक्ति कुछ सबमॉड्यूल को धकेलना भूल जाता है (क्योंकि यह नए लोगों के लिए एक पीआईटीए है, जब तक कि वे आदी नहीं हो जाते
git
)।
हालाँकि यदि आपने कैश की गई निर्देशिका को हटा दिया है, तो दोनों अलग-अलग चेकआउट एक-दूसरे पर ठोकर खाएंगे, क्योंकि आप --name
विकल्पों का उपयोग नहीं करेंगे , है ना? इसलिए हर बार जब आप चेकआउट करते हैं तो आपको बार-बार .git/modules/<module>/
डायरेक्टरी को हटाना पड़ता है। यह बेहद बोझिल है और कुछ का उपयोग करना कठिन बनाता है git bisect
।
तो इस मॉड्यूल निर्देशिका को प्लेसहोल्डर के रूप में रखने के लिए एक बहुत ही तकनीकी कारण है। जो लोग नीचे कुछ निकालने की सलाह देते हैं वे .git/modules/
या तो बेहतर नहीं जानते हैं या आपको यह बताना भूल जाते हैं कि यह शक्तिशाली सुविधाओं को git bisect
लगभग असंभव बना देता है अगर यह इस तरह के एक उप-असंगतता को पार करता है।
एक और कारण ऊपर दिखाया गया है। को देखो ls
। आप वहां क्या देखते हैं?
ठीक है, मॉड्यूल two/
का दूसरा संस्करण नहीं है .git/modules/two/
, यह नीचे है .git/modules/someunusedname/
! तो ऐसी चीजें git rm $module; rm -f .git/module/$module
पूरी तरह से गलत हैं! हटाने के लिए आपको module/.git
या तो परामर्श करना होगा या .gitmodules
सही बात का पता लगाना होगा!
तो न केवल अन्य उत्तर इस खतरनाक जाल में आते हैं, यहां तक कि बहुत लोकप्रिय git
एक्सटेंशन में यह बग था ( यह अब वहां तय हो गया है )! तो बेहतर है कि .git/
निर्देशिका के अपने हाथ रखें यदि आप वास्तव में नहीं हैं, तो आप क्या कर रहे हैं!
और दार्शनिक दृष्टिकोण से, इतिहास को मिटा देना हमेशा गलत है!
हमेशा की तरह क्वांटम यांत्रिकी को छोड़कर , लेकिन यह कुछ पूरी तरह से अलग है।
FYI करें आप शायद यह अनुमान लगाते हैं : hilbix मेरा GitHub खाता है।
git rm modulename
औरrm -rf .git/modules/modulename