un-submodule एक गिट submodule


378

मैं जीआई सबमॉड्यूल को कैसे अन-सबमॉडल कर सकता हूं (सभी कोड को कोर में वापस ला सकता हूं)?

जैसा कि "सर्वश्रेष्ठ प्रक्रिया" में, मुझे "कैसे" करना चाहिए ...


5
नोट: git1.8.3 के साथ, आप अब एक कोशिश कर सकते हैं git submodule deinit, नीचे मेरा जवाब देखें
VonC

6
मुझे गलतफहमी हो सकती है, लेकिन git सबमॉड्यूल डिनिट कोड को हटाने लगता है।
जो जर्मनस्का

2
१. is.५ नवंबर (२०१३) के बाद से, एक सरल git submodule deinit asubmodule ; git rm asubmoduleपर्याप्त है, जैसा कि नीचे मेरे उत्तर
VonC

जवाबों:


527

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

git rm --cached submodule_path # delete reference to submodule HEAD (no trailing slash)
git rm .gitmodules             # if you have more than one submodules,
                               # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference
git commit -m "remove submodule"

यदि आप भी सबमॉड्यूल के इतिहास को संरक्षित करना चाहते हैं, तो आप एक छोटा सा ट्रिक कर सकते हैं: सबमॉड्यूल को मुख्य रिपॉजिटरी में "मर्ज" कर दें ताकि परिणाम पहले जैसा हो जाए, सिवाय इसके कि सबमॉड्यूल फाइलें अब अंदर हैं मुख्य भंडार।

मुख्य मॉड्यूल में आपको निम्नलिखित कार्य करने होंगे:

# Fetch the submodule commits into the main repository
git remote add submodule_origin git://url/to/submodule/origin
git fetch submodule_origin

# Start a fake merge (won't change any files, won't commit anything)
git merge -s ours --no-commit submodule_origin/master

# Do the same as in the first solution
git rm --cached submodule_path # delete reference to submodule HEAD
git rm .gitmodules             # if you have more than one submodules,
                               # you need to edit this file instead of deleting!
rm -rf submodule_path/.git     # make sure you have backup!!
git add submodule_path         # will add files instead of commit reference

# Commit and cleanup
git commit -m "removed submodule"
git remote rm submodule_origin

परिणामी भंडार थोड़ा अजीब लगेगा: एक से अधिक प्रारंभिक प्रतिबद्ध होंगे। लेकिन यह git के लिए कोई समस्या पैदा नहीं करेगा।

इस दूसरे समाधान में आपको बड़ा फायदा होगा कि आप अभी भी उन फाइलों पर गिट दोष या गिट लॉग चला सकते हैं जो मूल रूप से सबमॉड्यूल में थे। वास्तव में आपने यहां क्या किया है, एक रिपॉजिटरी के अंदर कई फाइलों का नाम बदलना है, और गिट को यह ऑटोडेट करना चाहिए। यदि आपको अभी भी गिट लॉग की समस्या है, तो कुछ विकल्पों (--follow;, -M, -C) को आज़माएं जो बेहतर नाम / कॉपी पहचान का काम करते हैं।


3
मुझे लगता है कि मुझे आपके पास कुछ git repos पर आपकी दूसरी विधि (इतिहास संरक्षण) करने की आवश्यकता है। क्या आप यह बता सकते हैं कि उपर्युक्त आदेशों में से कौन सा हिस्सा सबम्यूड्यूल से फाइल को उपनिर्देशिका में समाप्त करने का कारण बनता है? क्या यह है कि जब आप मर्ज git फ़ाइल को शीर्ष स्तर निर्देशिका (अपने इतिहास के साथ) में लाते हैं, लेकिन जब आप git को जोड़ते हैं तो submodule_path यह हर फ़ाइल के लिए git mv करता है?
बॉवी ओवंस

