Summary

두 개의 프로젝트를 하나의 monorepo로 통합하고, 각 프로젝트의 git 이력을 모두 보존하면서 합치는 방법을 제시 합니다. 이 작업을 수행하려면 git의 subtree 혹은 submodule 기능을 사용할 수 있지만, 일반적으로 이력 병합과 유지의 목적으로는 subtree 방법이 더 많이 사용됩니다. 아래에 subtree를 이용해 이력을 유지하면서 두 개의 git 저장소를 하나의 monorepo로 합치는 방법을 설명합니다.

monorepo 설정 방법

1. 새로운 Monorepo 생성

먼저 새로운 monorepo를 위한 빈 저장소를 생성합니다.

mkdir monorepo 
cd monorepo 
git init
# monorepo에서 `HEAD` 참조 오류를 방지하기 위해 빈 초기 커밋을 생성합니다.
git commit --allow-empty -m "Initial commit for monorepo

2. 기존 프로젝트를 Subtree로 추가하기

이제 두 개의 기존 프로젝트를 subtree로 추가하여 각각의 git 이력을 보존할 수 있습니다. 다음의 예시에서는 두 개의 프로젝트가 project-Aproject-B라는 이름을 가지고 있다고 가정합니다.

Note

순서를 지켜야 합니다.

2.1 프로젝트 A 추가

  1. 먼저 프로젝트 A의 원격 저장소를 추가합니다.
git remote add projectA <프로젝트_A_저장소_URL>
  1. projectA의 모든 브랜치와 태그를 가져옵니다.
git fetch projectA main
  1. 프로젝트 A를 monorepo의 하위 디렉토리로 추가합니다. 이 때 이력을 유지하면서 project-A 폴더에 추가됩니다.
git merge -s ours --allow-unrelated-histories --no-commit projectA/main
git read-tree --prefix=project-A/ -u projectA/main
git commit -m "Add project A as subtree"

위 명령어는 projectA의 이력을 보존하면서 project-A라는 하위 디렉토리에 프로젝트를 통합합니다.

2.2 프로젝트 B 추가

프로젝트 B도 비슷한 절차로 추가합니다.

  1. 프로젝트 B의 원격 저장소를 추가합니다.
git remote add projectB <프로젝트_B_저장소_URL>
  1. projectB의 모든 브랜치와 태그를 가져옵니다.
git fetch projectB
  1. 프로젝트 B를 monorepo의 하위 디렉토리로 추가합니다.
git merge -s ours --allow-unrelated-histories --no-commit projectB/main
git read-tree --prefix=project-B/ -u projectB/main
git commit -m "Add project B as subtree"

3. Git 이력 확인하기

이제 git log를 실행하여 두 개의 프로젝트의 이력이 보존된 것을 확인할 수 있습니다. project-Aproject-B 각각의 폴더에 대한 이력들이 모두 유지되어 합쳐진 것을 확인할 수 있습니다.

참고사항

이 작업을 할 때 --allow-unrelated-histories 플래그를 사용하면 두 저장소의 서로 다른 이력을 합칠 수 있습니다. 이 플래그는 서로 무관한 두 히스토리를 병합할 때 필수적입니다. 또한, subtree 방식은 이력을 보존하면서 두 프로젝트를 통합할 수 있어 기존 히스토리를 유지하는 데 매우 유용합니다.

이렇게 하면 기존 프로젝트 각각의 이력을 모두 유지하면서 하나의 monorepo로 통합하여 관리할 수 있습니다.

monorepo 사용법

subtree 방식을 사용하여 프로젝트를 통합한 이후, 특정 프로젝트(project-A)의 이력만 보고 싶다면 디렉토리에 진입하지 않아도 Git 명령어를 사용하여 쉽게 이력을 필터링할 수 있습니다. 즉, 특정 디렉토리 (project-A/)에 대한 변경 사항만 추적하여 해당 프로젝트의 이력을 확인할 수 있습니다.

1. 이력관리

1.1 특정 디렉토리 이력 확인하기 (project-A)

git log 명령어를 사용하면서 -- <directory> 옵션을 추가하면 해당 디렉토리와 관련된 커밋만을 필터링해서 확인할 수 있습니다.

git log -- project-A/

이 명령은 project-A/ 디렉토리의 파일과 관련된 변경 사항만 포함한 커밋들을 보여줍니다. 즉, project-A의 이력을 분리해서 볼 수 있는 것입니다.

1.2 이력 확인 시 다양한 옵션 사용하기

git log에는 다양한 옵션을 조합할 수 있기 때문에 원하는 형태로 프로젝트의 이력을 쉽게 볼 수 있습니다. 예를 들어:

1.3 디렉토리 이동 후 git log 확인

물론, project-A/ 디렉토리로 이동한 후에 git log를 실행해도 동일하게 해당 디렉토리와 관련된 이력만 확인할 수 있습니다.

cd project-A/ git log

이 방식은 project-A 디렉토리에 있는 상태에서 직접적으로 이력을 보고 싶을 때 유용합니다. 하지만 디렉토리에 진입하지 않고도 -- <directory> 옵션을 사용하면 전역적인 관점에서 project-A의 이력만 볼 수 있어서 더 편리할 때가 많습니다.

요약

이렇게 하면 subtree로 통합된 상태에서도 각각의 프로젝트 이력을 간편하게 조회할 수 있습니다.

subtree로 구성된 project-A에 대한 작업을 할 경우, 커밋을 어디서 진행하든 상관없이 최종적으로 monorepo의 이력에 통합됩니다. subtree 방식으로 프로젝트를 합친 후에는 monorepo의 모든 디렉토리와 파일이 하나의 Git 저장소로 관리되기 때문에, 커밋 위치에 따라 이력 관리 방식이 달라지지는 않습니다. 구체적으로 설명드리면 다음과 같습니다.

2. 커밋 관리

2.1 Monorepo의 최상위에서 Commit 하는 경우

2.2 project-A 디렉토리에서 직접 Commit 하는 경우

3. 기타 관리 팁

3.1 중요한 점: 통합된 저장소로서의 관리

3.2 참고: 커밋 메시지와 컨벤션