मौजूदा गिट रिपॉजिटरी को दूसरे में कैसे आयात करें?


476

मेरे पास XXX नामक फ़ोल्डर में Git रिपॉजिटरी है , और मेरे पास YYY नामक दूसरा Git रिपॉजिटरी है ।

मैं XXX रिपॉजिटरी को YYY रिपॉजिटरी में ZZZ नाम के एक उपनिर्देशिका के रूप में आयात करना चाहता हूं और सभी XXX के इतिहास को YYY में जोड़ना चाहता हूं ।

इससे पहले फ़ोल्डर संरचना:

├── XXX
│   ├── .git
│   └── (project files)
└── YYY
    ├── .git
    └── (project files)

फ़ोल्डर संरचना के बाद:

YYY
├── .git  <-- This now contains the change history from XXX
├──  ZZZ  <-- This was originally XXX
│    └── (project files)
└──  (project files)

क्या यह किया जा सकता है, या मुझे उप-मॉड्यूल का उपयोग करना चाहिए?


2
जब आप एक नया रेपो बनाते हैं, तो Github पर वेब इंटरफेस से ऐसा करना संभव है
bgcode

जवाबों:


429

संभवतः YYY में XXX सामान को एक शाखा में खींचने का सबसे सरल तरीका होगा और फिर इसे मास्टर में विलय कर दिया जाएगा:

में YYY :

git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master
mkdir ZZZ
git mv stuff ZZZ/stuff                      # repeat as necessary for each file/dir
git commit -m "Moved stuff to ZZZ"
git checkout master                
git merge ZZZ --allow-unrelated-histories   # should add ZZZ/ to master
git commit
git remote rm other
git branch -d ZZZ                           # to get rid of the extra branch before pushing
git push                                    # if you have a remote, that is

मैंने वास्तव में अपने रिपॉज के एक जोड़े के साथ यह कोशिश की थी और यह काम करता है। जार्ग के जवाब के विपरीत यह आपको अन्य रेपो का उपयोग जारी नहीं रखने देगा, लेकिन मुझे नहीं लगता कि आपने इसे वैसे भी निर्दिष्ट किया है।

नोट: चूंकि यह मूल रूप से 2009 में लिखा गया था, git ने नीचे दिए गए उत्तर में उल्लिखित सबरी मर्ज जोड़ा है। मैं शायद आज उस विधि का उपयोग करूंगा, हालांकि यह विधि अभी भी काम करती है।


1
धन्यवाद। मैंने आपकी तकनीक का थोड़ा संशोधित संस्करण इस्तेमाल किया: मैंने XXX पर एक 'स्टेजिंग' शाखा बनाई जहाँ मैंने ZZZ फ़ोल्डर बनाया, और उसमें 'सामान' को स्थानांतरित किया। फिर मैंने XXX को YYY में मिला दिया।
विजय पटेल

1
यह मेरे लिए बहुत अच्छा काम किया। केवल जो बदलाव मैंने किए वे थे: 1) "git Branch -d ZZZ" पुश से पहले क्योंकि मैं नहीं चाहता था कि यह अस्थायी शाखा चारों ओर लटके। 2) "गिट पुश" मुझे त्रुटि दे रहा था: "सामान्य में कोई रेफरी और कोई निर्दिष्ट नहीं; कुछ भी नहीं कर रहा है। शायद आपको 'मास्टर' जैसी शाखा निर्दिष्ट करनी चाहिए।" (जिस मूल को मैं आगे बढ़ा रहा था, वह एक खाली नंगे भंडार था।) लेकिन "गिट पुश - ऑल" एक विजेता की तरह काम करता था।
क्रेजीप्रो