5
असल में, हाँ। चाल यह है कि गिट नाम बदलने के संचालन को संग्रहीत नहीं करता है: इसके बजाय, यह माता-पिता के कमिट्स को देखकर उनका पता लगाता है। यदि कोई फ़ाइल सामग्री है जो पिछली प्रतिबद्ध में मौजूद थी, लेकिन एक अलग फ़ाइल नाम के साथ, इसे एक नाम (या प्रतिलिपि) माना जाता है। उपरोक्त चरणों में, git mergeयह सुनिश्चित करता है कि प्रत्येक फ़ाइल के लिए "पिछले प्रतिबद्ध" (मर्ज के दो "पक्षों में से एक) होगा।
gyim

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

4
@theduke मुझे भी यह समस्या थी। यह इन चरणों का पालन करने से पहले तय किया जा सकता है, अपने सबमॉड्यूल रिपॉजिटरी से सभी फाइलों को एक डायरेक्टरी संरचना में उसी पथ के साथ स्थानांतरित करना, जिस रिपॉजिटरी में आप विलय करने वाले हैं: यानी। यदि मुख्य भंडार में आपका सबमॉडल foo / में है, तो सबमॉड्यूल में, प्रदर्शन करें mkdir foo && git mv !(foo) foo && git commit
क्रिस डाउन

35
--allow-unrelated-historiesजैसा कि मुझे मिल रहा था fatal: refusing to merge unrelated histories, नकली मर्ज में मर्ज को जोड़ने के लिए जोड़ने की आवश्यकता है: यहाँ और अधिक: github.com/git/git/blob/master/Documentation/RelNotes/…
vaskort

72

1.8.5 git (नवंबर 2013 ) के बाद से (सबमॉड्यूल के इतिहास को ध्यान में रखते हुए ):

mv yoursubmodule yoursubmodule_tmp
git submodule deinit yourSubmodule
git rm yourSubmodule
mv yoursubmodule_tmp yoursubmodule
git add yoursubmodule

वो होगा:

  • अपंजीकृत और अनलोड (यानी की सामग्री हटाएं ) सबमॉड्यूल ( deinit, इसलिए mv पहला ),
  • .gitmodulesआप के लिए साफ ( rm),
  • और माता-पिता रेपो ( ) के सूचकांक में उस सबमॉड्यूल SHA1 का प्रतिनिधित्व करने वाली विशेष प्रविष्टि को हटा दें rm

एक बार सबमॉड्यूल को हटाने के पूरा होने ( deinitऔर git rm) के बाद, आप फ़ोल्डर को फिर से उसके मूल नाम में बदल सकते हैं और इसे एक नियमित फ़ोल्डर के रूप में गिट रेपो में जोड़ सकते हैं।

नोट: यदि सबमॉडल एक पुराने Git (<1.8) द्वारा बनाया गया था, तो आपको .gitसबमॉड्यूल के भीतर नेस्टेड फ़ोल्डर को हटाने की आवश्यकता हो सकती है, जैसा कि साइमन ईस्ट ने टिप्पणी की थी


यदि आपको उप- इतिहास का इतिहास रखने की आवश्यकता है, तो jsears का उत्तर देखें , जो उपयोग करता है git filter-branch


5
यह वास्तव में 1.8.4 में काम करने वाले पेड़ से हटा देता है (मेरा पूरा सबमॉड्यूल डायर साफ हो गया था)।
क्रिस डाउन

@ क्रिस का मतलब है, deinitअकेले अपने सबमॉडल से काम कर रहे पेड़ को साफ किया?
VonC

हाँ, यह सबमॉड्यूल निर्देशिका की सभी सामग्री को हटा देता है।
क्रिस डाउन

2
@mschuett नहीं, आप कुछ भी याद नहीं कर रहे हैं: एक सबमॉड्यूल में प्रथम स्थान पर एक .गित नहीं है। यदि आपके लिए यह मामला था, तो यह एक नेस्टेड रेपो था, एक सबमॉड्यूल नहीं। यह बताता है कि क्यों यह उत्तर आपके मामले में लागू नहीं होगा। दोनों के बीच अंतर के लिए, stackoverflow.com/a/34410102/6309 देखें ।
वॉन मार्क

1
@VonC मैं वर्तमान में 2.9.0.windows.1 पर हूं, हालांकि सबमॉडल्स कई साल पहले गिट के बहुत पहले संस्करण पर बनाए गए हैं, मुझे यकीन नहीं है। मुझे लगता है कि जब तक मैं अंतिम ऐड + कमिट करने से पहले उस फ़ाइल को हटा देता हूं, तब तक चरण काम करते प्रतीत होते हैं।
साइमन ईस्ट

67

मैंने एक स्क्रिप्ट बनाई है जो सभी फ़ाइल इतिहास को बनाए रखते हुए एक सरल निर्देशिका में एक सबमॉड्यूल का अनुवाद करेगी। यह उन git log --follow <file>मुद्दों से ग्रस्त नहीं है जो अन्य समाधान से ग्रस्त हैं। यह एक बहुत ही आसान एक-लाइन आमंत्रण है जो आपके लिए सभी काम करता है। G'luck।

यह लुकास जेनो द्वारा अपने ब्लॉग पोस्ट " माता-पिता के भंडार में एक सबमॉडल को एकीकृत करना " द्वारा वर्णित उत्कृष्ट कार्य पर बनाता है , लेकिन पूरी प्रक्रिया को स्वचालित करता है और कुछ अन्य कोने के मामलों को साफ करता है।

नवीनतम कोड https://github.com/jeremysears/scripts/blob/master/bin/bin-submodule-rewrite पर github पर Bugfixes के साथ बनाए रखा जाएगा , लेकिन उचित स्टैन्कवरफ़्लो उत्तर प्रोटोकॉल के लिए, मैंने इसमें शामिल किया है नीचे इसकी संपूर्णता में समाधान।

उपयोग:

$ git-submodule-rewrite <submodule-name>

Git-submodule-पुनर्लेखन:

#!/usr/bin/env bash

# This script builds on the excellent work by Lucas Jenß, described in his blog
# post "Integrating a submodule into the parent repository", but automates the
# entire process and cleans up a few other corner cases.
# https://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html

function usage(){
  echo "Merge a submodule into a repo, retaining file history."
  echo "Usage: $0 <submodule-name>"
  echo ""
  echo "options:"
  echo "  -h, --help                Print this message"
  echo "  -v, --verbose             Display verbose output"
}

function abort {
    echo "$(tput setaf 1)$1$(tput sgr0)"
    exit 1
}

function request_confirmation {
    read -p "$(tput setaf 4)$1 (y/n) $(tput sgr0)"
    [ "$REPLY" == "y" ] || abort "Aborted!"
}

function warn() {
  cat << EOF
    This script will convert your "${sub}" git submodule into
    a simple subdirectory in the parent repository while retaining all
    contents and file history.

    The script will:
      * delete the ${sub} submodule configuration from .gitmodules and
        .git/config and commit it.
      * rewrite the entire history of the ${sub} submodule so that all
        paths are prefixed by ${path}.
        This ensures that git log will correctly follow the original file
        history.
      * merge the submodule into its parent repository and commit it.

    NOTE: This script might completely garble your repository, so PLEASE apply
    this only to a fresh clone of the repository where it does not matter if
    the repo is destroyed.  It would be wise to keep a backup clone of your
    repository, so that you can reconstitute it if need be.  You have been
    warned.  Use at your own risk.

EOF

  request_confirmation "Do you want to proceed?"
}

function git_version_lte() {
  OP_VERSION=$(printf "%03d%03d%03d%03d" $(echo "$1" | tr '.' '\n' | head -n 4))
  GIT_VERSION=$(git version)
  GIT_VERSION=$(printf "%03d%03d%03d%03d" $(echo "${GIT_VERSION#git version}" | tr '.' '\n' | head -n 4))
  echo -e "${GIT_VERSION}\n${OP_VERSION}" | sort | head -n1
  [ ${OP_VERSION} -le ${GIT_VERSION} ]
}

function main() {

  warn

  if [ "${verbose}" == "true" ]; then
    set -x
  fi

  # Remove submodule and commit
  git config -f .gitmodules --remove-section "submodule.${sub}"
  if git config -f .git/config --get "submodule.${sub}.url"; then
    git config -f .git/config --remove-section "submodule.${sub}"
  fi
  rm -rf "${path}"
  git add -A .
  git commit -m "Remove submodule ${sub}"
  rm -rf ".git/modules/${sub}"

  # Rewrite submodule history
  local tmpdir="$(mktemp -d -t submodule-rewrite-XXXXXX)"
  git clone "${url}" "${tmpdir}"
  pushd "${tmpdir}"
  local tab="$(printf '\t')"
  local filter="git ls-files -s | sed \"s/${tab}/${tab}${path}\//\" | GIT_INDEX_FILE=\${GIT_INDEX_FILE}.new git update-index --index-info && mv \${GIT_INDEX_FILE}.new \${GIT_INDEX_FILE}"
  git filter-branch --index-filter "${filter}" HEAD
  popd

  # Merge in rewritten submodule history
  git remote add "${sub}" "${tmpdir}"
  git fetch "${sub}"

  if git_version_lte 2.8.4
  then
    # Previous to git 2.9.0 the parameter would yield an error
    ALLOW_UNRELATED_HISTORIES=""
  else
    # From git 2.9.0 this parameter is required
    ALLOW_UNRELATED_HISTORIES="--allow-unrelated-histories"
  fi

  git merge -s ours --no-commit ${ALLOW_UNRELATED_HISTORIES} "${sub}/master"
  rm -rf tmpdir

  # Add submodule content
  git clone "${url}" "${path}"
  rm -rf "${path}/.git"
  git add "${path}"
  git commit -m "Merge submodule contents for ${sub}"
  git config -f .git/config --remove-section "remote.${sub}"

  set +x
  echo "$(tput setaf 2)Submodule merge complete. Push changes after review.$(tput sgr0)"
}

set -euo pipefail

declare verbose=false
while [ $# -gt 0 ]; do
    case "$1" in
        (-h|--help)
            usage
            exit 0
            ;;
        (-v|--verbose)
            verbose=true
            ;;
        (*)
            break
            ;;
    esac
    shift
done

declare sub="${1:-}"

if [ -z "${sub}" ]; then
  >&2 echo "Error: No submodule specified"
  usage
  exit 1
fi

shift

if [ -n "${1:-}" ]; then
  >&2 echo "Error: Unknown option: ${1:-}"
  usage
  exit 1
fi

if ! [ -d ".git" ]; then
  >&2 echo "Error: No git repository found.  Must be run from the root of a git repository"
  usage
  exit 1
fi

declare path="$(git config -f .gitmodules --get "submodule.${sub}.path")"
declare url="$(git config -f .gitmodules --get "submodule.${sub}.url")"

if [ -z "${path}" ]; then
  >&2 echo "Error: Submodule not found: ${sub}"
  usage
  exit 1
fi

if ! [ -d "${path}" ]; then
  >&2 echo "Error: Submodule path not found: ${path}"
  usage
  exit 1
fi

main

उबंटू 16.04 पर काम नहीं करता है। मैंने गितुब रेपो को पुल अनुरोध भेजा ।
qnnc

1
अच्छी पकड़, @qznc। यह OSX पर परीक्षण किया गया था। मैं ख़ुशी से विलीन हो जाऊंगा कि जब यह दोनों प्लेटफार्मों पर गुजरता है।
jsears

@qznc उबंटू 16.04 समर्थन मर्ज किए गए और अपडेट किए गए उत्तर।
17:00

2
यह सबसे अच्छा जवाब है, पूरे इतिहास को रखता है। बहुत अच्छा!
चार्ल्स

1
Git Bash 2.20.1.1 में विंडोज 10 पर त्रुटियों के बिना सभी काम करें। गीथूब के नवीनतम संस्करण के साथ: curl https://raw.githubusercontent.com/jeremysears/scripts/master/bin/git-submodule-rewrite > git-submodule-rewrite.shऔर./git-submodule-rewrite.sh <submodule-name>
एलेक्सी

32
  1. git rm --cached the_submodule_path
  2. सबमॉड्यूल सेक्शन को हटा दें .gitmodulesफ़ाइल , या यदि यह एकमात्र सबमॉड्यूल है, तो फ़ाइल को हटा दें।
  3. एक प्रतिबद्ध "हटाए गए सबमॉड्यूल xyz" करें
  4. git add the_submodule_path
  5. एक और प्रतिबद्ध "xyz का जोड़ा कोडबेस"

मुझे अभी तक कोई आसान रास्ता नहीं मिला। आप git commit -aस्वाद के मामले में 3-5 कदम एक सेक में कर सकते हैं।


6
.gitmodulesइसके बजाय नहीं होना चाहिए .submodules?
इम्ज़ - इवान ज़खरीशेव

1
ऐसा .gitmodulesनहीं होना चाहिए.submodules
मिक्स जूल

1
मैं दूर करने के लिए किया था .gitsubmodule की सूची से पहले git addsubmodule फ़ोल्डर पर काम करेगा
कार्सन इवांस

16

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

इस उदाहरण के लिए मुख्य रेपो होगा git@site.com:main/main.gitऔर सबमॉड्यूल रेपो होगा git@site.com:main/child.git। यह मानता है कि सबमॉडल मूल रेपो की मूल निर्देशिका में स्थित है। आवश्यकतानुसार निर्देश समायोजित करें।

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

git clone git@site.com:main/main.git
git submodule deinit child
git rm child
git add --all
git commit -m "remove child submodule"

अब हम बच्चे के रिपोज को मुख्य रेपो में जोड़ देंगे।

git remote add upstream git@site.com:main/child.git
git fetch upstream
git checkout -b merge-prep upstream/master

अगला चरण मानता है कि आप मर्ज-प्रैप शाखा पर फ़ाइलों को उसी स्थान पर स्थानांतरित करना चाहते हैं, क्योंकि सबमॉड्यूल ऊपर था, हालांकि आप फ़ाइल पथ को बदलकर आसानी से स्थान बदल सकते हैं।

mkdir child

बाल फ़ोल्डर में .गित फ़ोल्डर को छोड़कर सभी फ़ोल्डर्स और फ़ाइलों को स्थानांतरित करें।

git add --all
git commit -m "merge prep"

अब आप अपनी फ़ाइलों को वापस मास्टर शाखा में मर्ज कर सकते हैं।

git checkout master
git merge merge-prep # --allow-unrelated-histories merge-prep flag may be required 

चारों ओर देखें और सुनिश्चित करें कि दौड़ने से पहले सब कुछ अच्छा लगे git push

एक बात जो आपको अब याद रखनी है वह यह है कि git लॉग डिफ़ॉल्ट रूप से स्थानांतरित फ़ाइलों के द्वारा नहीं होता है, लेकिन इसे चलाकर git log --follow filenameआप अपनी फ़ाइलों का पूरा इतिहास देख सकते हैं।


2
मुझे फाइनल में पहुंचने का पूरा मौका मिला और मुझे git merge merge-prepत्रुटि मिली fatal: refusing to merge unrelated histories। वर्कअराउंड यह है git merge --allow-unrelated-histories merge-prep:।
विनम्र

@humblehacker धन्यवाद मैं थोड़ा टिप्पणी के मामले में दूसरों के रूप में अच्छी तरह से चलाते हैं।
एमएसचुसेट

1
सबमॉड्यूल का इतिहास रखने के लिए सबसे अच्छा जवाब। धन्यवाद @mschuett
एंटोन

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

संभवतः, लेकिन मुझे यह पता नहीं है। मैं व्यक्तिगत रूप से रेपो में उन फाइलों को स्थानांतरित करने के लिए एक
कमेटी बनाऊंगा जिन्हें

12

हमारे साथ ऐसा हुआ कि हमने 2 परियोजनाओं के लिए 2 रिपॉजिटरी बनाईं जो इतने युग्मित थे कि उन्हें अलग करने का कोई मतलब नहीं था, इसलिए हमने उन्हें विलय कर दिया।

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

यदि आपको सबमॉड्यूल काम कर रहा है, और आप इसे उस निर्देशिका में बदलना चाहते हैं, जो आप कर सकते हैं:

git clone project_uri project_name

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

cd project_name
vim .gitmodules

.gitmodulesअपने पसंदीदा संपादक (या विम) के साथ संपादित करें उस सबमॉड्यूल को हटाने के लिए जिसे आप बदलने की योजना बनाते हैं। आपको जिन लाइनों को हटाने की आवश्यकता है, वे कुछ इस तरह दिखनी चाहिए:

[submodule "lib/asi-http-request"]
    path = lib/asi-http-request
    url = https://github.com/pokeb/asi-http-request.git

फ़ाइल सहेजने के बाद,

git rm --cached directory_of_submodule
git commit -am "Removed submodule_name as submodule"
rm -rf directory_of_submodule

यहां हम सबमॉड्यूल रिलेशन को पूरी तरह से हटा देते हैं ताकि हम प्रोजेक्ट में दूसरी रेपो को बना सकें।

git remote add -f submodule_origin submodule_uri
git fetch submodel_origin/master

यहां हम मर्ज करने के लिए सबमॉड्यूल रिपॉजिटरी लाते हैं।

git merge -s ours --no-commit submodule_origin/master

यहां हम 2 रिपॉजिटरी का मर्ज ऑपरेशन शुरू करते हैं, लेकिन कमिट करने से पहले रुक जाते हैं।

git read-tree --prefix=directory_of_submodule/ -u submodule_origin/master

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

git commit -am "submodule_name is now part of main project"

यहाँ हम मर्ज में बदलाव की एक प्रक्रिया को पूरा करते हैं।

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


ऐसा प्रतीत नहीं होता है कि सबमॉड्यूल फ़ाइलों का इतिहास संरक्षित है, मैं अभी-अभी जोड़ी गई फाइलों के लिए गिट लॉग में एक ही कमिट देखता हूंdirectory_of_submodule
एनेंट्रोपिक

@Anentropic उत्तर देने में देरी के लिए क्षमा करें। मैंने अभी पूरी प्रक्रिया फिर से (एक छोटे से फिक्स के साथ) की। प्रक्रिया पूरे इतिहास को रखती है, लेकिन इसमें एक मर्ज बिंदु है, शायद यही कारण है कि आप इसे नहीं ढूंढते हैं। यदि आप सबमॉड्यूल इतिहास देखना चाहते हैं तो केवल "गिट लॉग" करें, मर्ज कमिट के लिए लुकअप (उदाहरण में संदेश के साथ एक है "सबमॉड्यूल_नाम अब मुख्य परियोजना का हिस्सा है")। इसमें 2 पैरेंट कमिट होंगे (मर्ज: sdasda asdasd), git दूसरी कमिट लॉग इन करें और आपको अपने सभी सबमॉड्यूल / मास्टर इतिहास मिल गए।
डिविसिनो

मेरी स्मृति अब धुंधली है, लेकिन मुझे लगता है कि मैं मर्ज किए गए सबमॉड्यूल फ़ाइलों के इतिहास को प्राप्त करने में सक्षम था, git log original_path_of_file_in_submoduleअर्थात फ़ाइल के लिए गिट रेपो में पंजीकृत पथ (जो अब फ़ाइल सिस्टम पर मौजूद नहीं है) भले ही सबम्यूअल फ़ाइल हो अब रहता हैsubmodule_path/new_path_of_file
एंथ्रोपिक

यह इतिहास को बहुत अच्छी तरह से संरक्षित नहीं करता है, और पथ भी गलत हैं। मुझे लगता है कि ट्री-फ़िल्टर जैसी किसी चीज़ की ज़रूरत है लेकिन मैं अपनी गहराई से बाहर हूँ ... कोशिश कर रहा हूँ कि मुझे यहाँ क्या मिला है: x3ro.de/2013/09/01/…
ल्यूक एच

यह उत्तर अप्रचलित है, stackoverflow.com/a/16162228/11343 (VonC उत्तर) ऐसा ही करता है लेकिन बेहतर है
CharlesB


6

यहाँ @ gimim के उत्तर का थोड़ा उन्नत संस्करण (IMHO) है। वह मुख्य कार्य प्रतिलिपि में खतरनाक परिवर्तनों का एक गुच्छा कर रहा है, जहां मुझे लगता है कि अलग-अलग क्लोनों पर काम करना बहुत आसान है और फिर अंत में उन्हें एक साथ मर्ज करना।

एक अलग निर्देशिका में (गलतियों को आसानी से साफ करने और फिर से प्रयास करने के लिए) शीर्ष रेपो और सब्रेपो दोनों की जांच करें।

git clone ../main_repo main.tmp
git clone ../main_repo/sub_repo sub.tmp

वांछित सबनिर्देशिका में सभी फ़ाइलों को स्थानांतरित करने के लिए पहले सब्रेपो को संपादित करें

cd sub.tmp
mkdir sub_repo_path
git mv `ls | grep -v sub_repo_path` sub_repo_path/
git commit -m "Moved entire subrepo into sub_repo_path"

HEAD का नोट बना लें

SUBREPO_HEAD=`git reflog | awk '{ print $1; exit; }'`

अब मुख्य रेपो से सब्रेपो को हटा दें

cd ../main.tmp
rmdir sub_repo_path
vi .gitmodules  # remove config for submodule
git add -A
git commit -m "Removed submodule sub_repo_path in preparation for merge"

और अंत में, बस उन्हें मर्ज करें

git fetch ../sub.tmp
# remove --allow-unrelated-histories if using git older than 2.9.0
git merge --allow-unrelated-histories $SUBREPO_HEAD

और हो गया! सुरक्षित रूप से और बिना किसी जादू के।


... कौन सा उत्तर है? संभवत: समय के साथ शीर्ष उत्तर बदल सकता है और साथ ही उपयोगकर्ता नाम का संदर्भ लेना चाहता है।
कंटैंगो

@Contango उत्तर अपडेट किया गया। लेकिन शीर्ष उत्तर अभी भी 400 अंक की बढ़त के साथ शीर्ष उत्तर है ;-)
डकैती

क्या यह काम करता है अगर सब्रेपो में पहले से ही एक निर्देशिका है subrepoजिसमें सामान है?
23

अंतिम चरण में मुझे निम्नलिखित त्रुटि मिलती है: git merge $SUBREPO_HEAD fatal: refusing to merge unrelated historiesक्या मुझे git merge $SUBREPO_HEAD --allow-unrelated-historiesइस मामले में उपयोग करना चाहिए ? या इसके बिना काम करना चाहिए और मैंने गलती की?
तिवारी

1
@ Ti-m हां, यह वास्तव में दो इतिहासों को मिलाने का मामला है जो किसी भी साझा को साझा नहीं करते हैं। असंबंधित इतिहास के खिलाफ पहरेदार मुझे लगता है कि यह पहली बार लिखा था के बाद से गिट में नया हो रहा है; मैं अपना जवाब अपडेट करूंगा।
dataless

3

जब के लिए

git rm [-r] --cached submodule_path

रिटर्न

fatal: pathspec 'emr/normalizers/' did not match any files

संदर्भ: मैंने rm -r .git*अपने सबमॉड्यूल फ़ोल्डरों में यह महसूस करने से पहले किया था कि उन्हें मुख्य परियोजना में डी-सबमोडाइल्ड होने की आवश्यकता थी जिसमें मैंने उन्हें अभी जोड़ा था। मुझे उपरोक्त त्रुटि तब हुई जब कुछ को डी-सबमॉडलिंग किया गया, लेकिन उन सभी को नहीं। वैसे भी, मैंने उन्हें चलाकर तय किया, (बाद में, निश्चित रूप से rm -r .git*)

mv submodule_path submodule_path.temp
git add -A .
git commit -m "De-submodulization phase 1/2"
mv submodule_path.temp submodule_path
git add -A .
git commit -m "De-submodulization phase 2/2"

ध्यान दें कि यह इतिहास को संरक्षित नहीं करता है।


3

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

नामक एक फाइल में git-integrate-submodule:

#!/usr/bin/env bash
mv "$1" "${1}_"
git submodule deinit "$1"
git rm "$1"
mv "${1}_" "$1"
git add "$1/**"

0

मुझे यह अधिक सुविधाजनक लगा (यह भी?) सबमॉड्यूल से स्थानीय प्रतिबद्ध डेटा प्राप्त करना, क्योंकि अन्यथा मैं उन्हें ढीला कर दूंगा। (उन्हें धक्का नहीं दे सकता था क्योंकि मुझे उस रिमोट तक पहुंच नहीं थी)। इसलिए मैंने submodule / .git को Remote_origin2 के रूप में जोड़ा, यह कमिट किया और उस शाखा से विलय कर दिया। मुझे यकीन नहीं है कि अगर मुझे अभी भी मूल के रूप में सबमॉडल रिमोट की आवश्यकता है, क्योंकि मैं अभी तक गिट से परिचित नहीं हूं।


0

यहाँ मुझे जो सबसे अच्छा और सरल मिला।

सबमॉड्यूल रेपो में, HEAD से आप मुख्य रेपो में विलय करना चाहते हैं:

  • git checkout -b "mergeMe"
  • mkdir "foo/bar/myLib/" (समान पथ जहाँ आप मुख्य रेपो पर फ़ाइलें चाहते हैं)
  • git mv * "foo/bar/myLib/" (सभी को पथ में ले जाएँ)
  • git commit -m "ready to merge into main"

सबमोडुले को हटाने और "फू / बार / मायलिब" रास्ता साफ करने के बाद मुख्य रेपो में वापस:

  • git merge --allow-unrelated-histories SubmoduleOriginRemote/mergeMe

बूम किया

इतिहास संरक्षित है

कोई चिंता नहीं


यह लगभग कुछ अन्य उत्तरों के समान है। लेकिन यह आपको सबमॉडल रेपो मानता है। इसके अलावा, यह सबमॉड्यूल के लिए भविष्य के अपस्ट्रीम परिवर्तनों को प्राप्त करना आसान बनाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.