मैं एक गिट रिपॉजिटरी के भीतर मौजूदा गिट सबमॉड्यूल को कैसे स्थानांतरित करूं?


356

मैं अपने Git सुपरप्रोजेक्ट में Git सबमॉड्यूल का निर्देशिका नाम बदलना चाहूंगा।

मान लीजिए कि मेरी .gitmodulesफ़ाइल में निम्नलिखित प्रविष्टि है :

[submodule ".emacs.d/vimpulse"]  
path = .emacs.d/vimpulse  
url = git://gitorious.org/vimpulse/vimpulse.git

मुझे पहले हटाने के बिना .emacs.d/vimpulseनिर्देशिका को स्थानांतरित करने के लिए क्या करना है .emacs.d/vendor/vimpulse( यहां और यहां बताया गया है ) और फिर इसे फिर से जोड़ना।

क्या Git को वास्तव में सबमॉड्यूल टैग में पूरे पथ की आवश्यकता है

[submodule ".emacs.d/vimpulse"]

या क्या यह सबप्रोजेक्ट के नाम को स्टोर करना भी संभव है?

[submodule "vimpulse"]

ध्यान दें: ओपी अपने / अपने सवाल का जवाब git mvकमांड के साथ देता है, सवाल में ही सही।
डैन रोसेनस्टार्क

फिर भी, आप git mvइस तरह का उपयोग नहीं कर सकते । deinitतब rm निर्दिष्ट स्टैक्वेरोफ़्लो के रूप में उपयोग करें / a / 18892438/8047
दान रोसेनस्टार्क

14
@ यार: कम से कम git 2.0.0 पर, git mv बस सबमॉडल्स के लिए भी काम करता है , किसी और चीज की जरूरत नहीं।
पेड्रो रोमानो

9
Git 1.8.5मूविंग सबमॉड्यूल्स के साथ शुरुआत मूल रूप से git mvकमांड ( रिलीज नोट्स से , पहले @thisch खुद से जुड़ी) का उपयोग करके की जाती है। यहाँ
dennisschagt

git mvकार्यक्षेत्र में सबमॉड्यूल को स्थानांतरित करता है, और सबमॉड्यूल .it फ़ाइलों को सही ढंग से अपडेट करता है, लेकिन पेरेंट रेपो के .गित / मॉड्यूल फ़ोल्डर के भीतर सबफ़ोल्डर वही रहता है - क्या यह ठीक है? (मैं विंडोज पर git 2.19.0 का उपयोग कर रहा हूं)
yoyo

जवाबों:


377

नोट: जैसा कि टिप्पणियों में उल्लेख किया गया है यह उत्तर पुराने संस्करणों के साथ आवश्यक कदमों को संदर्भित करता है। Git के पास अब सबमोडुल्स को स्थानांतरित करने के लिए मूल समर्थन है:

1.8.5 git के बाद से, git mv old/submod new/submodउम्मीद के मुताबिक काम करता है और आपके लिए सभी प्लंबिंग करता है। आप git 1.9.3 या नए का उपयोग करना चाह सकते हैं, क्योंकि इसमें सबमॉड्यूल मूविंग के लिए फ़िक्सेस शामिल हैं।