1
मैं YYY रेपो में केवल ZZZ फ़ोल्डर प्लस इतिहास के साथ समाप्त करना चाहता था: मैं मूल XXX रेपो, और YYY रेपो में ZZZ शाखा को हटाना चाहता था। मैंने पाया कि ZZZ शाखा को हटाने के रूप में @CrazyPyro ने इतिहास को हटाने का सुझाव दिया - इसे रखने के लिए मैंने हटाने से पहले ZZZ शाखा को मास्टर में विलय कर दिया।
ओली स्टडहोलमे

4
@ सेबैस्टियनब्लैक मैंने सिर्फ अपने दो रिपोज के साथ इसके साथ खिलवाड़ किया, और महसूस किया कि एक ऐसा लापता कदम है जिस पर किसी ने कभी गौर नहीं किया, बावजूद इसके कि मैं वर्षों से इस पर उठ रहा हूं। :-) मैंने इसे मास्टर में विलय करने का उल्लेख किया है , लेकिन वास्तव में इसे नहीं दिखाया। अब इसे संपादित कर रहे हैं ...
ebneter

2
जब आप अपने सबफ़ोल्डर में फ़ाइलों को ले जा रहे हों, तो आप कुछ ऐसा जोड़ सकते हैं: git mv $(ls|grep -v <your foldername>) <your foldername>/ यह सभी फ़ाइलों और फ़ोल्डरों को आपके नए फ़ोल्डर में कॉपी कर देगा
Serup

366

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

git remote add XXX_remote <path-or-url-to-XXX-repo>
git fetch XXX_remote
git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master
git read-tree --prefix=ZZZ/ -u XXX_remote/master
git commit -m "Imported XXX as a subtree."

आप अपस्ट्रीम परिवर्तनों को ट्रैक कर सकते हैं जैसे:

git pull -s subtree XXX_remote master

अपने आप ही यह पता लगा लें कि जड़ें मर्ज करने से पहले हैं, इसलिए आपको बाद के मर्ज पर उपसर्ग निर्दिष्ट करने की आवश्यकता नहीं है।

नकारात्मक पक्ष यह है कि मर्ज किए गए इतिहास में फ़ाइलों को बिना उपसर्ग वाले हैं (एक उपनिर्देशिका में नहीं) है। परिणामस्वरूप git log ZZZ/aआपको मर्ज किए गए इतिहास को छोड़कर सभी परिवर्तन (यदि कोई हो) दिखाएंगे। तुम कर सकते हो:

git log --follow -- a

लेकिन यह मर्ज किए गए इतिहास में अन्य परिवर्तनों को नहीं दिखाएगा।

दूसरे शब्दों में, यदि आप ZZZरिपॉजिटरी की फाइलों को नहीं बदलते हैं XXX, तो आपको निर्दिष्ट --followऔर एक उपसर्ग पथ की आवश्यकता है। यदि आप उन्हें दोनों रिपॉजिटरी में बदलते हैं, तो आपके पास 2 कमांड हैं, जिनमें से कोई भी सभी बदलाव नहीं दिखाता है।

2.9 से पहले के संस्करणों को प्राप्त करें : आपको --allow-unrelated-historiesविकल्प को पास करने की आवश्यकता नहीं है git merge

अन्य उत्तर में विधि read-treeजो merge -s oursचरण का उपयोग करती है और छोड़ती है, वह प्रभावी रूप से cp के साथ फ़ाइलों की प्रतिलिपि बनाने और परिणाम करने से अलग नहीं है।

मूल स्रोत जीथब के "सबट्री मर्ज" सहायता लेख से था । और एक और उपयोगी लिंक


9
ऐसा लगता है कि इतिहास को संरक्षित नहीं किया गया है ... अगर मैं अपने द्वारा git logखींची गई किसी भी फाइल पर करता हूं तो मैं केवल एक मर्ज कमिट देखता हूं और अन्य रेपो में इसके पिछले जीवन से कुछ भी नहीं है? Git 1.8.0
एंथ्रोपिक

