폴더에서 하위 모듈 저장소를 만들고 git 커밋 기록을 유지합니다.


111

특정 방식으로 다른 웹 애플리케이션을 탐색하는 웹 애플리케이션이 있습니다. demos폴더 에 일부 웹 데모가 포함되어 있으며 데모 중 하나에 자체 저장소가 있어야합니다. 이 데모 응용 프로그램에 대한 별도의 저장소를 만들고하위 패키지 커밋 기록을 잃지 않고 주 저장소의 하위 모듈 .

리포지토리 폴더의 파일에서 커밋 기록을 유지하고 거기에서 리포지토리를 만들고 대신 서브 모듈 로 사용할 수 있습니까?


Git 리포지토리 A에서 Git 리포지토리 B로 디렉토리 1을 이동하는 방법을 검색했습니다. 기사에 대한 링크는 +1입니다.
Chetabahana 2015


예이 솔루션이 공유 주셔서 감사합니다 약간의 차이가 실제로 매우 유사합니다
GabLeRoux

답변:


191

세부 솔루션

npm을 사용하는 git 하위 모듈에 대한 빠른 대안은이 답변 끝에있는 참고 (마지막 단락)를 참조하십시오.)

다음 답변에서는 저장소에서 폴더를 추출하고 거기에서 git 저장소를 만든 다음 폴더 대신 하위 모듈 로 포함하는 방법을 알 수 있습니다.

Gerg Bayer의 기사 에서 Git 저장소 간에 파일 이동, 기록 보존 에서 영감을 얻었습니다.

처음에는 다음과 같은 것이 있습니다.

<git repository A>
    someFolders
    someFiles
    someLib <-- we want this to be a new repo and a git submodule!
        some files

단계가 울부 짖는 소리, 나는 이것을 참조 할 것 someLib같은 <directory 1>.

마지막에는 다음과 같은 것이 있습니다.

<git repository A>
    someFolders
    someFiles
    @submodule --> <git repository B>

<git repository B>
    someFolders
    someFiles

다른 저장소의 폴더에서 새 git 저장소 만들기

1 단계

분할 할 저장소의 새 복사본을 가져옵니다.

git clone <git repository A url>
cd <git repository A directory>

2 단계

현재 폴더가 새 저장소가되므로 현재 원격을 제거하십시오.

git remote rm origin

3 단계

원하는 폴더의 기록을 추출하고 커밋합니다.

git filter-branch --subdirectory-filter <directory 1> -- --all

이제 directory 1모든 관련 커밋 기록과 함께 저장소의 루트에 있는 파일이있는 git 저장소가 있어야합니다 .

4 단계

온라인 저장소를 만들고 새 저장소를 푸시하십시오!

git remote add origin <git repository B url>
git push

upstream첫 번째 푸시를 위해 분기 를 설정해야 할 수 있습니다.

git push --set-upstream origin master

정리 <git repository A>(선택 사항, 주석 참조)

우리는의 (역사를 파일과 커밋) 흔적을 삭제할 <git repository B>에서 <git repository A>한 번만이이 폴더에 대한 역사 때문에.

이는 github에서 민감한 데이터 제거를 기반으로 합니다.

새 폴더로 이동하고

git clone <git repository A url>
cd <git repository A directory>
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <directory 1> -r' --prune-empty --tag-name-filter cat -- --all

<directory 1>제거하려는 폴더로 바꿉니다 . -r지정된 디렉토리 내에서 재귀 적으로 수행합니다. :). 지금에 밀어 origin/master--force

git push origin master --force

보스 스테이지 (아래 참고 참조)

크리에이트 서브 모듈 에서 <git repository B>로를<git repository A>

git submodule add <git repository B url>
git submodule update
git commit

모든 것이 예상대로 작동하는지 확인하고 push

git push origin master

노트

이 모든 작업을 수행 한 후 내 경우에는 npm 을 사용 하여 내 자신의 종속성을 관리 하는 것이 더 적절하다는 것을 깨달았습니다 . git url과 버전을 지정할 수 있습니다. package.json git urls as dependencies를 참조하십시오 .

이렇게하면 요구 사항으로 사용할 리포지토리가 npm 모듈 이어야하므로 package.json파일 이 있어야합니다. 그렇지 않으면 다음 오류가 발생 Error: ENOENT, open 'tmp.tgz-unpack/package.json'합니다..

tldr (대체 솔루션)

당신은 쉽게 사용할 찾을 수 있습니다 NPM을 하고 자식 URL을 종속성을 관리 :

  • 새 저장소로 폴더 이동
  • npm init두 저장소 내에서 실행
  • npm install --save git://github.com/user/project.git#commit-ish종속성을 설치하려는 위치에서 실행

39
"Clean <git repository A>"단계는 피해야합니다. 이렇게하면 기록에서 이전 버전 / 커밋을 완전히 복원 / 체크 아웃 할 수 없습니다. 폴더를 git rm하고 하위 모듈을 추가하면됩니다. 따라서 이전 커밋을 확인할 때 완전히 작동하는 복사본이 있는지 확인합니다.
Cybot 2014

cd someLib2 단계 전에 해야하지 않습니까? "현재 폴더가 새 저장소가됩니다"라고 말하지만 실제로는 그렇지 않습니다. 새 저장소 (하위 모듈)는 해당 폴더 안에 있습니다.
Jago

1
확인 : 예, 하나 이상의 하위 모듈에서 작동합니다. 자세한 답변에 감사드립니다. 또한 npm을 사용할 필요가 없습니다.
Breno Inojosa

2
내가 추가 할 정보를 정보] refs/original/...3 단계에서 생성 된
에밀의 Bergeron

6
GitHub는 새 저장소로 폴더를 추출하는 방법에 대한 기사를 작성했습니다. help.github.com/articles/…
jrobichaud

9

@GabLeRoux의 솔루션은 브랜치 및 관련 커밋을 스쿼시합니다.

모든 추가 브랜치 및 커밋을 복제하고 유지하는 간단한 방법 :

1-이 git 별칭이 있는지 확인

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

2-원격 복제, 모든 분기 가져 오기, 원격 변경, 디렉터리 필터링, 푸시

git clone git@github.com:user/existing-repo.git new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin git@github.com:user/new-repo.git
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags

3

GabLeRoux의 솔루션은 git lfs분리하려는 디렉토리 아래에 대용량 파일 을 사용하고있는 경우를 제외하고는 잘 작동합니다 . 이 경우 3 단계 이후 모든 대용량 파일은 실제 파일 대신 포인터 파일로 유지됩니다. 아마도 .gitattributes필터 분기 프로세스에서 파일이 제거 되었기 때문일 것입니다 .

이것을 깨닫고 다음 솔루션이 저에게 효과적이라는 것을 알았습니다.

cp .gitattributes .git/info/attributes

.gitattributesgit lfs가 대용량 파일을 추적하는 데 사용하는 git lfs를 .git/디렉토리로 복사 하여 삭제를 방지합니다.

filter-branch가 완료 .gitattributes되면 새 저장소에 git lfs를 계속 사용하려면 다시 넣는 것을 잊지 마십시오 .

mv .git/info/attributes .gitattributes
git add .gitattributes
git commit -m 'added back .gitattributes'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.