यह प्रक्रिया समान है कि आप सबमॉडल कैसे निकालेंगे (देखें कि मैं सबमॉडल कैसे निकालूं? )

  1. .gitmodulesसबमॉड्यूल के पथ को उचित रूप से संपादित करें और बदलें, और इसे इंडेक्स में रखें git add .gitmodules
  2. यदि आवश्यक हो, तो सबमॉड्यूल ( mkdir -p new/parent) के नए स्थान की मूल निर्देशिका बनाएं ।
  3. सभी सामग्री को पुरानी से नई निर्देशिका में स्थानांतरित करें ( mv -vi old/parent/submodule new/parent/submodule)।
  4. सुनिश्चित करें कि गिट इस निर्देशिका को ट्रैक करता है ( git add new/parent)।
  5. के साथ पुरानी निर्देशिका निकालें git rm --cached old/parent/submodule
  6. .git/modules/old/parent/submoduleअपनी सभी सामग्री के साथ निर्देशिका को स्थानांतरित करें .git/modules/new/parent/submodule
  7. .git/modules/new/parent/configफ़ाइल को संपादित करें , सुनिश्चित करें कि वर्कट्री आइटम नए स्थानों पर इंगित करता है, इसलिए इस उदाहरण में यह होना चाहिए worktree = ../../../../../new/parent/module। आमतौर पर ..उस जगह पर सीधे रास्ते में निर्देशिका से दो अधिक होना चाहिए ।
  8. फ़ाइल को संपादित करें new/parent/module/.git, सुनिश्चित करें कि इसमें पथ मुख्य प्रोजेक्ट .gitफ़ोल्डर के अंदर सही नए स्थान को इंगित करता है , इसलिए इस उदाहरण में gitdir: ../../../.git/modules/new/parent/submodule

    git status आउटपुट मेरे लिए इस तरह दिखता है:

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   .gitmodules
    #       renamed:    old/parent/submodule -> new/parent/submodule
    #
    
  9. अंत में, बदलाव करें।


37
जब आप अपडेट करते हैं .itmodules सुनिश्चित करते हैं कि आप उस pathकॉन्फ़िगरेशन और सबमॉड्यूल के नाम दोनों को अपडेट करते हैं । उदाहरण के लिए, बार foo / मॉड्यूल बढ़ने में / मॉड्यूल आप .gitmodules में अनुभाग में परिवर्तन करना होगा [submodule "foo/module"]करने के लिए [submodule "bar/module"], और है कि एक ही धारा के तहत path = foo/moduleकरने के लिए path = bar/module। इसके अलावा, आप .git / config अनुभाग में परिवर्तन करना होगा [submodule "foo/module"]करने के लिए [submodule "bar/module"]
विल्हेमटेल

3
यह मेरे लिए या तो काम नहीं करता था ... मैंने जो निकटतम समाधान पाया है वह एक सबमॉड्यूल (एक दर्द) को हटा रहा है और फिर इसे अलग स्थान पर फिर से जोड़ रहा है।
पाब्लो ओल्मोस डी एगुइलेरा सी।

33
एक बहुत-बहुत महत्वपूर्ण नोट: यदि आपको fatal: 'git status --porcelain' failed in...सबमॉड्यूल में किसी भी .ITI फ़ाइल या निर्देशिका को हटाना है।
मारक

19
ऐसा लगता है कि इस पोस्ट की तरह इस तरह के संपादन के रूप में कुछ ही कदम, याद करते हैं .git/modules/old/parent/submodule, नए स्थान पर जाने की, अद्यतन करने gitdirमें old/parent/submodule/.git...
SZX

38
1.8.5 git के बाद से, git mv old/submod new/submodउम्मीद के मुताबिक काम करता है और आपके लिए सभी प्लंबिंग करता है। आप शायद git 1.9.3+ का उपयोग करना चाहते हैं क्योंकि इसमें सबमॉड्यूल मूविंग के लिए फ़िक्सेस शामिल हैं।
वल्लिक

232

वल्लोरिक की टिप्पणी से ऊपर लिया गया सबसे आधुनिक उत्तर:

  1. Git 1.9.3 पर अपग्रेड करें (या यदि सबमॉडल में नेस्टेड सबमॉड्यूल्स हों तो 2.18 )
  2. git mv old/submod new/submod
  3. बाद में .gitmodules और सबमॉड्यूल निर्देशिका पहले से ही एक प्रतिबद्ध के लिए मंचन की जाती है (आप इसे इसके साथ सत्यापित कर सकते हैं git status।)
  4. बदलाव के साथ git commitऔर आप जाने के लिए अच्छे हैं!

