Close

Git submodules

Git 하위 모듈을 사용하면 Git 리포지토리를 다른 Git 리포지토리의 하위 디렉터리로 유지할 수 있습니다. Git 하위 모듈은 특정 시점의 스냅샷에서 다른 리포지토리에 대한 참조입니다. Git 하위 모듈을 통해 Git 리포지토리에서 외부 코드의 버전 기록을 통합하고 추적할 수 있습니다.


git 하위 모듈이란 무엇입니까?


코드 리포지토리는 외부 코드에 의존하는 경우가 많습니다. 외부 코드는 몇 가지 다른 방법으로 통합될 수 있습니다. 외부 코드는 메인 리포지토리에 직접 복사하여 붙여넣을 수 있습니다. 이 방법은 외부 리포지토리의 업스트림 변경 사항이 손실된다는 단점이 있습니다. 외부 코드를 통합하는 또다른 방법은 Ruby Gems 또는 NPM과 같은 언어 패키지 관리 시스템을 사용하는 것입니다. 이 방법은 origin 코드가 배포되는 모든 곳에서 설치 및 버전 관리가 필요하다는 단점이 있습니다. 두 가지 통합 방법 모두 외부 리포지토리에 대한 편집 및 변경 사항을 추적할 수 없습니다.

git 하위 모듈은 다른 외부 리포지토리의 특정 커밋을 가리키는 호스트 git 리포지토리 내의 레코드입니다. 하위 모듈은 매우 정적이며 특정 커밋만 추적합니다. 하위 모듈은 git ref 또는 브랜치를 추적하지 않으며 호스트 리포지토리가 업데이트될 때 자동으로 업데이트되지 않습니다. 리포지토리에 하위 모듈을 추가하면 새 .gitmodules 파일이 만들어집니다. .gitmodules 파일에는 하위 모듈 프로젝트의 URL과 로컬 디렉터리 간의 매핑에 대한 메타데이터가 들어 있습니다. 호스트 리포지토리에 여러 개의 하위 모듈이 있는 경우 .gitmodules 파일에는 각 하위 모듈에 대한 항목이 있습니다.

git 하위 모듈은 언제 사용해야 합니까?


외부 종속성에 대해 엄격한 버전 관리를 유지해야 하는 경우 git 하위 모듈을 사용하는 것이 좋습니다. git 하위 모듈에 대한 몇 가지 가장 좋은 사용 사례는 다음과 같습니다.

  • 외부 구성 요소 또는 하위 프로젝트가 너무 빠르게 변경되거나 예정된 변경으로 인해 API가 중단되는 경우 안전을 위해 코드를 특정 커밋에 잠글 수 있습니다.
  • 자주 업데이트되지 않는 구성 요소가 있고 공급업체 종속성으로 추적하려는 경우입니다.
  • 프로젝트의 일부를 제3자에게 위임하고 특정 시간이나 릴리스에 작업을 통합하려는 경우입니다. 다시 한 번 강조하자면 업데이트가 너무 빈번하지 않을 때 효과적입니다.
데이터베이스
관련 자료

전체 Git 리포지토리를 이동하는 방법

Bitbucket 로고
솔루션 보기

Bitbucket Cloud에서 Git에 대해 알아보기

git 하위 모듈의 일반적인 명령


git 하위 모듈 추가

git submodule add는 기존 리포지토리에 새 하위 모듈을 추가하는 데 사용됩니다. 다음은 빈 리포지토리를 만들고 Git 하위 모듈을 탐색하는 예시입니다.

$ mkdir git-submodule-demo
$ cd git-submodule-demo/
$ git init
Initialized empty Git repository in /Users/atlassian/git-submodule-demo/.git/

이 명령 시퀀스는 git-submodule-demo라는 새 디렉터리를 만들고 해당 디렉터리로 들어가서 새 리포지토리로 초기화합니다. 그 다음으로 새로운 리포지토리에 하위 모듈을 추가합니다.

$ git submodule add https://bitbucket.org/jaredw/awesomelibrary
Cloning into '/Users/atlassian/git-submodule-demo/awesomelibrary'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.

git submodule add 명령은 Git 리포지토리를 가리키는 URL 매개 변수를 사용합니다. 여기서는 하위 모듈로 awesomelibrary를 추가했습니다. Git은 즉시 하위 모듈을 복제합니다. 이제 git status를 사용하여 리포지토리의 현재 상태를 검토할 수 있습니다.

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

new file:   .gitmodules
new file:   awesomelibrary

이제 리포지토리에 두 개의 새 파일인 .gitmodulesawesomelibrary 디렉터리가 생겼습니다. .gitmodules의 콘텐츠를 보면 새 하위 모듈 매핑이 표시됩니다

[submodule "awesomelibrary"]
path = awesomelibrary
url = https://bitbucket.org/jaredw/awesomelibrary
$ git add .gitmodules awesomelibrary/
$ git commit -m "added submodule"
[main (root-commit) d5002d0] added submodule
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 awesomelibrary