8
अहा! अगर मैं आयातित फ़ाइल के पुराने पथ का उपयोग करता हूँ, अर्थात इसे उप में आयात किया गया उपखंड छोड़ दें, तो git लॉग मुझे प्रतिबद्ध इतिहास देगा, उदाहरण git log -- myfileके लिएgit log -- rack/myfile
Anentropic

2
@FrancescoFrassinelli, कि वांछनीय नहीं है? इतिहास को लाना इस पद्धति की एक विशेषता है।
patrickvacek

4
@FrancescoFrassinelli, यदि आप इतिहास नहीं चाहते हैं, तो बस एक नियमित प्रतिलिपि क्यों नहीं? मैं यह पता लगाने की कोशिश कर रहा हूं कि अगर इतिहास के लिए नहीं तो मैं आपको इस तरीके से क्या आकर्षित करूंगा - यही एकमात्र कारण है कि मैंने इस पद्धति का उपयोग किया है!
patrickvacek

7
Git 2.9 के बाद से, आपको --allow-unrelated-historiesमर्ज करते समय विकल्प की आवश्यकता होती है ।
स्टुक्सनेट

112

git-subtreeइतिहास को संरक्षित करते हुए (और / या उपप्रकारों के इतिहास को विभाजित करते हुए, कई रिपोजिटरी को एक में विलय करने के इस उपयोग के मामले के लिए डिज़ाइन की गई एक स्क्रिप्ट है, हालांकि यह इस सवाल के लिए अप्रासंगिक लगता है)। यह 1.7.11 रिलीज के बाद से गिट पेड़ के हिस्से के रूप में वितरित किया जाता है ।

उपनिर्देशिका के रूप <repo>में संशोधन पर एक भंडार में विलय करने के लिए , निम्नानुसार उपयोग करें :<rev><prefix>git subtree add

git subtree add -P <prefix> <repo> <rev>

git-subtree एक अधिक उपयोगकर्ता के अनुकूल तरीके से उप-मर्ज रणनीति को लागू करता है।

आपके मामले के लिए, रिपॉजिटरी YYY के अंदर, आप दौड़ेंगे:

git subtree add -P ZZZ /path/to/XXX.git master

नकारात्मक पक्ष यह है कि मर्ज किए गए इतिहास में फ़ाइलों को बिना उपसर्ग वाले हैं (एक उपनिर्देशिका में नहीं) है। परिणामस्वरूप git log ZZZ/aआपको मर्ज किए गए इतिहास को छोड़कर सभी परिवर्तन (यदि कोई हो) दिखाएंगे। तुम कर सकते हो:

git log --follow -- a

लेकिन यह मर्ज किए गए इतिहास में अन्य परिवर्तनों को नहीं दिखाएगा।

दूसरे शब्दों में, यदि आप ZZZरिपॉजिटरी की फाइलों को नहीं बदलते हैं XXX, तो आपको निर्दिष्ट --followऔर एक उपसर्ग पथ की आवश्यकता है। यदि आप उन्हें दोनों रिपॉजिटरी में बदलते हैं, तो आपके पास 2 कमांड हैं, जिनमें से कोई भी सभी बदलाव नहीं दिखाता है।

यहाँ पर अधिक है


4
यदि आपके पास नंगे रिपॉजिटरी या रिमोट के बजाय विलय करने के लिए एक निर्देशिका है, तोgit subtree add -P name-of-desired-prefix ~/location/of/git/repo-without-.git branch-name
Tatsh

2
Noob अनुभव: git (संस्करण 2.9.0.windows.1) "घातक: अस्पष्ट तर्क 'HEAD' का जवाब देता है: अज्ञात संशोधन या काम के पेड़ में नहीं पथ" जब मैंने इसे नए सिरे से आरंभिक, स्थानीय, गैर-नंगे भंडार में आज़माया, लेकिन यह ठीक काम किया के बाद मैं वास्तव में नई रिपोजिटरी जा रहा था, यानी एक सादे फ़ाइल को जोड़ने और नियमित रूप से करने के बाद।
Stein