किया हुआ!


3
यह वास्तव में स्थानांतरित सबमॉडल के अंदर एक सबमॉड्यूल 1.9.3 को छोड़कर काम करता है । इसके लिए कुछ मैनुअल क्लीनअप की जरूरत थी।
पास्कल

3
यह पहले से ही जारी नोट्स1.8.5 में वर्णित संस्करण में काम करना चाहिए ।
17

6
इस उत्तर को 1000 अपवोट मिलना चाहिए, मैंने लगभग अपने रेपो के साथ ऊपर वर्णित चरणों को करते हुए एक गड़बड़ कर दी, वास्तव में स्टैकऑवरफ्लो को इस स्थिति के लिए एक यूसेज़ होना चाहिए।
एमजीपी

5
वाह, यह एक आकर्षण (git 1.9.5) की तरह काम करता है, काश यह चयनित उत्तर होता।
एलेक्स इलियाव

7
एक बात यह नहीं है कि यह सबमॉडल के लिए प्रारंभिक लेबल को नहीं बदलता है। यदि आप .gitmodulesफ़ाइल की जाँच करते हैं, तो old/submodअभी भी सबमॉड्यूल के लिए लेबल के रूप में उपयोग किया जाता है जबकि पथ को बदल दिया गया है। लेबल को भी बदलने के लिए, ऐसा लगता है कि आपको वास्तव में मॉड्यूल निर्देशिका पथ को अंदर ले जाने की आवश्यकता है .git, और फिर मैन्युअल रूप से लेबल को बदलें .gitmodules
CMCDragonkai

55

मेरे मामले में, मैं एक निर्देशिका से एक उपनिर्देशिका को एक उपनिर्देशिका में स्थानांतरित करना चाहता था, जैसे "AFNetworking" -> "ext / AFNetworking"। ये चरण हैं जिनका मैंने अनुसरण किया है:

  1. संपादित करें। सबटूड्यूल नाम और पथ को बदलने के लिए "ext / AFNetworking"
  2. सबमॉड्यूल की गिट निर्देशिका को ".गित / मॉड्यूल / एएफएन नेटवर्किंग" से ".गित / मॉड्यूल / एक्सट / एएफएन नेटवर्किंग" पर ले जाएं।
  3. लाइब्रेरी को "AFNetworking" से "ext / AFNetworking" में ले जाएं
  4. ".Git / मॉड्यूल / ext / AFNetworking / config" संपादित करें और [core] worktreeलाइन को ठीक करें । मेरा से बदल ../../../AFNetworkingगया../../../../ext/AFNetworking
  5. "Ext / AFNetworking / .git" संपादित करें और ठीक करें gitdir। मेरा से बदल ../.git/modules/AFNetworkingगया../../git/modules/ext/AFNetworking
  6. git add .gitmodules
  7. git rm --cached AFNetworking
  8. git submodule add -f <url> ext/AFNetworking

अंत में, मैंने git स्टेटस में देखा:

matt$ git status
# On branch ios-master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    AFNetworking -> ext/AFNetworking

वेटिला। उपरोक्त उदाहरण निर्देशिका की गहराई को नहीं बदलता है, जो कार्य की जटिलता के लिए एक बड़ा अंतर बनाता है, और सबमॉड्यूल का नाम नहीं बदलता है (जो वास्तव में आवश्यक नहीं हो सकता है, लेकिन मैंने इसे संगत किया है अगर मैं उस रास्ते पर एक नया मॉड्यूल जोड़ देता तो ऐसा होता।)


4
धन्यवाद मैट। मैं स्वीकृत उत्तर पर खो गया था। आधार मामले से अधिक कवर करने के लिए धन्यवाद। इसने एकदम जादू की तरह काम किया।
एंड्रयू हबब्स

