एक फ़ोल्डर से एक सबमॉड्यूल रिपॉजिटरी बनाएं और इसकी गिट कमिट हिस्ट्री रखें


111

मेरे पास एक वेब एप्लिकेशन है जो एक विशेष तरीके से अन्य वेब एप्लिकेशन की खोज करता है। इसमें एक demosफ़ोल्डर में कुछ वेब डेमो होते हैं और डेमो में से एक में अब यह स्वयं का भंडार होना चाहिए। मैं इस डेमो एप्लिकेशन के लिए एक अलग रिपॉजिटरी बनाना और इसे बनाना चाहूंगासबपैकेज अपने प्रतिबद्ध इतिहास को खोए बिना मुख्य भंडार से सबमॉड्यूल

क्या रिपॉजिटरी के फोल्डर में फाइलों से कमिटेड हिस्ट्री रखना और उसमें से रिपॉजिटरी बनाना और उसकी जगह सबमॉडल के रूप में इस्तेमाल करना संभव है ?


मैं खोज रहा हूं कि लेख के लिंक के लिए Git रिपॉजिटरी A से Git रिपॉजिटरी B. +1 तक निर्देशिका को कैसे स्थानांतरित किया जाए।
चेतबाहन

1
डुप्लिकेट? stackoverflow.com/questions/12514197/…
n

हाँ, यह वास्तव में बहुत समान है, समाधान थोड़ा अलग है, इसे साझा करने के लिए धन्यवाद
GabLeRoux

जवाबों:


191

विस्तृत समाधान

इस उत्तर के अंत में नोट देखें (अंतिम पैराग्राफ) एनपीएम का उपयोग करके गिट सबमॉडल्स के त्वरित विकल्प के लिए;)

निम्नलिखित उत्तर में, आप जानेंगे कि रिपॉजिटरी से फोल्डर कैसे निकाला जाता है और उससे एक git रिपॉजिटरी बनाते हैं और फिर इसे फोल्डर के बजाय सबमॉड्यूल के रूप में शामिल करते हैं ।

Gerg Bayer के लेख से प्रेरित होकर एक Git रिपॉजिटरी से दूसरे में फाइल को मूविंग हिस्ट्री, प्रिजर्विंग हिस्ट्री

शुरुआत में, हमारे पास कुछ इस तरह है:

<git repository A>
    someFolders
    someFiles
    someLib <-- we want this to be a new repo and a git submodule!
        some files

में दिए चरणों bellow, मैं इस संदर्भित करेंगे someLibके रूप में <directory 1>

अंत में, हमारे पास कुछ इस तरह होगा:

<git repository A>
    someFolders
    someFiles
    @submodule --> <git repository B>

<git repository B>
    someFolders
    someFiles

एक अन्य रिपॉजिटरी में एक फ़ोल्डर से एक नया गिट रिपॉजिटरी बनाएँ

चरण 1

विभाजित करने के लिए भंडार की एक नई प्रति प्राप्त करें।

git clone <git repository A url>
cd <git repository A directory>

चरण 2

वर्तमान फ़ोल्डर नया रिपॉजिटरी होगा ताकि वर्तमान रिमोट को हटा दें।

git remote rm origin

चरण 3

वांछित फ़ोल्डर का इतिहास निकालें और इसे प्रतिबद्ध करें

git filter-branch --subdirectory-filter <directory 1> -- --all

अब आपके पास directory 1सभी संबंधित प्रतिबद्ध इतिहास के साथ अपने रेपो रूट की फाइलों से एक गिट रिपॉजिटरी होनी चाहिए ।

चरण 4

अपनी ऑनलाइन रिपॉजिटरी बनाएं और अपनी नई रिपॉजिटरी को आगे बढ़ाएं!

git remote add origin <git repository B url>
git push

आपको upstreamअपने पहले पुश के लिए शाखा निर्धारित करने की आवश्यकता हो सकती है

git push --set-upstream origin master

स्वच्छ <git repository A>(वैकल्पिक, टिप्पणियां देखें)

हम के निशान (फ़ाइलें और इतिहास के लिए प्रतिबद्ध) को हटाना चाहते <git repository B>से <git repository A>तो इस फ़ोल्डर के लिए इतिहास केवल एक बार होता है।

यह जीथब से संवेदनशील डेटा को हटाने पर आधारित है ।

एक नए फ़ोल्डर में जाएं और

git clone <git repository A url>
cd <git repository A directory>
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <directory 1> -r' --prune-empty --tag-name-filter cat -- --all

<directory 1>उस फ़ोल्डर से बदलें जिसे आप निकालना चाहते हैं। -rयह निर्दिष्ट निर्देशिका के अंदर पुनरावृत्ति करेगा :)। अब के origin/masterसाथ धक्का--force

git push origin master --force

बॉस स्टेज (नीचे नोट देखें)

में से एक सबमॉड्यूल बनाएं<git repository B><git repository A>

