두 개의 Git 리포지토리를 새로운 세 번째 리포지토리로 병합해야합니다. 하위 트리 병합 (예 : 두 개의 Git 리포지토리를 병합하는 방법에 대한 Jakub Narębski의 답변) 을 사용 하여이 작업을 수행하는 방법에 대한 많은 설명을 찾았으며 하위 트리를 커밋 할 때 모든 파일을 병합한다는 점을 제외하고는 대부분 지침을 따릅니다. 이전 리포지토리에서 새 추가 파일로 기록됩니다. 내가 할 때 이전 리포지토리에서 커밋 기록을 볼 수 있지만 그렇게 하면 해당 파일에 대한 커밋이 하나만 표시됩니다-하위 트리 병합. 위의 답변에 대한 의견에서 판단 할 때, 나는이 문제를 보는 데 혼자가 아니지만 게시 된 해결책을 찾지 못했습니다.git log
git log <file>
리포지토리를 병합하고 개별 파일 기록을 그대로 두는 방법이 있습니까?
답변
두 리포지토리를 함께 붙이고 외부 종속성을 관리하는 것이 아니라 모든 방식으로 보이도록하면 대답이 훨씬 간단합니다. 원격 저장소를 기존 저장소에 추가하고 새 저장소에 병합하고 파일 및 폴더를 하위 디렉토리로 이동 한 다음 이동을 커밋하고 모든 추가 저장소에 대해 반복하면됩니다. 하위 모듈, 하위 트리 병합 및 고급 rebase는 약간 다른 문제를 해결하기 위해 만들어졌으며 내가하려는 일에 적합하지 않습니다.
다음은 두 개의 저장소를 서로 연결하는 Powershell 스크립트의 예입니다.
# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init
# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"
# Add a remote for and fetch the old repo
git remote add -f old_a <OldA repo URL>
# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories
# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}
# Commit the move
git commit -m "Move old_a files into subdir"
# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"
그 대신에 old_b를 old_a (새로운 결합 저장소가 됨)로 병합하는 대신 스크립트를 수정하십시오.
진행중인 기능 분기를 가져 오려면 다음을 사용하십시오.
# Bring over a feature branch from one of the old repos
git checkout -b feature-in-progress
git merge -s recursive -Xsubtree=old_a old_a/feature-in-progress
그것은 프로세스의 유일한 명백한 부분입니다-그것은 하위 트리 병합이 아니라, 일반적인 재귀 병합에 대한 인수로, Git에게 대상의 이름을 변경했으며 Git이 모든 것을 올바르게 정렬하도록 도와줍니다.
여기에 좀 더 자세한 설명을 썼습니다 .
답변
기록을 다시 쓰지 않는 방법이 있으므로 모든 커밋 ID가 계속 유효합니다. 결과적으로 두 번째 리포지토리의 파일은 하위 디렉토리에있게됩니다.
-
두 번째 저장소를 원격으로 추가하십시오.
cd firstgitrepo/ git remote add secondrepo username@servername:andsoon
-
두 번째 repo의 커밋을 모두 다운로드했는지 확인하십시오.
git fetch secondrepo
-
두 번째 리포지토리에서 로컬 브랜치를 만듭니다.
git branch branchfromsecondrepo secondrepo/master
-
모든 파일을 서브 디렉토리로 이동하십시오.
git checkout branchfromsecondrepo mkdir subdir/ git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} subdir/ git commit -m "Moved files to subdir/"
-
두 번째 브랜치를 첫 번째 repo의 마스터 브랜치로 병합하십시오.
git checkout master git merge --allow-unrelated-histories branchfromsecondrepo
저장소에 루트 커밋이 두 개 이상 있지만 문제가되지는 않습니다.
답변
몇 년이 지났고 잘 기반을 둔 투표 솔루션이 있지만 이전 저장소의 기록을 삭제하지 않고 2 개의 원격 저장소를 새 저장소로 병합하고 싶기 때문에 조금 다릅니다 .
-
Github에서 새 저장소를 만듭니다.
-
새로 작성된 저장소를 다운로드하고 이전 원격 저장소를 추가하십시오.
git clone https://github.com/alexbr9007/Test.git cd Test git remote add OldRepo https://github.com/alexbr9007/Django-React.git git remote -v
-
이전 리포지토리에서 모든 파일을 가져 와서 새 분기를 만듭니다.
git fetch OldRepo git branch -a
-
마스터 브랜치에서 병합을 수행하여 이전 리포지토리를 새로 생성 된 리포지토리와 결합하십시오.
git merge remotes/OldRepo/master --allow-unrelated-histories
-
OldRepo에서 추가 된 모든 새로 작성된 컨텐츠를 저장하고 파일을이 새 폴더로 이동하려면 새 폴더를 작성하십시오.
-
마지막으로 결합 된 저장소에서 파일을 업로드하고 GitHub에서 OldRepo를 안전하게 삭제할 수 있습니다.
이것이 원격 저장소 병합을 다루는 모든 사람에게 유용 할 수 있기를 바랍니다.
답변
사용을 살펴보십시오
git rebase --root --preserve-merges --onto
삶의 초기에 두 역사를 연결합니다.
경로가 겹치는 경우 다음과 같이 수정하십시오.
git filter-branch --index-filter
로그를 사용할 때 다음을 사용하여 “복사본 찾기”를 확인하십시오.
git log -CC
그렇게하면 경로에서 파일의 움직임을 찾을 수 있습니다.
답변
@Flimm 의 솔루션 을 다음 git alias
과 같이 (내 추가 ~/.gitconfig
)했습니다.
[alias]
mergeRepo = "!mergeRepo() { \
[ $# -ne 3 ] && echo \"Three parameters required, <remote URI> <new branch> <new dir>\" && exit 1; \
git remote add newRepo $1; \
git fetch newRepo; \
git branch \"$2\" newRepo/master; \
git checkout \"$2\"; \
mkdir -vp \"${GIT_PREFIX}$3\"; \
git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} \"${GIT_PREFIX}$3\"/; \
git commit -m \"Moved files to '${GIT_PREFIX}$3'\"; \
git checkout master; git merge --allow-unrelated-histories --no-edit -s recursive -X no-renames \"$2\"; \
git branch -D \"$2\"; git remote remove newRepo; \
}; \
mergeRepo"
답변
이 기능은 원격 저장소를 로컬 저장소로 복제합니다.
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
주의. 이 스크립트는 커밋을 다시 작성할 수 있지만 모든 작성자와 날짜를 저장합니다. 즉, 새로운 커밋에 다른 해시가 있으며, 변경 사항을 원격 서버로 푸시하려고하면 강제 키로 만 수행 할 수 있으며 서버에서 커밋도 다시 작성됩니다. 따라서 시작하기 전에 백업을 만드십시오.
이익!
답변
두 git 기록을 병합하여 하나의 git history를 갖는 한 repo를 다른 repo에 포함시키는 단계를 따르십시오.
- 병합하려는 리포지토리를 모두 복제하십시오.
자식 클론 git@github.com : user / parent-repo.git
자식 클론 git@github.com : user / child-repo.git
- 아동 저장소로 이동
CD 아동 레포 /
- 아래 명령을 실행하고 경로
my/new/subdir
(3 발생)를 하위 저장소를 원하는 디렉토리 구조로 바꾸십시오 .
git filter-branch –prune-empty –tree-filter ‘if [! -e my / new / subdir]; mkdir -p my / new / subdir git ls-tree-이름 만 $ GIT_COMMIT | xargs -I 파일 mv 파일 my / new / subdir fi ‘
- 부모 저장소로 이동
cd ../parent-repo/
- 하위 리포지토리에 대한 경로를 가리키는 상위 리포지토리에 원격 추가
자식 원격 추가 자식 원격 ../child-repo/
- 아이 레포를 가져옵니다
자식 원격 가져 오기 자식
- 역사를 병합
git merge-관련이없는 아이의 원격 / 마스터를 허용
부모 리포지토리에서 git 로그를 확인하면 자식 리포지토리가 병합되어야합니다. 커밋 소스에서 나타내는 태그를 볼 수도 있습니다.
아래 기사는 두 리포지토리를 병합하여 하나의 단일 리포지토리를 갖는 한 리포지를 다른 리포에 포함시키는 데 도움이되었습니다.
http://ericlathrop.com/2014/01/combining-git-repositories/
도움이 되었기를 바랍니다. 행복한 코딩!