आपको .गित / मॉड्यूल पथों के आसपास फेरबदल करने की आवश्यकता नहीं है, या सबमोडुले का नाम बदल दें (जैसा कि मेहराब और बॉब बेल उल्लेख)। हालांकि, ऐसा करने से चीजें साफ हो सकती हैं।
गतोतिग्रादो २५'१३

किसी भी उप-सबमॉड्यूल के लिए चरण 2, 3, 4 और 5 पुनरावृत्ति करना न भूलें।
हर्जब्यूब

22

[अपडेट: २०१४-११-२६] जैसा कि यार कुछ भी करने से पहले अच्छी तरह से नीचे संक्षेप में बताते हैं , सुनिश्चित करें कि आप सबमॉड्यूल के URL को जानते हैं। यदि अज्ञात है, .git/.gitmodulesतो कुंजी को खोलें और जांचें submodule.<name>.url

क्या मेरे लिए काम किया था वर्ष submodule हटाने का उपयोग कर git submodule deinit <submodule>के बाद git rm <submodule-folder>। फिर नए फ़ोल्डर नाम और प्रतिबद्ध के साथ फिर से सबमॉड्यूल जोड़ें। कमिट करने से पहले git स्टेटस को चेक करना पुराने सबमॉड्यूल को नए नाम और .gitmodule में बदला हुआ दिखाता है।

$ git submodule deinit foo
$ git rm foo
$ git submodule add https://bar.com/foo.git new-foo
$ git status
renamed:    foo -> new-foo
modified:   .gitmodules
$ git commit -am "rename foo submodule to new-foo"

1
इसके लिए git 1.8.3 या उच्चतर की आवश्यकता होती है। अपना पोस्ट अपग्रेड करने के लिए यह पोस्ट देखें: evgeny-goldin.com/blog/3-ways-install-git-linux-ubuntu
माइकल कोल

1
या, एक बेहतर तरीका: sudo add-apt-repository ppa: git-core / ppa sudo apt-get update sudo apt-get install git
माइकल कोल

@MichaelCole धन्यवाद! आप सही हैं! Git-1.8.3 रिलीज नोट्स देखें । जानकारी के लिए: उबंटू-13.10 (सजीव समन्दर) Git-1.8.3.2 है , लेकिन अच्छा पता करने के लिए नहीं है पीपीए । इसके अलावा, IMHO गिट सबट्री मर्ज रणनीति एक बेहतर तरीका है; मैंने अपनी खुद की परियोजनाओं के लिए सबमॉडल्स को छोड़ दिया है। अभी भी मौजूदा परियोजनाओं के लिए समझने के लिए अच्छा है।
मार्क मिकोफ़्स्की

मैंने कई उपाय आजमाए लेकिन आपका सबसे अच्छा है। केवल कमांड लाइन का उपयोग करें ताकि आपको किसी भी git फ़ाइल को संशोधित करने की आवश्यकता न हो (और नहीं होनी चाहिए)। धन्यवाद!
नाहंग89

12

चाल समझ रही है कि .gitसबमॉडल्स के लिए निर्देशिका अब मास्टर रिपॉजिटरी में रखी गई है, के तहत .git/modules, और प्रत्येक सबमॉड्यूल में एक .gitफ़ाइल है जो इसे इंगित करती है। यह वह प्रक्रिया है जिसकी आपको अब आवश्यकता है:

  • सबमॉड्यूल को उसके नए घर में स्थानांतरित करें।
  • .gitफ़ाइल को सबमॉड्यूल की वर्किंग डायरेक्टरी में एडिट करें , और उसमें जो भी रास्ता हो उसे संशोधित करें ताकि यह मास्टर रिपॉजिटरी की .git/modulesडायरेक्टरी में राइट डाइरेक्टरी की ओर इशारा करे ।
  • मास्टर रिपॉजिटरी की .git/modulesनिर्देशिका दर्ज करें , और अपने सबमॉड्यूल के अनुरूप निर्देशिका खोजें।
  • configफ़ाइल को संपादित करें , worktreeपथ को अपडेट करना ताकि यह सबमॉड्यूल की कार्यशील निर्देशिका के नए स्थान को इंगित करे।
  • .gitmodulesमास्टर रिपॉजिटरी के रूट में फाइल को एडिट करें, सबमॉड्यूल की वर्किंग डायरेक्टरी के लिए रास्ता अपडेट करें।
  • git add -u
  • git add <parent-of-new-submodule-directory>(यह महत्वपूर्ण है कि आप माता-पिता को जोड़ते हैं , न कि उप-निर्देशिका निर्देशिका को।)