git submodule add <git repository B url>
git submodule update
git commit

सत्यापित करें कि क्या सब कुछ उम्मीद के मुताबिक काम किया और push

git push origin master

ध्यान दें

यह सब करने के बाद, मैंने अपने मामले में महसूस किया कि इसके बजाय अपनी निर्भरता को प्रबंधित करने के लिए npm का उपयोग करना अधिक उचित था । हम git url और संस्करण निर्दिष्ट कर सकते हैं, निर्भरता के रूप में package.json git urls देखें ।

यदि आप इसे इस तरह से करते हैं, तो जिस रिपॉजिटरी को आप आवश्यकता के रूप में उपयोग करना चाहते हैं वह एक npm मॉड्यूल होना चाहिए ताकि इसमें एक package.jsonफ़ाइल होनी चाहिए या आपको यह त्रुटि मिलेगी Error: ENOENT, open 'tmp.tgz-unpack/package.json':।

tldr (वैकल्पिक समाधान)

आपको एनपीएम का उपयोग करना आसान होगा और गिट के साथ निर्भरता को प्रबंधित करना होगा :

  • फ़ोल्डर को नए रिपॉजिटरी में ले जाएं
  • npm initदोनों रिपॉजिटरी के अंदर चलाते हैं
  • npm install --save git://github.com/user/project.git#commit-ishजहाँ आप अपनी निर्भरताएँ स्थापित करना चाहते हैं उसे चलाएं

39
चरण "क्लीन <git रिपॉजिटरी ए>" से बचा जाना चाहिए। ऐसा करने से आप अपने इतिहास से पुराने संस्करणों / कमिट्स को पूरी तरह से पुनर्स्थापित / चेकआउट नहीं कर सकते हैं। आपको बस rm फ़ोल्डर को git करना चाहिए और सबमॉड्यूल जोड़ना चाहिए। इसलिए आप पुराने कमिट्स की जांच करते समय पूरी तरह से काम करना सुनिश्चित करते हैं।
साइबोट

क्या आपको cd someLibचरण 2 से पहले नहीं करना चाहिए ? आप कहते हैं "वर्तमान फ़ोल्डर नया भंडार होगा" लेकिन वास्तव में यह नहीं होगा; नया रिपॉजिटरी (सबमॉड्यूल) उस फोल्डर के अंदर है।
जागो

1
पुष्टि: हाँ, यह एक से अधिक सबमॉड्यूल के लिए काम करता है। विस्तृत उत्तर के लिए बहुत बहुत धन्यवाद। इसके अलावा, npm का उपयोग करने के लिए नहीं है।
ब्रेनो इनोजोसा

2
मैं इसके बारे में जानकारी जोड़ूंगा, refs/original/...जो चरण 3 में बनाई गई है
एमिल बर्जरॉन

6
GitHub ने एक फ़ोल्डर का निष्कर्षण एक नए भंडार में कैसे प्राप्त किया जाए इस पर एक लेख बनाया: help.github.com/articles/…
jrobichaud

9

@GabLeRoux द्वारा समाधान शाखाओं को तोड़ता है, और संबंधित कमिट करता है।

क्लोन करने और उन सभी अतिरिक्त शाखाओं को रखने का एक सरल तरीका:

1 - सुनिश्चित करें कि आपके पास यह git उपनाम है

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

2 - रिमोट को क्लोन करें, सभी शाखाओं को खींचें, रिमोट को बदलें, अपनी निर्देशिका को फ़िल्टर करें, पुश करें

git clone git@github.com:user/existing-repo.git new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin git@github.com:user/new-repo.git
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags

3

GabLeRoux का समाधान अच्छी तरह से काम करता है, सिवाय इसके कि आप उपयोग करते हैं git lfsऔर उस निर्देशिका के तहत बड़ी फाइलें हैं जिन्हें आप अलग करना चाहते हैं। उस स्थिति में, चरण 3 के बाद सभी बड़ी फाइलें वास्तविक फाइलों के बजाय सूचक फाइलें बनी रहेंगी। मुझे लगता है कि यह शायद .gitattributesफ़िल्टर शाखा प्रक्रिया में फ़ाइल को हटाने के कारण है ।

यह महसूस करते हुए, मुझे लगता है कि मेरे लिए निम्नलिखित समाधान काम करता है:

cp .gitattributes .git/info/attributes

हटाए जाने से बचने के .gitattributesलिए बड़ी फ़ाइलों को ट्रैक करने के लिए कौन सी git lfs का उपयोग करता है नकल करना .git/

जब फ़िल्टर-ब्रांच किया जाता है, .gitattributesतो यदि आप अभी भी नई रिपॉजिटरी के लिए git lfs का उपयोग करना चाहते हैं , तो उसे वापस रखना न भूलें :

mv .git/info/attributes .gitattributes
git add .gitattributes
git commit -m 'added back .gitattributes'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.