git 하위 모듈 복제

git clone /url/to/repo/with/submodules
git submodule init
git submodule update

git 하위 모듈 초기화

git submodule init의 기본 동작은 .gitmodules 파일의 매핑을 로컬 ./.git/config 파일에 복사하는 것입니다. 이것은 불필요한 것처럼 보일 수 있으며 git submodule init의 유용성에 대해 의문이 들 수 있습니다. git submodule init에는 명시적인 모듈 이름 목록을 허용하는 확장 동작이 있습니다. 이를 통해 리포지토리 작업에 필요한 특정 하위 모듈만 활성화하는 워크플로가 가능합니다. 리포지토리에 많은 하위 모듈이 있지만 수행 중인 작업을 위해 모두 가져올 필요는 없는 경우에 유용합니다.

하위 모듈 워크플로

상위 리포지토리 내에서 하위 모듈이 제대로 초기화되고 업데이트되면 독립 실행형 리포지토리처럼 활용할 수 있습니다. 하위 모듈마다 브랜치와 기록이 있다는 것을 의미합니다. 하위 모듈을 변경할 때는 하위 모듈의 변경 사항을 게시하고 하위 모듈에 대한 상위 리포지토리 참조를 업데이트하는 것이 중요합니다. awesomelibrary 예시로 계속하여 몇 가지 사항을 변경해 보겠습니다.

$ cd awesomelibrary/
$ git checkout -b new_awesome
Switched to a new branch 'new_awesome'
$ echo "new awesome file" > new_awesome.txt
$ git status
On branch new_awesome
Untracked files:
  (use "git add <file>..." to include in what will be committed)

new_awesome.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add new_awesome.txt
$ git commit -m "added new awesome textfile"
[new_awesome 0567ce8] added new awesome textfile
 1 file changed, 1 insertion(+)
 create mode 100644 new_awesome.txt
$ git branch
  main
* new_awesome

여기에서는 디렉터리를 awesomelibrary 하위 모듈로 변경했습니다. 일부 콘텐츠가 포함된 새로운 new_awesome.txt 텍스트 파일을 만들었으며 이 새 파일을 하위 모듈에 추가하고 커밋했습니다. 이제 디렉터리를 다시 상위 리포지토리로 변경하고 상위 리포지토리의 현재 상태를 살펴보겠습니다.

$ cd ..
$ git status
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

modified:   awesomelibrary (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

git status를 실행하면 상위 리포지토리가 awesomelibrary 하위 모듈에 대한 새 커밋을 인식하고 있음을 알 수 있습니다. 특정 업데이트에 대해 자세히 설명하는 것은 하위 모듈 리포지토리의 책임이므로 상위 리포지토리에서는 이루어지지 않습니다. 상위 리포지토리는 하위 모듈을 커밋에 고정하는 것과만 관련이 있습니다. 이제 하위 모듈에서 git addgit commit을 수행하여 상위 리포지토리를 다시 업데이트할 수 있습니다. 그러면 모든 것이 로컬 콘텐츠와 함께 양호한 상태가 됩니다. 팀 환경에서 작업하는 경우 하위 모듈 업데이트와 상위 리포지토리 업데이트를 git push하는 것이 중요합니다.

하위 모듈에서 작업할 때 흔히 발생하는 혼란과 실수의 패턴은 원격 사용자에 대한 업데이트 푸시를 잊어버리는 것입니다. 방금 수행한 awesomelibrary 작업으로 돌아가 보면 업데이트를 상위 리포지토리에만 푸시했습니다. 다른 개발자가 최근 상위 리포지토리를 풀하려는 경우, 우리가 하위 모듈을 푸시하는 것을 잊었기 때문에 리포지토리는 개발자가 풀할 수 없는 awesomelibrary의 커밋을 가리키고 있을 것입니다. 그러면 원격 개발자의 로컬 리포지토리가 손상될 것입니다. 이러한 실패 시나리오를 방지하려면 항상 하위 모듈과 상위 리포지토리를 커밋하고 푸시해야 합니다.

결론


Git 하위 모듈은 Git을 외부 종속성 관리 도구로 활용하는 효과적인 방법입니다. Git 하위 모듈은 고급 기능이며 팀원이 채택하는 데 학습 곡선을 거쳐야 할 수 있으므로 사용하기 전에 장단점을 비교해 보세요.


이 문서 공유

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

도구로 가득한 벽을 사용하여 협업하는 사람들

Bitbucket 블로그

DevOps 일러스트레이션

DevOps 학습 경로

Atlassian 전문가와 함께 하는 Demo Den 기능 데모

Bitbucket Cloud가 Atlassian Open DevOps와 작동하는 방법

DevOps 뉴스레터 신청

Thank you for signing up