कुछ नोट:

  • [submodule "submodule-name"]में लाइनों .gitmodulesऔर .git/configएक दूसरे को मेल खाना चाहिए, लेकिन कुछ और के अनुरूप नहीं है।
  • सबमॉड्यूल वर्किंग डायरेक्टरी और .gitडायरेक्टरी को एक दूसरे की ओर सही ढंग से इशारा करना चाहिए।
  • .gitmodulesऔर .git/configफ़ाइलें सिंक्रनाइज़ किया जाना चाहिए।

9

"[सबमॉड्यूल" के बाद उद्धरण में स्ट्रिंग कोई फर्क नहीं पड़ता। आप चाहें तो इसे "फोब्बर" में बदल सकते हैं। इसका उपयोग ".it / config" में मिलान प्रविष्टि को खोजने के लिए किया जाता है।

इसलिए, यदि आप "गिट सबमॉड्यूल इनिट" चलाने से पहले बदलाव करते हैं, तो यह ठीक काम करेगा। यदि आप परिवर्तन करते हैं (या मर्ज के माध्यम से परिवर्तन उठाते हैं), तो आपको या तो मैन्युअल रूप से संपादित करना होगा। .it / config या फिर "git सबमॉड्यूल इनिट" को फिर से चलाना होगा। यदि आप बाद में करते हैं, तो आप पुराने नाम .it / config में हानिरहित "फंसे हुए" प्रविष्टि के साथ रह जाएंगे।


यह वास्तव में कष्टप्रद है, लेकिन आप सही हैं। सबसे खराब हिस्सा यह है, यदि आप केवल URL बदलते हैं, तो git init को चलाने से यह अपडेट नहीं होता है, आपको इसे .it / config को संपादित करना होगा।
crimson_penguin

1
इस मामले git submodule syncमें परिवर्तन को .git/configस्वचालित रूप से प्रचारित करता है
चार्ल्स बीआर

9

आप बस एक नया सबमॉड्यूल जोड़ सकते हैं और मानक कमांड्स का उपयोग करके पुराने सबमॉड्यूल को हटा सकते हैं। (.गित के अंदर किसी भी आकस्मिक त्रुटि को रोकना चाहिए)

उदाहरण सेटअप:

mkdir foo; cd foo; git init; 
echo "readme" > README.md; git add README.md; git commit -m "First"
## add submodule
git submodule add git://github.com/jquery/jquery.git
git commit -m "Added jquery"
## </setup example>

एग्जाम मूव 'jquery' को 'seller / jquery / jquery':

oldPath="jquery"
newPath="vendor/jquery/jquery"
orginUrl=`git config --local --get submodule.${oldPath}.url`

## add new submodule
mkdir -p `dirname "${newPath}"`
git submodule add -- "${orginUrl}" "${newPath}"

## remove old submodule
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}"              ## remove old src
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (housekeeping)

## commit
git add .gitmodules
git commit -m "Renamed ${oldPath} to ${newPath}"

बड़े सबमॉड्यूल के लिए बोनस विधि:

यदि सबमॉड्यूल बड़ा है और आप क्लोन के लिए इंतजार नहीं करना पसंद करते हैं, तो आप पुराने के मूल के रूप में उपयोग करके नया सबमॉड्यूल बना सकते हैं, और फिर मूल स्विच कर सकते हैं।

