기존 Git 저장소를 다른 저장소로 가져 오는 방법은 무엇입니까?


476

XXX 라는 폴더에 Git 저장소가 있고 YYY 라는 두 번째 Git 저장소가 있습니다.

XXX 리포지토리를 YZZ 리포지토리로 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

답변:


430

아마도 가장 간단한 방법은 XXX 항목YYY 의 지점으로 가져온 다음 마스터로 병합하는 것입니다.

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

나는 실제로 몇 가지 내 repos로 이것을 시도했고 작동합니다. Jörg의 답변 과 달리 다른 저장소를 계속 사용할 수는 없지만 어쨌든 지정하지 않았다고 생각합니다.

참고 : 이것은 2009 년에 처음 작성되었으므로 git은 아래 답변에 언급 된 하위 트리 병합을 추가했습니다. 물론이 방법은 여전히 ​​효과가 있지만 아마도 그 방법을 오늘 사용할 것입니다.


1
감사. 기술의 약간 수정 된 버전을 사용했습니다. ZZZ 폴더를 만든 XXX에 '스테이징'브랜치를 만들고 'stuff'를 그 폴더로 옮겼습니다. 그런 다음 XXX를 YYY에 병합했습니다.
Vijay Patel

1
이것은 나를 위해 잘 작동했습니다. 내가 한 유일한 변경 사항은 다음과 같습니다. 1)이 임시 분기가 매달려 싶지 않기 때문에 푸시 전에 "git branch -d ZZZ". 2) "git push"라는 오류가 발생했습니다. "공통 참조가없고 지정되지 않았습니다. 아무 것도하지 않습니다. 아마도 'master'와 같은 분기를 지정해야합니다." (내가 밀었던 원점은 비어있는 빈 저장소였습니다.) 그러나 "git push --all"은 챔피언처럼 작동했습니다.
CrazyPyro

1
YYY 리포지토리의 ZZZ 폴더와 기록 만 사용하고 싶었습니다. 원래 XXX 리포지토리와 YYY 리포지토리의 ZZZ 분기를 삭제하고 싶었습니다. @CrazyPyro가 히스토리 제거를 제안한 것처럼 ZZZ 브랜치를 삭제하는 것을 발견했습니다. 삭제하기 전에 ZZZ 브랜치를 마스터로 병합했습니다.
Oli Studholme

4
@SebastianBlask 나는 두 번의 repos로 이것을 엉망으로 만들었고, 몇 년 동안 나의지지를 얻었음에도 불구하고 아무도 눈치 채지 못한 것처럼 보이는 단계가 없다는 것을 깨달았습니다. :-) 마스터로 병합하는 것을 언급 했지만 실제로 표시하지는 않았습니다. 지금 편집 중 ...
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은 병합을 수행하기 전에 루트가있는 위치를 자체적으로 파악하므로 후속 병합에 접두사를 지정할 필요가 없습니다.

단점은 병합의 역사에 파일이 (가 아닌 하위 디렉토리에) 접두어가 있다는 것입니다. 결과적으로 git log ZZZ/a병합 된 기록을 제외한 모든 변경 사항이 표시됩니다 (있는 경우). 넌 할 수있어:

git log --follow -- a

하지만 병합 된 기록 이외의 변경 사항은 표시되지 않습니다.

즉, ZZZrepository XXX에서 파일을 변경하지 않으면 --follow접두사 를 지정 하고 경로 를 지정해야 합니다. 두 저장소 모두에서 변경하면 두 가지 명령이 있으며 그 중 어느 것도 변경 사항을 모두 표시하지 않습니다.

2.9 이전의 힘내 버전 :에 --allow-unrelated-histories옵션을 전달할 필요가 없습니다 git merge.

단계 를 사용 read-tree하고 건너 뛰는 다른 대답의 방법은 merge -s ourscp로 파일을 복사하고 결과를 커밋하는 것과 사실상 다르지 않습니다.

원본 소스는 github의 "Subtree Merge"도움말에서 제공 됩니다. 그리고 또 다른 유용한 링크 .


9
이것은 역사를 보존하지 않은 것 같습니다 ... git log내가 가져온 파일 중 하나를 수행하면 단일 병합 커밋이 표시되고 다른 리포지토리의 이전 삶과는 전혀 다른 것이 있습니까? 힘내 1.8.0
Anentropic

