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

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

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



답변

세부 솔루션

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종속성을 설치하려는 위치에서 실행

답변

@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


답변

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'


답변