उदाहरण (समान उदाहरण सेटअप का उपयोग करें)

oldPath="jquery"
newPath="vendor/jquery/jquery"
baseDir=`pwd`
orginUrl=`git config --local --get submodule.${oldPath}.url`

# add new submodule using old submodule as origin
mkdir -p `dirname "${newPath}"`
git submodule add -- "file://${baseDir}/${oldPath}" "${newPath}"

## change origin back to original
git config -f .gitmodules submodule."${newPath}".url "${orginUrl}"
git submodule sync -- "${newPath}"

## remove old submodule
...

यदि आप सिर का उपयोग नहीं कर रहे हैं, तो आपको मॉड्यूल के सही संस्करण को देखने की आवश्यकता हो सकती है newPath
पौलमेलनिकोव

2

दिए गए समाधान ने मेरे लिए काम नहीं किया, हालांकि एक समान संस्करण किया ...

यह एक क्लोन रिपोजिटरी के साथ है, इसलिए सबमॉड्यूल गिट रिपोज शीर्ष रिपॉजिटरी में शामिल हैं। सभी भंडार शीर्ष भंडार से हैं:

  1. .Itmodules संपादित करें और प्रश्न में सबमॉड्यूल के लिए "पथ =" सेटिंग बदलें। (लेबल बदलने की आवश्यकता नहीं है, न ही इस फ़ाइल को अनुक्रमणिका में जोड़ने के लिए।)

  2. संपादित करें .IT / मॉड्यूल / नाम / कॉन्फिग और प्रश्न में सबमॉड्यूल के लिए "वर्कट्री =" सेटिंग बदलें

  3. Daud:

    mv submodule newpath/submodule
    git add -u
    git add newpath/submodule
    

मुझे आश्चर्य है कि अगर यह फर्क पड़ता है अगर रिपॉजिटरी परमाणु, या रिश्तेदार सबमॉड्यूल्स हैं, तो मेरे मामले में यह सापेक्ष था (सबमॉड्यूल /। यह topproject / .गित / मॉड्यूल / सबमॉड्यूल के लिए एक रेफरी है)


2

बस शेल स्क्रिप्ट git-submodule-Move का उपयोग करें ।


हे, मैंने इस प्रश्न को फिर से देखा, और एक उच्च मतदान जवाब का उपयोग किया, और अब मैं चाहता हूं कि मैं नीचे स्क्रॉल करूं और अपने पिछले उत्तर को देखूं जिसके बारे में मैं भूल गया था।
फ्लिम

2

मैं कल ही इस अध्यादेश से गुज़रा और इस जवाब ने पूरी तरह से काम किया। यहाँ स्पष्टता के लिए मेरे कदम हैं:

  1. सुनिश्चित करें कि सबमॉड्यूल को अपने सर्वर में जांचा और धकेला गया है। आपको यह भी जानना होगा कि इसकी शाखा कौन सी है।
  2. आपको अपने सबमॉड्यूल का URL चाहिए! उपयोग करें more .gitmodulesक्योंकि एक बार जब आप सबमॉडल को हटा देते हैं तो यह आसपास नहीं होगा
  3. अब आप उपयोग कर सकते हैं deinit, rmऔर फिरsubmodule add

उदाहरण

कमानों

    git submodule deinit Classes/lib/mustIReally
    git rm foo
    git submodule add http://developer.audiob.us/download/SDK.git lib/AudioBus

    # do your normal commit and push
    git commit -a 

नोट: git mv ऐसा नहीं करता है। बिल्कुल भी।


3
अच्छा सारांश। git mvहालांकि Git के अंतिम संस्करणों में +1 बेहतर होना चाहिए।
वॉनक

@VonC मैंने git 1.8.5 पर परीक्षण किया, बहुत यकीन है कि इसके बारे में जितना अच्छा हो उतना अच्छा है mv। धन्यवाद!
दान रोसेनस्टार्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.