SVN 리포지토리를 Git으로 성공적으로 변환 한 후 이제 여러 개의 작은 리포지토리로 나누고 기록을 유지하려는 매우 큰 Git 리포지토리를 갖게되었습니다.
따라서 누군가 다음과 같은 repo를 분해하는 데 도움을 줄 수 있습니까?
MyHugeRepo/
.git/
DIR_A/
DIR_B/
DIR_1/
DIR_2/
다음과 같은 두 개의 저장소로 :
MyABRepo/
.git
DIR_A/
DIR_B/
My12Repo/
.git
DIR_1/
DIR_2/
이 이전 질문에서 지침을 따르려고 시도했지만 여러 디렉토리를 별도의 저장소에 넣으려고 할 때 실제로 적합하지 않습니다 ( Detach (move) 하위 디렉토리를 별도의 Git 저장소로 ).
답변
그러면 MyABRepo가 설정됩니다. 물론 My12Repo도 비슷하게 할 수 있습니다.
git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD
.git / refs / original / refs / heads / master에 대한 참조가 남아 있습니다. 다음과 같이 제거 할 수 있습니다.
cd ..
git clone MyABRepo.tmp MyABRepo
모든 것이 잘되면 MyABRepo.tmp를 제거 할 수 있습니다.
어떤 이유로 .git-rewrite와 관련된 오류가 발생하면 다음을 시도 할 수 있습니다.
git clone MyHugeRepo/ MyABRepo.tmp/
cd MyABRepo.tmp
git filter-branch -d /tmp/git-rewrite.tmp --prune-empty --index-filter 'git rm --cached --ignore-unmatch DIR_1/* DIR_2/*' HEAD
cd ..
git clone MyABRepo.tmp MyABRepo
이렇게하면 /tmp/git-rewrite.tmp를 임시 디렉터리로 만들어 .git-rewrite
. 당연히 /tmp/git-rewrite.tmp
쓰기 권한이 있고 디렉토리가 아직 존재하지 않는 한 대신 원하는 경로로 대체 할 수 있습니다.
답변
git filter-branch --index-filter
with git rm --cached
를 사용 하여 원래 저장소의 복제본 / 복사본에서 원하지 않는 디렉토리를 삭제할 수 있습니다 .
예를 들면 :
trim_repo() { : trim_repo src dst dir-to-trim-out...
: uses printf %q: needs bash, zsh, or maybe ksh
git clone "$1" "$2" &&
(
cd "$2" &&
shift 2 &&
: mirror original branches &&
git checkout HEAD~0 2>/dev/null &&
d=$(printf ' %q' "$@") &&
git for-each-ref --shell --format='
o=%(refname:short) b=${o#origin/} &&
if test -n "$b" && test "$b" != HEAD; then
git branch --force --no-track "$b" "$o"
fi
' refs/remotes/origin/ | sh -e &&
git checkout - &&
git remote rm origin &&
: do the filtering &&
git filter-branch \
--index-filter 'git rm --ignore-unmatch --cached -r -- '"$d" \
--tag-name-filter cat \
--prune-empty \
-- --all
)
}
trim_repo MyHugeRepo MyABRepo DIR_1 DIR_2
trim_repo MyHugeRepo My12Repo DIR_A DIR_B
각 저장소의 불필요한 브랜치 또는 태그를 수동으로 삭제해야합니다 (예 : feature-x-for-AB 브랜치가있는 경우 “12”저장소에서 삭제할 수 있음).
답변
git_split 프로젝트는 원하는 것을 정확히 수행하는 간단한 스크립트입니다. https://github.com/vangorra/git_split
git 디렉토리를 자체 위치에있는 자체 저장소로 전환합니다. 하위 트리 재미있는 사업이 없습니다. 이 스크립트는 git 저장소의 기존 디렉토리를 가져 와서 해당 디렉토리를 자체 독립 저장소로 바꿉니다. 그 과정에서 사용자가 제공 한 디렉토리의 전체 변경 내역을 복사합니다.
./git_split.sh <src_repo> <src_branch> <relative_dir_path> <dest_repo>
src_repo - The source repo to pull from.
src_branch - The branch of the source repo to pull from. (usually master)
relative_dir_path - Relative path of the directory in the source repo to split.
dest_repo - The repo to push to.
답변
다음은이를 수행 할 루비 스크립트입니다.
https://gist.github.com/4341033
답변
귀하의 답변에 감사하지만 저장소를 두 번 복사 한 다음 각각에서 원하지 않는 파일을 삭제했습니다. 나중에 다른 곳에서 버전이 제어되기 때문에 삭제 된 파일에 대한 모든 커밋을 제거하기 위해 나중에 filter-branch를 사용할 것입니다.
cp -R MyHugeRepo MyABRepo
cp -R MyHugeRepo My12Repo
cd MyABRepo/
rm -Rf DIR_1/ DIR_2/
git add -A
git commit -a
이것은 내가 필요한 것을 위해 일했습니다.
편집 : 물론 A 및 B 디렉토리에 대해 My12Repo에서 동일한 작업이 수행되었습니다. 이것은 원치 않는 디렉토리를 삭제할 때까지 동일한 기록을 가진 두 개의 저장소를 제공했습니다.