8
아하! 가져온 파일의 이전 경로를 사용하는 경우 (예 : 가져온 git log -- myfilegit log -- rack/myfile
하위

2
@FrancescoFrassinelli, 바람직하지 않습니까? 히스토리를 가져 오는 것은 이 방법 의 특징 입니다.
patrickvacek

4
@FrancescoFrassinelli, 당신이 역사를 원하지 않는다면, 왜 정기적으로 복사하지 않습니까? 나는 역사가 아닌 경우이 방법으로 당신을 끌 수있는 것을 알아 내려고 노력하고 있습니다-이것이 내가이 방법을 사용한 유일한 이유입니다!
patrickvacek

7
Git 2.9부터는 --allow-unrelated-histories병합을 수행 할 때 옵션이 필요합니다 .
stuXnet

112

git-subtree은 히스토리를 유지하면서 (그리고이 질문과 관련이없는 것처럼 하위 트리의 히스토리를 분할하면서) 여러 리포지토리를 하나로 병합하는이 유스 케이스를 위해 설계된 스크립트입니다. 릴리스 1.7.11 이후 git 트리의 일부로 배포됩니다 .

<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

하지만 병합 된 기록 이외의 변경 사항은 표시되지 않습니다.

즉, ZZZrepository XXX에서 파일을 변경하지 않으면 --follow접두사 를 지정 하고 경로 를 지정해야 합니다. 두 저장소 모두에서 변경하면 두 가지 명령이 있으며 그 중 어느 것도 변경 사항을 모두 표시하지 않습니다.

여기 에 더 있습니다 .


4
Bare 저장소 나 원격 저장소 대신 병합 할 디렉토리가있는 경우git subtree add -P name-of-desired-prefix ~/location/of/git/repo-without-.git branch-name
Tatsh

2
멍청한 경험 : git (버전 2.9.0.windows.1)은 새로 초기화 된 로컬 비 베어 리포지토리에서 시도했을 때 "치명적인 : 모호한 인수 'HEAD': 알 수없는 개정 또는 경로가 작업 트리에 없습니다"라고 응답합니다. 그러나 새 저장소를 실제로 가져온 후에, 즉 일반 파일을 추가하고 정기적으로 커밋 한 후에 정상적으로 작동했습니다.
Stein

내 시나리오에서 아름답게 일했습니다.
Johnny Utahh 2016 년

아 환상적입니다.
dwjohnston

나는 @Tatsh 제안을 사용했고 그것은 나를 위해 일했다
Carmine Tambascia

49

Git 저장소 자체에는 잘 알려진 인스턴스가 있습니다. Git 커뮤니티에서 Git 커뮤니티에서 " 가장 멋진 병합 "으로 알려져 있습니다 (Litus Torvalds가 전자 메일에서 Git 메일 링리스트에 사용 된 제목 줄 다음에이를 설명 함). 병합). 이 경우 gitkGit GUI의 일부인 Git GUI는 실제로 별도의 프로젝트였습니다. Linus는 해당 리포지토리를 Git 리포지토리에 병합하여

  • Git 저장소에 항상 Git의 일부로 개발 된 것처럼 보입니다.
  • 모든 역사는 그대로 유지되고
  • 기존 저장소에서 독립적으로 개발할 수 있으며 변경 사항은 간단하게 변경 git pull됩니다.

전자 메일에는 재생산에 필요한 단계가 포함되어 있지만 마음이 희미하지는 않습니다. 첫째, Linus Git을 으므로 아마 당신이나 나보다 그것에 대해 조금 더 알고있을 것입니다. Git은 그 이후로 상당히 향상 되었으므로 훨씬 쉬울 것입니다.

특히 요즘에는 특정 상황에서 gitk 서브 모듈을 사용한다고 생각합니다.


3
BTW. (어떤이있는 경우) 이후의 병합에 사용되는 전략이라고 하위 트리의 병합 및 타사가 git-subtree이 당신을 도울 수있는 도구 : github.com/apenwarr/git-subtree
야쿱 Narębski

고마워, 나는 그것을 잊었다. subtree특히와 함께 병합 전략, git-subtree도구는 좋은, 서브 모듈에 어쩌면 우수한 대안이다.
Jörg W Mittag

12

이를 수행하는 간단한 방법은 git format-patch를 사용하는 것입니다.

우리가 2 개의 git 저장소 foobar 가 있다고 가정하십시오 .

foo 는 다음을 포함합니다 :

  • foo.txt
  • .git

내용 :

  • bar.txt
  • .git

