기록을 유지하면서 git 저장소에서 새 저장소로 단일 디렉토리를 이동하려면 어떻게해야합니까?


110

별도의 디렉토리에 여러 프로젝트가 포함 된 git 저장소를 상속했습니다. 리포지토리를 각 프로젝트마다 하나씩 새로운 개별 리포지토리로 분할 한 다음 마스터 리포지토리에 프로젝트를 하위 모듈로 포함하도록하고 싶습니다. 가능하면 개별 프로젝트의 개정 내역을 유지하면서이 모든 작업을 수행하고 싶습니다.

각 프로젝트에 대한 저장소를 복제하고 매번 다른 모든 프로젝트를 제거 할 수 있지만 새 프로젝트 저장소마다 복제 된 기록을 피하는 더 좋은 방법이 있습니까?


2
저장소의 일부를 하위 모듈로 변환하는 데 매우 유용하므로 git-submodules 태그가 추가되었습니다.
idbrii

답변:


99

git filter-branch프로젝트 기록을 다시 작성하는 데 사용할 수 있습니다 . 문서에서 :

foodir /이 프로젝트 루트 인 것처럼 보이도록 저장소를 다시 작성하고 다른 모든 기록을 삭제하려면 :

git filter-branch --subdirectory-filter foodir -- --all

리포지토리의 복사본을 여러 개 만들고 분할하려는 각 하위 디렉토리에 대해 수행하면 찾고있는 항목이 완성됩니다.


1
foodir 를 제외 하고 모든 기록을 제거 하려면 어떻게해야 합니까?
saeedgnu

1
참고 : 여러 디렉토리를 원하는 경우 --subdirectory-filter여러 번 지정해야합니다 . EG git filter-branch --subdirectory-filter foodir --subdirectory-filter bardir--subdirectory은 여러 dir을 사용하지 않지만 여러 번 지정할 수 있습니다.
EnabrenTane

3
@Adam 이력을 foodir다시 쓰지 않고 원래 프로젝트 의 이력을 유지하려면 git rm -r foodir충분해야합니다 (작업 트리에서 복사본도 삭제됩니다. 원하지 않으면 --cached). 당신은 역사에서 완전히 제거하고자한다면 (너무 ilius의 질문 @ 응답), 당신은 같은 것을 원하는git filter-branch --index-filter 'git rm -r --cached --ignore-unmatched foodir' -- --all
브라이언 캠벨

2
@ilius 이전에 질문을 놓쳐서 죄송합니다. 디렉토리 및 기록을 제거하는 방법에 대한 답변은 위의 답변을 참조하십시오.
Brian Campbell

2
@ilius 그래, 그것도 작동합니다. 대규모 프로젝트의 경우 --index-filter솔루션은 --tree-filter실제로 파일을 체크 아웃 할 필요가없고 인덱스를 직접 조작 할 수 있기 때문에. 는 --tree-filter오히려 인덱스 조작 작업으로 작업하는 것보다 일반 filsystem 작업을 사용할 수 있지만 사용하는 것이 좀 더 쉽게 할 수 있습니다.
Brian Campbell

4

폴더를 새 저장소로 내보내려면 다음이 필요합니다.

  1. 내보내려는 폴더가있는 저장소를 복제합니다.
  2. 호스팅 공급자에 GitHub로 빈 저장소를 생성하려면 내 보낸 폴더를 저장합니다.
  3. 복제 된 저장소 폴더를 열고 다음 명령을 실행합니다.

    git subtree push --prefix=YourFolderNameToExport https://github.com/YourUserName/YourNewCleanRepoName master
    

1
git subtreeCygwin 패키지로는 사용할 수 없습니다. 필요한 경우 : stackoverflow.com/a/27116828/2484903
Jack Miller

2

git의 요점은 부모 커밋을 해싱하여 각 커밋에 기록이 구현된다는 것입니다. 커밋을 새 저장소로 "재생"(기본적으로 svn-importer가 작동하는 방식)하고 각 하위 프로젝트 만 유지할 수 있습니다. 그러나 이것은 커밋 해시의 의미를 파괴합니다. 그것에 문제가 없다면 그렇게하십시오.

과거에 나는 그것을 복제하고 계속 진행했습니다. 이것은 일을 더 크게 만들지 만 디스크 공간은 저렴합니다. 내 시간은 비싸다.

또한 디렉토리를 연결하는 도구도 모릅니다. 디렉토리에 git-log하여 모든 커밋을 찾은 다음 git-fast-export와 같은 것으로 커밋을 재생할 수 있다고 가정합니다.


나는 확실히이 방법을 수행하지 것이다하지만 그는 노력했다 볼 수 있습니다 -이 때문에이 음수가 될 자격이되지 않았기 때문에 upvoted
앨빈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.