티스토리 뷰

Copy of How to copy Sub Directory to another Git Repo

 

Git Repository 통폐합 과정에서 기존 Git Commit History를 유지하는 것이 중요하다.

일반적인 방법으로 A Repo를 B Repo에 통합했을 때, A Repo의 모든 Commit 정보가 B Repo에 전달된다

A Repo의 특정 디렉토리 및 특정 프로젝트만을 B Repo에 통합해야하는 상황에도 불필요한 모든 Commit 정보가 포함되는 것이다.

이 문서는 A Repo의 특정 디렉토리를 B Repo로 통합하는 과정에서, 그 디렉토리 Commit History만을 B Repo에 포함할 수 있는 방법을 설명한다

 

Case. old-repo / a-sdk → new-repo Repository 로 통합

 

old-repo는 a-sdk, b-sdk 및 sdk의 sample 까지 멀티 프로젝트 및 디렉토리를 포함하고있다.

이 중, a-sdk 만을 new-repo Reposity로 통합시킬 것이다.

 

1. srcDir, destDir을 각 Repo Clone

작업용 디렉토리를 생성하고 srcDir destDir을 각 Repo에서 파일을 Clone 한다

rm -rf ~/repo
mkdir ~/repo
cd ~/repo
srcrepo=old-repo
dstrepo=new-repo
git clone git@github.com:<User>/$dstrepo.git
git clone git@github.com:<User>/$srcrepo.git

 

2. srcDir 특정 디렉토리 분리

git filter-branch 옵션을 이용해 특정 디렉토리를 분리한다.
위 옵션은 지정한 디렉터리의 히스토리만 모아서 프로젝트 루트로 만들어 준다.

old-repo의 a-sdk을 루트로 만들어준다

cd ~/repo/$srcrepo git filter-branch --subdirectory-filter a-sdk -- --all

 

3. destDir에서 srcDir을 자신의 remote repo로 설정

desDir의 Remote에 srcDir을 추가하여 srcDir을 가져올 수 있도록 설정한다.

cd ~/repo/$dstrepo git remote add temp ../$srcrepo

 

4. srcDir Repo의 정보 가져오기

git fetch srcDir를 통해서 srcDir repo의 모든 정보를 가져온다.

2번 과정에서 srcDir의 루트를 a-sdk로 설정하였기에, a-sdk의 정보만 가져오게 된다.

git branch merge/a-sdk git checkout merge/a-sdk git fetch temp

 

5. 두 Repo 커밋 통함

git merge를 통해 두 리포간의 커밋을 섞는다. 단 커밋없이 진행하고, 실패된 커밋은 무시한다

a-sdk 정보만 가져왔기에 a-sdk의 커밋 정보만 merge 된다.

git merge --allow-unrelated-histories -s ours --no-commit temp/master

 

6. 원하는 디렉토리에 파일 읽어오기

git read-tree을 통해 원하는 디렉토리에 대해서 파일을 실제로 읽는다.

ex) srcDir에서 가져온 a-sdk 파일을 읽어 sdk / a-sdk 디렉토리에 위치시킨다.

git read-tree --prefix=sdk/a-sdk -u temp/master

 

7. 커밋

git commit 을 통해서 현재 부분 머지된 것을 커밋으로 만든다.

오직 a-sdk 커밋 히스토리만 머지된 것을 확인할 수 있다.

git commit -m "migration from $srcrepo" git remote rm temp

 

전체 코드

rm -rf ~/repo
mkdir ~/repo
cd ~/repo
srcrepo=old-repo
dstrepo=new-repo
git clone git@github.com:<User>/$dstrepo.git
git clone git@github.com:<User>/$srcrepo.git
cd ~/repo/$srcrepo
git filter-branch --subdirectory-filter a-sdk -- --all
cd ~/repo/$dstrepo
git remote add temp ../$srcrepo
git branch merge/a-sdk
git checkout merge/a-sdk
git fetch temp
git merge --allow-unrelated-histories -s ours --no-commit temp/master
git read-tree --prefix=sdk/a-sdk -u temp/master
git commit -m "migration from $srcrepo"
git remote rm temp

 

참고문헌

git filter-branch로 저장소 분리하기 - https://blog.outsider.ne.kr/1249

Merge a subdirectory of another repository with git - https://bneijt.nl/blog/post/merge-a-subdirectory-of-another-repository-with-git/

댓글