외부 종속성 관리: Git Submodule과 Subtree를 활용한 프로젝트 개발 및 관리 방법

최소희·2024년 5월 13일
0

프론트엔드 학습

목록 보기
14/16

💡 이 글은 Submodule과 Subtree를 활용하여, Firestore와 같은 외부 종속성의 코드를 안정적으로 관리하면서 프로젝트를 원활히 통합하는 방법에 대해서 소개합니다.

글 작성 배경

Firestore와 같은 외부 종속성의 코드를 클라이언트 내부 프로젝트에서 직접 수정하고 병합하는 것은 프로젝트의 안정성을 위협할 수 있습니다.

지난 2개월 간, Firestore로 API를 개발하여 2개의 클라이언트 레포지토리에 동시 사용할 수 있도록 Submodule과 Subtree를 관리해왔습니다.

이 경험을 토대로, 코드를 완전히 분리하여 외부 종속성의 코드를 안정적으로 유지하면서도 서로 다른 프로젝트들의 원활한 통합을 관리할 수 있는 SubmoduleSubtree에 대해 배우고, 상황에 따라 어떤 방법을 선택해야 하는지에 대해 이해를 돕고자 작성하게 되었습니다.

Submodule과 Subtree

Submodule과 Subtree는 외부 레포지토리를 현재 레포지토리에 포함시키는 방법입니다.

Submodule외부 레포지토리를 다른 디렉토리에 포함시키고, 외부 레포지토리의 변경 사항을 추적할 수 있습니다.

반면 Subtree외부 레포지토리를 현재 레포지토리의 하위 디렉토리로 포함시키는 구조입니다.

사실 이렇게만 읽었을 때는 이해가 어려울 수 있습니다.

저의 경험을 바탕으로 예시를 들겠습니다.

저는 Firebase의 Firestore를 사용하여 데이터베이스에 직접 접근하여 CRUD 작업을 수행하는 API를 A 레포지토리에서 개발하고 있습니다.

이 API는 아래의 구조처럼 앱을 개발하고 있는 B와 웹을 개발하고 있는 C 레포지토리에서 사용해야 합니다.

Submodule architecture

이때, B와 C 레포지토리가 A 코드로 개발한 API 기능을 가져오는 방법을 고려해야 했습니다.

외부 코드를 통합하는 방법은 다음의 경우들이 있을 것입니다.

  1. A(외부 코드)를 메인 레포지토리에 직접 복사하여 붙여 넣는다.
  2. NPM과 같은 언어 패키지 관리 시스템을 사용한다.

1번은 A(외부 코드)의 업스트림 변경 사항이 손실된다는 단점이 있습니다.

2번은 origin 코드가 배포되는 모든 곳에서 설치 및 버전 관리가 필요하다는 단점이 있습니다.

두 가지 통합 방법 모두 외부 레포지토리에 대한 편집 및 변경 사항을 추적할 수 없습니다.

그래서 외부 레포지토리의 변경 사항을 추적 및 업데이트할 수 있는 Git Submodule 방식을 사용하게 되었습니다.


그런데, 왜 Subtree가 아닌 Submodule을 선택했을까요?

차이점은 B와 C가 외부 코드(A)를 직접 수정하여 배포할 수 있는가 없는가에 있습니다.

Git Submodule은 다른 외부 레포지토리의 특정 커밋을 추적합니다.

또한, 자동으로 업데이트 되지 않습니다.

이는 서버 쪽에서도 안정화된 코드를 기반으로 클라이언트가 개발할 수 있도록 보장함과 동시에 서버쪽에서 자체 추가적인 개발을 할 수 있도록 해줍니다.

또한, Submodule을 사용하면 외부 코드를 가져와서 사용할 수 있지만, 내부적으로 외부 코드를 수정했을 때, 이 수정 내역이 외부 코드의 origin에 반영되지 않습니다.

즉, B와 C는 로컬에서는 수정할 수 있지만, 이 수정 사항이 A 레포지토리에 반영되지 않습니다.

반면에 Subtree를 사용한다면, B와 C는 A의 코드를 가져와서 수정한 사항을 A의 origin에 반영할 수 있습니다. 이는 B와 C가 A의 코드를 직접 수정하여 개선할 수 있는 유연성을 제공합니다.

더 자세한 이해를 돕기 위해 다음 실습을 준비해보았습니다.

Submodule, Subtree 두 기능 적용하기

실제 프로젝트에서 Submodule과 Subtree를 사용하여 Firestore와 같은 외부 종속성을 관리하는 방법에 대해 실습하고, 결과물을 확인해보겠습니다.

이를 통해 어떻게 외부 코드를 프로젝트에 통합하고 관리할 수 있는지에 대한 이해를 높일 수 있을 것입니다.