मेरे परिदृश्य के लिए खूबसूरती से काम किया।
जॉनी उटाह

ओह यह शानदार है।
dwjohnston

मैंने @ ततश सुझाव का इस्तेमाल किया और इसने मेरे लिए काम किया
कार्माइन टैम्बस्किया

49

Git रिपॉजिटरी में इसका एक प्रसिद्ध उदाहरण है, जिसे सामूहिक रूप से Git समुदाय में " सबसे अच्छे मर्ज " के रूप में जाना जाता है (विषय पंक्ति के बाद Linus Torvalds का उपयोग G-mailinglist के लिए ई-मेल में किया गया है जो इसका वर्णन करता है मर्ज)। इस मामले में, gitkGit GUI जो अब Git का हिस्सा है, वास्तव में एक अलग परियोजना हुआ करती थी। लिनुस उस भंडार में एक तरह से उस भंडार को विलय करने में कामयाब रहे

  • यह Git रिपॉजिटरी में प्रकट होता है जैसे कि इसे हमेशा Git के भाग के रूप में विकसित किया गया था,
  • सभी इतिहास को बरकरार रखा गया है और
  • यह अभी भी स्वतंत्र रूप से अपनी पुरानी रिपॉजिटरी में विकसित किया जा सकता है, जिसमें केवल git pullएड होते हैं।

ई-मेल में पुन: पेश करने के लिए आवश्यक कदम हैं, लेकिन यह दिल के बेहोश करने के लिए नहीं है: पहले, लिनस ने गिट लिखा , इसलिए वह शायद इसके बारे में आपको या मेरे बारे में थोड़ा अधिक जानता है, और दूसरा, यह लगभग 5 साल पहले था और Git में तब से काफी सुधार हुआ है , इसलिए शायद अब यह बहुत आसान है।

विशेष रूप से, मुझे लगता है कि आजकल उस विशिष्ट मामले में एक gitk सबमॉडल का उपयोग किया जाएगा।


3
Btw। बाद के मर्ज के लिए इस्तेमाल की जाने वाली रणनीति (यदि कोई हो) को सबट्री मर्ज कहा जाता है , और थर्ड पार्टी git-subtreeटूल है, जो आपकी इस में मदद कर सकता है: github.com/apenwarr/git-subtree
Jakub Narębski

धन्यवाद, मैं इसके बारे में भूल गया। subtreeमर्ज रणनीति, विशेष रूप से साथ संयोजन के रूप में git-subtreeउपकरण के लिए एक अच्छा है, शायद submodules के लिए और भी बेहतर विकल्प नहीं है।
जॉर्ग डब्ल्यू मित्तग

12

इसका सरल तरीका यह है कि git फॉर्मेट-पैच का उपयोग करें।

मान लें कि हमारे पास 2 गिट रिपॉजिटरी फू और बार हैं

फू में शामिल हैं:

  • foo.txt
  • .git

बार में शामिल हैं:

  • bar.txt
  • .git

और हम बार इतिहास और इन फाइलों से युक्त फू -अप के साथ अंत करना चाहते हैं :

  • foo.txt
  • .git
  • foobar / bar.txt