그리고 우리 는 히스토리 와이 파일들을 포함하는 foo 로 끝내고 싶습니다 :

  • 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/*

그리고 우리가 bar에서 모든 메시지 커밋을 다시 작성하려면 예를 들어 Linux에서 할 수 있습니다.

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

각 커밋 메시지의 시작 부분에 "[bar]"가 추가됩니다.


원래 리포지토리에 분기 및 병합 git am이 포함 된 경우 실패 할 수 있습니다.
Adam Monsen

1
Minor gotcha : git am [ ]은 커밋 메시지에서 무엇이든 제거 합니다. 당신이 아닌 다른 마커를 사용한다 그래서[bar]
HRJ

나를 위해 일하지 않았다. "오류 : foobar / mySubDir / test_host1 : 색인에 없습니다. 실패한 패치의 사본은 다음 위치에 있습니다. /home/myuser/src/proj/.git/rebase-apply/patch이 문제를 해결 한 경우 "git am --continue"를 실행하십시오. 이것은 11 개의 패치를 적용한 후 (60 개 중)
oligofren

1
이 블로그 에는 다소 다른 질문에 대한 비슷한 답변이 있습니다 (선택한 파일 만 이동).
Jesse Glick

단점은 모든 커밋이 대상 리포지토리의 HEAD에 추가된다는 것입니다.
CSchulz

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"

공지 사항
경로는 via를 대체 sed하므로 병합 후 경로가 올바른 경로로 이동했는지 확인하십시오.
--allow-unrelated-histories매개 변수는 git> = 2.9 이후에만 존재합니다.


2
OS X 사용자의 gnu-sed경우 git-add-repo기능을 작동 시키려면 설치 하십시오 . 다시 한 번 감사합니다 Andrey!
ptaylor

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로 완료된 후 push --set-upstream 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)으로 푸시합니다. 그러나 원격의 이전 기록과 상태를 삭제합니다. 재미있다! :-이자형


1

필자의 경우 다른 저장소 (XXX)에서 일부 파일 만 가져오고 싶었습니다. 하위 트리가 너무 복잡하여 다른 솔루션이 작동하지 않았습니다. 이것이 내가 한 일입니다.

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

이것은 가져오고 자하는 파일 (ZZZ)에 역순으로 영향을 미치는 모든 커밋의 공백으로 구분 된 목록을 제공합니다 (이름 변경을 캡처하려면 --follow를 추가해야 할 수도 있음). 그런 다음 대상 저장소 (YYY)로 이동하여 다른 저장소 (XXX)를 원격으로 추가하고 가져 왔습니다.

git cherry-pick $ALL_COMMITS

이것은 모든 커밋을 브랜치에 추가하므로 히스토리가있는 모든 파일을 갖게되며 마치이 저장소에 항상있는 것처럼 원하는 파일을 수행 할 수 있습니다.


1

참조 기본 예제 에서 이 문서 와 저장소에 같은 매핑을 고려 :

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

이 장에서 설명 된 모든 활동 후 (병합 후) branch를 제거하십시오 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지점의 A 가 작업을 수행합니다. 이렇게하면 기본 업스트림과 같은 로컬 브랜치 conflg를 잃지 않습니다.
tomekwi

0

문제에 대한 또 다른 해결책 ( git-submodules 대신)을 제안 할 수 있습니다 - 길 (git links) 도구

복잡한 자식 리포지토리 종속성을 설명하고 관리 할 수 ​​있습니다.

또한 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

각 줄은 git link를 다음 형식으로 설명합니다.

  1. 저장소의 고유 이름
  2. 저장소의 상대 경로 (.gitlinks 파일 경로에서 시작)
  3. git clone 명령에서 사용할 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

Gil (git links) 도구는 다음 명령을 지원합니다.

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) 이름을 사용하겠습니다.bYYY설명을 좀 더 읽기 쉽도록 .

당신이 저장소를 병합 할 말 ab(나는 그들이 서로 옆에 위치하고있어 있으리라 믿고있어) :

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되어 낙담 ).

두 개의 큰 리포지토리를 병합하여 그 중 하나를 하위 디렉터리에 넣는 예 : https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

여기 에 더 있습니다 .


-1

나는 그것을하는 쉬운 방법을 모른다. 당신은 이것을 할 수 있습니다 :

  1. git filter-branch를 사용하여 XXX 저장소에 ZZZ 수퍼 디렉토리를 추가하십시오.
  2. 새 분기를 YYY 저장소로 푸시하십시오.
  3. 푸시 된 분기를 YYY의 트렁크와 병합하십시오.

매력적으로 들리면 세부 사항으로 편집 할 수 있습니다.


-2

'git mv'와 'git pull'을 사용 하여이 작업을 수행 할 수 있다고 생각합니다.

나는 공정한 멍청한 놈이다-그래서 당신의 주요 저장소에주의하십시오-그러나 나는 단지 임시 디렉토리에서 이것을 시도했고 그것은 효과가있는 것 같습니다.

먼저-YYY 내에있을 때의 모양과 일치하도록 XXX의 구조 이름을 바꿉니다.

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

이제 XXX는 다음과 같습니다.

XXX
 |- ZZZ
     |- ZZZ

이제 'git pull'을 사용하여 변경 사항을 가져옵니다.

cd ../YYY
git pull ../XXX

이제 YYY는 다음과 같습니다.

YYY
 |- ZZZ
     |- ZZZ
 |- (other folders that already were in YYY)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.