1. 프로젝트 구조 설정

  1. 클라이언트 프로젝트와 서버 프로젝트를 위한 각각의 디렉토리를 생성합니다.
  2. 각각의 디렉토리에서 git init 명령어를 실행하여 Git 레포지토리를 초기화합니다.
  3. 각각의 레포지토리에 간단한 예제 코드를 작성합니다.

2. Submodule 적용

  1. 클라이언트 프로젝트에 서버 프로젝트(lib_repository_url) 를 submodule로 추가합니다.

    git submodule add <lib_repository_url> <path>

    path: 클라이언트 프로젝트(내부 프로젝트) 내의 폴더 경로

    이 명령은 클라이언트 프로젝트에 서버 프로젝트를 path 경로에 서브모듈로 추가합니다.

  2. 아래 명령어로 submodule을 초기화 합니다.

    	git submodule update --init --recursive
  3. 클라이언트 프로젝트에서 서버 프로젝트 디렉토리를 확인합니다.

  4. 서버 프로젝트의 변경 사항을 추적하고 동기화하기 위해 서버 프로젝트 디렉토리로 이동하여 변경 사항을 커밋하고 푸시합니다.

  5. submodule의 변경 사항을 가져옵니다.

    • 특정 서브모듈 업데이트: git submodule update --remote <path>
    • 모든 서브모듈 업데이트: git submodule update --remote

    이 명령들은 submodule의 최신 변경 사항을 가져옵니다.

3. Subtree 적용

  1. 클라이언트 프로젝트에서 다음명령어를 사용하여 서버 프로젝트를 Subtree로 추가합니다.

    git subtree add --prefix=<path> <클라이언트 프로젝트 레포지토리 URL> master

    이 명령은 서버 레포지토리의 최신 변경 사항을 서버 프로젝트의 path subtree에 통합합니다.

  2. 클라이언트 프로젝트에서 서버 프로젝트 디렉토리를 확인합니다.

  3. 서브트리에 대한 변경 사항을 반영합니다.

    • 서브트리 내에서 작업 후 메인 프로젝트(클라이언트 프로젝트)에 푸시:
      통합된 서버 프로젝트에서 변경 사항을 커밋 및 이를 푸시합니다. 변경 사항은 클라이언트 프로젝트의 일부로 관리됩니다. (즉, 클라이언트 프로젝트가 변경된 서버 프로젝트와 함께 반영됨)
    • 서브트리 변경 사항을 외부 레포지토리(서버 프로젝트)에 푸시: subtree에서 변경한 사항을 외부 레포지토리에 푸시할 수 있습니다
      git subtree push --prefix=<path> <lib_repository_url> master

4. 결과 확인

  1. Submodule을 사용한 클라이언트 레포지토리
    • 서버 api에 접근하여 사용할 수 있습니다.
    • update를 통해 최신화된 서버 코드를 기반으로 동기화합니다.
  2. Subtree를 사용한 서버 레포지토리
    • 클라이언트 구조에서 현재 서버 코드가 제대로 동작하는 지 확인할 수 있습니다.
    • 클라이언트 구조에서 해당 서버 api의 버그를 확인하여 서버의 수정 사항을 반영할 수 있습니다.

마무리

저는 Node.js 환경에서 Firestore를 활용한 CRUD 메서드를 클래스 형태로 개발하고 있습니다. 이 메서드들은 클라이언트에서 사용하기 위해 tanstack-query(react-query) hook으로도 개발되었습니다. 이렇게 구현한 API를 클라이언트에 제공하기 위해 Submodule 형태로 관리하고 있습니다.

그러나 API의 기능을 테스트할 때, CRUD 메서드의 단위 테스트 뿐만 아니라 클라이언트 환경에서 query가 올바르게 동작하는지에 대한 테스트도 필요했습니다.
Subtree가 이 필요성을 해결해주었습니다. 서버 코드를 클라이언트 프로젝트에 통합하고 동시에 클라이언트 환경에서 서버 API를 개발하고 query를 테스트할 수 있었습니다.

이러한 경험을 통해, 프로젝트의 요구 사항에 따라 Submodule과 Subtree를 유연하게 활용하여 코드를 관리하고 협업하는 방법에 대해 배우게 되었습니다.

저와 비슷한 상황이신 분들도 제 글을 통해서 도움이 되셨으면 좋겠습니다!

참고 자료
https://www.atlassian.com/ko/git/tutorials/git-submodule
https://www.atlassian.com/ko/git/tutorials/git-subtree
https://git-scm.com/book/en/v2/Git-Tools-Submodules

profile
프론트엔드 개발자 👩🏻‍💻

0개의 댓글