तो ऐसा करने के लिए:

 1. create a temporary directory eg PATH_YOU_WANT/patch-bar
 2. go in bar directory
 3. git format-patch --root HEAD --no-stat -o PATH_YOU_WANT/patch-bar --src-prefix=a/foobar/ --dst-prefix=b/foobar/
 4. go in foo directory
 5. git am PATH_YOU_WANT/patch-bar/*

और यदि हम बार से किए गए सभी संदेशों को फिर से लिखना चाहते हैं, जैसे लिनक्स पर हम कर सकते हैं:

git filter-branch --msg-filter 'sed "1s/^/\[bar\] /"' COMMIT_SHA1_OF_THE_PARENT_OF_THE_FIRST_BAR_COMMIT..HEAD

यह प्रत्येक प्रतिबद्ध संदेश की शुरुआत में "[बार]" जोड़ेगा।


यदि मूल रिपॉजिटरी में शाखाएं और विलय होते हैं, git amतो संभावना नहीं होगी।
एडम मोंसेन

1
माइनर गेट्चा: [ ]कमिट मैसेज से कुछ भी छीन लिया जाता है । तो अगर आप से एक अलग मार्कर का उपयोग करना चाहिए[bar]
HRJ

मेरे लिए काम नहीं किया। "त्रुटि मिली: foobar / mySubDir / test_host1: इंडेक्स में मौजूद नहीं है। जो पैच विफल हुआ है उसकी प्रति इसमें पाई गई है: /home/myuser/src/proj/.git/rebase-apply/patch जब आपने इस समस्या को हल कर लिया है , "git am --continue" चलाएं। यह 11 पैच (60 में से) लगाने के बाद था।
oligofren

1
इस ब्लॉग का कुछ अलग सवाल (केवल चयनित फ़ाइलों को स्थानांतरित करने) के समान उत्तर है।
जेसी ग्लिक

मुझे एक नुकसान दिखाई देता है, सभी हिट लक्ष्य रिपॉजिटरी के हेड में जुड़ जाते हैं।
सीएसचुलज़

8

यह फ़ंक्शन रिमोट रेपो को स्थानीय रेपो डायर में क्लोन करेगा, विलय के बाद सभी कमिट सहेजे git logजाएंगे , मूल कमिट और उचित पथ दिखाए जाएंगे:

function git-add-repo
{
    repo="$1"
    dir="$(echo "$2" | sed 's/\/$//')"
    path="$(pwd)"

    tmp="$(mktemp -d)"
    remote="$(echo "$tmp" | sed 's/\///g'| sed 's/\./_/g')"

    git clone "$repo" "$tmp"
    cd "$tmp"

    git filter-branch --index-filter '
        git ls-files -s |
        sed "s,\t,&'"$dir"'/," |
        GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
    ' HEAD

    cd "$path"
    git remote add -f "$remote" "file://$tmp/.git"
    git pull "$remote/master"
    git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
    git remote remove "$remote"
    rm -rf "$tmp"
}

कैसे इस्तेमाल करे:

cd current/package
git-add-repo https://github.com/example/example dir/to/save

यदि थोड़ा बदलाव करें, तो आप फ़ाइलों / मर्ज किए गए रेपो के विभिन्न रास्तों में भी जा सकते हैं, उदाहरण के लिए:

repo="https://github.com/example/example"
path="$(pwd)"

tmp="$(mktemp -d)"
remote="$(echo "$tmp" | sed 's/\///g' | sed 's/\./_/g')"

git clone "$repo" "$tmp"
cd "$tmp"

GIT_ADD_STORED=""

function git-mv-store
{
    from="$(echo "$1" | sed 's/\./\\./')"
    to="$(echo "$2" | sed 's/\./\\./')"

    GIT_ADD_STORED+='s,\t'"$from"',\t'"$to"',;'
}

# NOTICE! This paths used for example! Use yours instead!
git-mv-store 'public/index.php' 'public/admin.php'
git-mv-store 'public/data' 'public/x/_data'
git-mv-store 'public/.htaccess' '.htaccess'
git-mv-store 'core/config' 'config/config'
git-mv-store 'core/defines.php' 'defines/defines.php'
git-mv-store 'README.md' 'doc/README.md'
git-mv-store '.gitignore' 'unneeded/.gitignore'

git filter-branch --index-filter '
    git ls-files -s |
    sed "'"$GIT_ADD_STORED"'" |
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info &&
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
' HEAD

GIT_ADD_STORED=""

cd "$path"
git remote add -f "$remote" "file://$tmp/.git"
git pull "$remote/master"
git merge --allow-unrelated-histories -m "Merge repo $repo into master" --edit "$remote/master"
git remote remove "$remote"
rm -rf "$tmp"

नोटिस
पथ के माध्यम से बदलता है sed, इसलिए सुनिश्चित करें कि यह विलय के बाद उचित पथ में स्थानांतरित हो गया है। पैरामीटर केवल Git> = 2.9 के बाद से ही मौजूद है।
--allow-unrelated-histories


2
ओएस एक्स के लोगों के gnu-sedलिए, git-add-repoफ़ंक्शन को काम करने के लिए इंस्टॉल करें । धन्यवाद फिर से एंड्री!
9

7

इस लेख के आधार पर , सबट्री का उपयोग करना मेरे लिए काम करता है और केवल लागू इतिहास को स्थानांतरित किया गया था। मामले में किसी को भी यहां कदम उठाने की जरूरत है (प्लेसहोल्डर्स को आपके लिए लागू मूल्यों के साथ बदलना सुनिश्चित करें):

एक नई शाखा में अपने स्रोत भंडार विभाजन सबफ़ोल्डर में

git subtree split --prefix=<source-path-to-merge> -b subtree-split-result

अपने गंतव्य रेपो में विभाजित परिणाम शाखा में विलय

git remote add merge-source-repo <path-to-your-source-repository>
git fetch merge-source-repo
git merge -s ours --no-commit merge-source-repo/subtree-split-result
git read-tree --prefix=<destination-path-to-merge-into> -u merge-source-repo/subtree-split-result

अपने परिवर्तनों को सत्यापित करें और प्रतिबद्ध करें

git status
git commit

भूलना मत

subtree-split-resultशाखा को हटाकर साफ करें

git branch -D subtree-split-result

स्रोत रेपो से डेटा लाने के लिए आपके द्वारा जोड़े गए रिमोट को निकालें

git remote rm merge-source-repo


3

एक और उत्तर जोड़ना क्योंकि मुझे लगता है कि यह थोड़ा सरल है। Repo_dest का एक पुल repo_to_import में किया जाता है और फिर एक पुश -सेट-अपस्ट्रीम url: repo_dest मास्टर किया जाता है।

इस विधि ने मेरे लिए कई छोटे रिपोज को बड़े आकार में आयात करने का काम किया है।

आयात कैसे करें: repo1_to_import to repo_dest

# checkout your repo1_to_import if you don't have it already 
git clone url:repo1_to_import repo1_to_import
cd repo1_to_import

# now. pull all of repo_dest
git pull url:repo_dest
ls 
git status # shows Your branch is ahead of 'origin/master' by xx commits.
# now push to repo_dest
git push --set-upstream url:repo_dest master

# repeat for other repositories you want to import

आयात करने से पहले मूल रेपो में वांछित स्थिति में फ़ाइलों का नाम बदलें या स्थानांतरित करें। जैसे

cd repo1_to_import
mkdir topDir
git add topDir
git mv this that and the other topDir/
git commit -m"move things into topDir in preparation for exporting into new repo"
# now do the pull and push to import

निम्नलिखित लिंक पर वर्णित विधि ने इस उत्तर को प्रेरित किया। मुझे यह पसंद आया क्योंकि यह अधिक सरल लग रहा था। मगर सावधान! ड्रेगन हो! https://help.github.com/articles/importing-an-external-git-repository git push --mirror url:repo_dest आपके स्थानीय रेपो इतिहास और स्थिति को दूरस्थ (url: repo_dest) पर धकेलता है। लेकिन यह पुराने इतिहास और रिमोट की स्थिति को हटा देता है। मज़ा ensues! :-इ


1

मैं अपने मामले में अन्य रिपॉजिटरी (एक्सएक्सएक्स) से केवल कुछ फाइलें आयात करना चाहता था। सबट्री मेरे लिए बहुत जटिल थी और अन्य समाधान काम नहीं कर रहे थे। यह जो मैंने किया है:

ALL_COMMITS=$(git log --reverse --pretty=format:%H -- ZZZ | tr '\n' ' ')

यह आपको उन सभी कमिटों की एक अलग-अलग-अलग सूची देता है जो उन फाइलों को प्रभावित करते हैं जिन्हें मैं रिवर्स ऑर्डर में आयात करना चाहता था (ZZZ) (आपको नाम बदलने के साथ-साथ नाम बदलने के लिए भी जोड़ना होगा)। फिर मैं लक्ष्य रिपॉजिटरी (YYY) में गया, दूसरे रिपॉजिटरी (XXX) को रिमोट के रूप में जोड़ा, इससे एक भ्रूण और आखिरकार:

git cherry-pick $ALL_COMMITS

जो आपकी शाखा में सभी आवागमन जोड़ता है, इस प्रकार आपके पास उनके इतिहास की सभी फाइलें होंगी और आप उनके साथ जो चाहें कर सकते हैं जैसे कि वे हमेशा इस भंडार में रहे हैं।


1

इस लेख में मूल उदाहरण देखें और रिपॉजिटरी पर इस तरह की मैपिंग पर विचार करें:

  • A<-> YYY,
  • B <-> XXX

इस अध्याय में वर्णित सभी गतिविधि के बाद (विलय के बाद), शाखा को हटा दें B-master:

$ git branch -d B-master

फिर, परिवर्तन को धक्का दें।

इससे मेरा काम बनता है।


0

मैं एक ऐसी स्थिति में था जहां मैं तलाश कर रहा था -s theirsलेकिन निश्चित रूप से, यह रणनीति मौजूद नहीं है। मेरा इतिहास यह था कि मैंने GitHub पर एक परियोजना शुरू की थी, और अब किसी कारण से, मेरे स्थानीय के masterसाथ विलय नहीं किया जा सकता upstream/masterथा, हालांकि मैंने इस शाखा में कोई स्थानीय परिवर्तन नहीं किया था। (वास्तव में नहीं पता कि वहां क्या हुआ था - मुझे लगता है कि अपस्ट्रीम ने पर्दे के पीछे कुछ गंदा धक्का दिया था, हो सकता है?)

मैं जो कर रहा था वह समाप्त हो गया

# as per https://help.github.com/articles/syncing-a-fork/
git fetch upstream
git checkout master
git merge upstream/master
....
# Lots of conflicts, ended up just abandonging this approach
git reset --hard   # Ditch failed merge
git checkout upstream/master
# Now in detached state
git branch -d master # !
git checkout -b master   # create new master from upstream/master

तो अब मेरा masterफिर से तालमेल हो गया है upstream/master(और आप उपरोक्त किसी अन्य शाखा के लिए भी दोहरा सकते हैं जिसे आप भी इसी तरह सिंक करना चाहते हैं)।


1
एक git reset --hard upstream/masterअपने स्थानीय पर masterशाखा काम करना होगा। इस तरह से आप लोकल ब्रांच को नहीं खोते हैं - डिफ़ॉल्ट अपस्ट्रीम जैसी चीजें।
17ek पर tomekwi

0

मैं आपकी समस्या के लिए एक और समाधान ( git-submodules का विकल्प ) सुझा सकता हूं - gil (git लिंक) टूल

यह जटिल गिट रिपोजिटरी निर्भरता का वर्णन और प्रबंधन करने की अनुमति देता है।

इसके अलावा यह git पुनरावर्ती सबमॉडुल्स निर्भरता समस्या का समाधान प्रदान करता है

विचार करें कि आपके पास निम्नलिखित परियोजना निर्भरताएँ हैं: नमूना गिट रिपॉजिटरी निर्भरता ग्राफ

फिर आप .gitlinksरिपॉजिटरी रिलेशन विवरण के साथ फाइल को परिभाषित कर सकते हैं :

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

प्रत्येक लाइन निम्नलिखित प्रारूप में गिट लिंक का वर्णन करती है:

  1. भंडार का अनोखा नाम
  2. रिपॉजिटरी का सापेक्ष पथ (.gitlinks फ़ाइल के पथ से शुरू)
  3. Git रिपॉजिटरी जो git क्लोन कमांड रिपोजिटरी ब्रांच में चेकआउट करने के लिए इस्तेमाल की जाएगी
  4. # के साथ शुरू की गई खाली लाइन या लाइन को पार्स नहीं किया जाता है (टिप्पणी के रूप में माना जाता है)।

अंत में आपको अपना रूट सैंपल रिपॉजिटरी अपडेट करना होगा:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

परिणामस्वरूप आप सभी आवश्यक परियोजनाओं का क्लोन बना लेंगे और उन्हें एक दूसरे से उचित तरीके से जोड़ लेंगे।

यदि आप बच्चे से जुड़े भंडार में सभी परिवर्तनों के साथ कुछ भंडार में सभी परिवर्तन करना चाहते हैं, तो आप इसे एक ही आदेश के साथ कर सकते हैं:

gil commit -a -m "Some big update"

पुश, पुश कमांड एक समान तरीके से काम करता है:

gil pull
gil push

गिल (गिट लिंक) उपकरण निम्नलिखित आदेशों का समर्थन करता है:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

गिट पुनरावर्ती सबमोडुल्स निर्भरता समस्या के बारे में अधिक ।


0

मुझे नाम a(के स्थान पर XXXऔर ZZZ) और b(के स्थान पर YYY) का उपयोग करने दें, क्योंकि इससे विवरण पढ़ने में थोड़ा आसान हो जाता है।

आप भंडार मर्ज करना चाहते हैं कहो aमें b(मैं यह सोचते कर रहा हूँ कि वे एक दूसरे के बगल में स्थित हैं):

cd a
git filter-repo --to-subdirectory-filter a
cd ..
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a

यह आप की जरूरत के लिए git-filter-repoस्थापित ( filter-branchहै हतोत्साहित )।

2 बड़े रिपोजिटरी को मर्ज करने का एक उदाहरण, उनमें से एक को एक उपनिर्देशिका में रखा गया है: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

यहाँ पर अधिक है


-1

मुझे ऐसा करने का एक आसान तरीका नहीं पता है। आप यह कर सकते हैं:

  1. XXX रिपॉजिटरी पर ZZZ सुपर-डायरेक्टरी को जोड़ने के लिए git फ़िल्टर-शाखा का उपयोग करें
  2. नई शाखा को YYY रिपॉजिटरी में पुश करें
  3. YYY के ट्रंक के साथ धक्का दिया शाखा को मर्ज करें।

अगर यह आकर्षक लगता है तो मैं विवरण के साथ संपादित कर सकता हूं।


-2

मुझे लगता है कि आप 'git mv' और 'git pull' का उपयोग करके ऐसा कर सकते हैं।

मैं एक निष्पक्ष काम कर रहा हूँ - तो अपने मुख्य भंडार के साथ सावधान रहना चाहिए - लेकिन मैं सिर्फ एक अस्थायी डायर में यह कोशिश की है और यह काम करने लगता है।

पहला - XXX की संरचना का नाम बदलकर मिलान करने के लिए कि आप यह कैसे देखना चाहते हैं जब यह YYY के भीतर है:

cd XXX
mkdir tmp
git mv ZZZ tmp/ZZZ
git mv tmp ZZZ

अब XXX इस तरह दिखता है:

XXX
 |- ZZZ
     |- ZZZ

अब परिवर्तनों को लाने के लिए 'गिट पुल' का उपयोग करें:

cd ../YYY
git pull ../XXX

अब YYY इस तरह दिखता है:

YYY
 |- ZZZ
     |- ZZZ
 |- (other folders that already were in YYY)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.