자식 모듈을 하위 모듈 해제 해제하려면 어떻게해야합니까 (모든 코드를 코어로 다시 가져

자식 서브 모듈을 서브 모듈 해제하려면 어떻게해야합니까 (모든 코드를 코어로 다시 가져 오는 중)?

“최상의 절차”에서와 같이 “어떻게해야”하는지와 같이 …



답변

서브 모듈 코드를 메인 리포지토리에 넣는 것만으로 서브 모듈을 제거하고 파일을 메인 리포지토리에 다시 추가하면됩니다.

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에는 아무런 문제가 없습니다.

이 두 번째 솔루션에서는 원래 하위 모듈에 있던 파일에서 git blame 또는 git log를 실행할 수 있다는 큰 이점이 있습니다. 실제로 여기에서 한 일은 하나의 저장소 내에서 많은 파일의 이름을 바꾸는 것이며 git은 이것을 자동 감지해야합니다. 여전히 git log에 문제가 있다면, 더 나은 이름 바꾸기 / 복사 탐지를 수행하는 몇 가지 옵션 (–follow, -M, -C)을 시도하십시오.


답변

git 1.8.5 (2013 년 11 월 ) 이후 ( 서브 모듈의 기록을 유지하지 않고 ) :

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

그것은 :

  • 서브 모듈을 등록 해제 및 언로드 (즉 , 내용 삭제 ) ( deinit따라서 mv 첫 번째 )
  • .gitmodules당신을 위해 청소 하십시오 ( rm)
  • 상위 저장소 ( ) 의 색인에서 해당 서브 모듈 SHA1을 나타내는 특수 항목을 제거하십시오 rm.

하위 모듈 제거가 완료되면 ( deinitgit rm) 폴더 이름을 원래 이름으로 바꾸고 git repo에 일반 폴더로 추가 할 수 있습니다.

참고 : 하위 모듈이 이전 Git (<1.8)에 의해 작성된 경우 Simon East의 설명.git따라 하위 모듈 자체 내에서 중첩 된 폴더 를 제거해야합니다.


당신이 서브 모듈의 역사를 유지해야하는 경우, 참조 jsears대답 하는 용도, git filter-branch.


답변

모든 파일 히스토리를 유지하면서 하위 모듈을 간단한 디렉토리로 변환하는 스크립트를 작성했습니다. git log --follow <file>다른 솔루션이 겪는 문제로 고통받지 않습니다 . 또한 모든 작업을 수행하는 매우 쉬운 한 줄 호출입니다. 행운을 빈다.

그의 블로그 포스트 ” 부모 저장소에 서브 모듈 통합 “에 설명 된 Lucas Jenß의 훌륭한 작업을 기반으로 하지만 전체 프로세스를 자동화하고 다른 몇 가지 경우를 정리합니다.

최신 코드는 https://github.com/jeremysears/scripts/blob/master/bin/git-submodule-rewrite의 github에서 버그 수정으로 유지 되지만 적절한 스택 오버 플로우 응답 프로토콜을 위해 아래에 전체적으로 솔루션이 있습니다.

용법:

$ git-submodule-rewrite <submodule-name>

자식 서브 모듈 다시 쓰기 :

#!/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

답변

  1. git rm --cached the_submodule_path
  2. .gitmodules파일 에서 하위 모듈 섹션을 제거 하거나 유일한 하위 모듈 인 경우 파일을 제거하십시오.
  3. 커밋 “제거 된 서브 모듈 xyz”
  4. git add the_submodule_path
  5. 또 다른 커밋 “xyz의 추가 된 코드베이스”

아직 더 쉬운 방법을 찾지 못했습니다. git commit -a맛의 문제를 통해 3-5 단계를 한 단계로 압축 할 수 있습니다 .


답변

여기에 많은 답변이 있지만 모두 복잡해 보이며 원하는 것을하지 않을 수 있습니다. 나는 대부분의 사람들이 그들의 역사를 지키기를 원한다고 확신합니다.

이 예에서 기본 리포지토리는 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 폴더를 제외한 모든 폴더와 파일을 하위 폴더로 옮깁니다.

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 log는 기본적으로 이동 된 파일을 따르지 않지만 실행 git log --follow filename하면 파일 의 전체 기록을 볼 수 있습니다.


답변

우리는 두 개의 프로젝트를 위해 두 개의 저장소를 만들어 서로 분리되어 의미가 없었으므로 병합했습니다.

먼저 각 마스터 브랜치를 병합하는 방법을 보여 드리고이를 모든 브랜치로 확장하는 방법을 설명하겠습니다. 도움이 되길 바랍니다.

서브 모듈이 작동하고 있고이를 서브 디렉토리로 변환하려면 다음을 수행하십시오.

git clone project_uri project_name

여기서는 클린 클론을 사용하여 작동합니다. 이 프로세스에서는 서브 모듈을 초기화하거나 업데이트 할 필요가 없으므로 건너 뛰십시오.

cd project_name
vim .gitmodules

.gitmodules선호하는 편집기 (또는 Vim)로 편집 하여 교체하려는 서브 모듈을 제거하십시오. 제거해야 할 줄은 다음과 같아야합니다.

[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

여기서 우리는 두 저장소의 병합 작업을 시작하지만 커밋 전에 중지합니다.

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

여기서 우리는 서브 모듈에있는 master의 내용을 디렉토리 이름 앞에 붙인 디렉토리로 보낸다.

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

이제 병합 변경 사항을 커밋하는 절차를 완료했습니다.

이 작업을 마친 후에는 다른 분기에서 병합을 다시 시작하고 병합 할 수 있습니다. 변경 사항을 수신 할 저장소의 분기를 체크 아웃하고 병합 및 읽기 트리 작업을 수행하는 분기를 변경하기 만하면됩니다.


답변

내가 찾은 이것에 대한 가장 좋은 대답은 다음과 같습니다.

http://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html

이 기사는 절차를 잘 설명합니다.