git submodule 사용법
프로그래밍 2013. 4. 11. 10:54 |원문 링크 : http://chrisjean.com/2009/04/20/git-submodules-adding-using-removing-and-updating/
GIT을 사용한지도 한달이 조금 더 되었네요. 솔직히 말하면 GIT을 사용하면서 좋은 점도 많이 있었지만, 개인적으로 사용하면서 불만도 있었던거 같습니다.
특히 서브모듈은 문제가 되는것중 하나였구요. 서브모듈의 개념은 간단하지만, 서브모듈을 사용하여 실질적인 공동작업 하는 방법을 아는것도 하나의 '일'입니다. 서브모듈에 관한 내용이 대체적으로는 문서가 잘 되었지만, 완벽히는 아니기 때문에, 제가 알아낸 두세가지 어려운 팁들을 공유합니다~법
"GIT 저장소에서 서브모듈을 제거하고 업데이트 하기"
- 서브 모듈이란?
서브모듈의 컨셉은 훌륭합니다. 본질적으로 하나의 저장소가 또다른 저장소에 들어갈수 있다는 개념이죠. 이러한 서브모듈의 장점을 증명하기위해서, 제가 서브모듈을 어떻게 사용하는지 설명해보겠습니다~
저는 WordPress에서 themes 담당을 맞고 있습니다. 테마에 기능들을 향하는 개발을 맡고 있죠. 저는 이러한 향상된 기능을 가진 모듈을 개발하는데요, 그 모듈들은 각자의 폴더를 다 가지고 있어요. 이 코드들은 다른 테마에 쉽게 추가 될수도 있고, 혹은 업데이트가 될수도 있는데, 이러한 작업은 계속 이루어집니다.
각 테마든 각자의 GIT저장소에 저장이 됩니다. 그리고, 테마에 들어가는 모듈을 직접 테마 저장소에 넣지 않았구요, 모듈별로 따로 저장소를 만들어 두었구요. 간단하게 서브모듈로 모듈들을 테마에 넣었습니다.
예를들면, FlexxBold라는 테마가 있는데, FlexxBold에는 현재 7가지 서브모듈이 추가 되어 있죠 billboard, contact-page-plugin, featured-images, feedburner-widget- file-utility- flexx-layout-editor, and, tutorials. 제가 서브모듈을 사용하기때문에, 각각의 모듈 저장소에서 수동적으로 업데이트를 하는게 아니라, 한번에 pull을 할 수 있었습니다.
제가 위에서 말했듯이, GIT의 모든 작업이 쉬운것이 아닙니다!! 제가 여러분께 알려드릴 서브모듈의 4가지 기능을 소개합니다. (역주 : 왜 한말을 또 할까.. 중략합니다.) 아래를 보세요
GIT저장소에 서브모듈 추가하기
다행스럽게, GIT저장소에 서브모듈 추가하는 법은 쉽습니다. 예를 들어보죠, SampleTheme 저장소가 있고, billboard라는 모듈 저장소를 lib/bilboard 디렉토리에 추가한다고 가정해보죠. 그럼 아래와 같이 하면 됩니다.
[user@office SampleTheme]$ git submodule add git@mygithost:billboard lib/billboard
Initialized empty Git repository in ~/git_dev/SampleTheme/lib/billboard/.git/
remote: Counting objects: 1006, done.
remote: Compressing objects: 100% (978/978), done.
remote: Total 1006 (delta 631), reused 0 (delta 0)
Receiving objects: 100% (1006/1006), 408.22 KiB, done.
Resolving deltas: 100% (631/631), done.
위 예제에 3가지 파트를 자세히 살펴보죠
-> git submodule add - 단순히 GIT에게 서브모듈을 추가하는 명령어입니다. 이 구문은 항상 고정입니다
-> git@mygithost:billboard 서브모듈로 지정할 바깥저장소에 대한 정보입니다. 문법은 저장소에따라 달라질수 있구요. 그리고 저장소가 이 기능을 지원하는지 확인해봐야됩니다.
-> lib/billboard - 서브모듈 저장소에 추가될 경로를 지정하는것입니다.
그럼 저장소에서는 어떻게 하고 있는지 체크해보죠.
[user@office SampleTheme]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: .gitmodules
# new file: lib/billboard
#
아까 넣은 경로가 생성되었고, 커밋할 부분이 추가 되었습니다. 또, .gitmodules 라는 파일이 추가 되었구요. 이 파일이 서브모듈에 대한 정보를 담고 있습니다. 자 이제 이 파일을 한번 보죠.
[user@office SampleTheme]$ cat .gitmodules
[submodule "lib/billboard"]
path = lib/billboard
url = git@mygithost:billboard
나중에 이 파일을 수정할 수 있다는점 기억하세요.
이제 남은거는 변경된 사항을 commit하시고 remote 저장소에 push하는거네요~
서브모듈 사용하기
저장소에 서브모듈을 추가하는것은 좋은 일이지만, 제 저장소를 보면, 폴더를 보면 실제 내용은 없는 빈 폴더네요. 외부 저장소로부터 서브모듈을 채우려면, 먼저 초기화를 하시고 다음에 update를 해야됩니다.
참고 : 위 내용은 GIT의 최신버전에는 적용되지 않습니다. 지금은 그냥 add하면 복사가 됩니다. 참고로 서브모듈 저장소에 또다른 서브모듈이 있는경우, 서브모듈의 서브모듈은 서브모듈 디렉토리에서 다음과 같은 정차를 진행해야됩니다. (해깔리시죠?)
만약에 phone-app 프로젝트 작업을 한다고 가정하고, graphics-lib라는 서브모듈을을 추가하고, render라는 graphics-lib의 서브모듈을 추가 하고 싶으면, graphics-lib를 먼저 add하세요, 그러면 phone-app/graphic-lib 는 복사가 되어 있을겁니다. 그런데 phone-app/graphic-lib/renderer는 역시 비어있을것입니다. phone-app/graphics-lib/renderer폴더를 복사되게 하고싶으시면, phone-app/graphics-lib 디렉토리로 이동하시고, 아래대로 하시면 됩니다. ^^
첫번째, 서브모듈을 초기화합니다. 아래처럼 하세요.
[user@office SampleTheme]$ git submodule init
Submodule 'lib/billboard' (git@mygithost:billboard) registered for path 'lib/billboard'
그다음, update 명령어를 이용해서 파일들을 불러옵니다.
[user@office SampleTheme]$ git submodule update
Initialized empty Git repository in ~/git_dev/SampleTheme/lib/billboard/.git/
remote: Counting objects: 26, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 26 (delta 5), reused 0 (delta 0)
Receiving objects: 100% (26/26), 17.37 KiB, done.
Resolving deltas: 100% (5/5), done.
Submodule path 'lib/billboard': checked out '1c407cb2315z0847facb57d79d680f88ca004332'
이제 lib/billboard 디렉토리를 보시면, 파일들이 채워져 있는것을 보실수 있게 될겁니다!
서브모듈 제거하기
서브모듈을 제거해야 한다면 어떻게 하실건가요? 서브모듈에 치명적인 코드가 담겨서, 전체적으로 복구 할수가 없고 새로 서브모듈을 만들어야 한다면 어떻게 하시겠습니다. 걱정마세요!! (역주 : 무슨 광고 같네요 ) 그냥 "git submodule rm [submodule path]" 를 치시면 됩니다. 그게 다입니다. 진짜라니깐요.
[user@office SampleTheme]$ git submodule rm lib/billboard
error: pathspec 'rm' did not match any file(s) known to git.
Did you forget to 'git add'?
b8ff8f68eb56938b9b4bf993619218fa848c5848 lib/billboard (1.2.25)
불행히도, 위의 명령은 틀렸네요. (역주 : 얘가 장난친거네요) GIT에는 내장된 서브모듈을 제거하는 명령이 없습니다. 하지만 걱정마세요. 제가 서브모듈을 수동으로 제거하는 방법을 알려드릴테니깐요.
SampleTheme에 lib/billboard 서브모듈을 제거한다고 가정하겠습니다. 모든 명령어는 SampleTheme저장소 디렉토리에서 실행 될것이구요. 그러기 위해 할 일이 있습니다.
1. 서브모듈의 entry파일인 .gitmodules 파일을 제거하세요. lib/billboard 서브모듈이 저장소에 유일한 서브모듈이기때문에, 그냥 간단히 git rm lib/billboard 하면됩니다. 근데, lib/billboard말고 다른 서브모듈이 또 존재하면, .gitsubmodules file을 제거 하시면 안되고, 수동으로 고쳐야됩니다. vi혹은 좋아하는 에디터로 파일 여시고요, 제거할 모듈 내용이 담긴 세줄을 지워주세요. 이경우애는 아래 내용을 지우면 되겠네요.
[submodule "lib/billboard"]
path = lib/billboard
url = git@mygithost:billboard
2. .git/config의 서브모듈 관련 애용도 지워야됩니다. 엄격히 말하면 이거 안하셔도 상관없는데, 저장소를 깔끔하게 유지하고싶고, 미래에 닥칠 문제(?)에 대비하고 싶으시면 하시는게 좋습니다. .git/config의 서브모듈관련 entry는 "git submodule init"을 했을때만 들어간다는거 참고하시구요. 없으면 무시하셔도 됩니다. 아까의 예제에서는 아래 라인들을 지우면 되겠군요.
[submodule "billboard"]
url = git@mygithost:billboard
3. 마지막으로 서브모듈에서 만들어졌던 디렉토리를 제거하시면됩니다. 쉽죠. 그냥 "git rm -cached [plugin path]" 하시면 되구요. 예제의 경우에는 "git rm -cached lib/billboard" 하면 되겠네요. 아시겠지만, 마지막 슬레시는 꼭 빼주셔야됩니다. 예제의 경우에서 "git rm -cached lib/billboard/" 라고 치시면 "fatal: pathspec 'lib/billboard/' did not match any files" 라는 에러메시지가 나올겁니다.
[user@office SampleTheme]$ git rm --cached lib/billboard
rm 'lib/billboard'
서브모듈 업데이트 하기
저장소에서 처음에 서브모듈 했을 당시에, 완벽히 구현안되었던 것들이 있을수도 있습니다. 서브모듈을 추가하면, 서브모듈을 가장 최근 commit이 main 저장소의 index에 저장됩니다. 이 의미는, 서브모듈의 저장소가 업데이트되면, 새로운 코드역시 서브모듈 저장소에서 pull 될것입니다.
테스트 할때나, 검수 넣을때 조심해야됩니다. 서브모듈이 업데이트 되면, 메인 저장소 코드랑 호환이 안될수도 있다는거 잊지마세요.
서브모듈 제거와 마찬가지로 불행하게도, git은 나중 commit에 대한 뚜렷한 대책을 세워놓지 않았습니다. 다행히, 그 대책이 어려운건 아닙니다.
1. 서브모듈을 "git submodule init"으로 초기화 합니다. 그 다음 "git submodule update"를 합니다.
[user@office SampleTheme]$ git submodule init
Submodule 'lib/billboard' (git@mygithost:billboard) registered for path 'lib/billboard'
[user@office SampleTheme]$ git submodule update
Initialized empty Git repository in ~/git_dev/SampleTheme/lib/billboard/.git/
remote: Counting objects: 26, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 26 (delta 5), reused 0 (delta 0)
Receiving objects: 100% (26/26), 17.37 KiB, done.
Resolving deltas: 100% (5/5), done.
Submodule path 'lib/billboard': checked out '1c407cb2315z0847facb57d79d680f88ca004332'
2. 서브모듈 디렉토리로 이동합니다. 이경우에는 "cd lib/billboard"하면 되겠군요.
[user@office SampleTheme]$ cd lib/billboard
[user@office SampleTheme/lib/billboard]$
3. "git submodule update"로 추가된 서브모듈의 저장소들은 "headless" 상태입니다. 무슨말이냐면요. 현재 branch에 존재하지 않는다는 거죠. 이걸 고칠려면, branch switch를 써야됩니다. 이경우에는, "git checkout master"라고 입력합니다.
[user@office SampleTheme/lib/billboard]$ git status
# Not currently on any branch.
nothing to commit (working directory clean)
[user@office SampleTheme/lib/billboard]$ git checkout master
Previous HEAD position was b8ff8f6... re-ordering
Switched to branch 'master'
Your branch is behind 'origin/master' by 8 commits, and can be fast-forwarded.
[user@office SampleTheme/lib/billboard]$ git status
# On branch master
# Your branch is behind 'origin/master' by 8 commits, and can be fast-forwarded.
#
nothing to commit (working directory clean)
4. 다음에는 그냥 저장소를 최신상태로 update하면됩니다. 그냥 "git pull"하면 됩니다.
[user@office SampleTheme/lib/billboard]$ git pull
remote: Counting objects: 31, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 24 (delta 15), reused 0 (delta 0)
Unpacking objects: 100% (24/24), done.
From mygithost:billboard
b8ff8f6..5cab93f master -> origin/master
* [new tag] 1.2.28 -> 1.2.28
From mygithost:billboard
* [new tag] 1.2.26 -> 1.2.26
* [new tag] 1.2.27 -> 1.2.27
Updating c547e0d..5cab93f
Fast-forward
billboard.php | 109 ++++++++++++++-
classes/view_gettingstarted.php | 107 ++++++++++++++
classes/view_gettingstarted_content.php | 38 +++++
css/admin.css | 26 ++++
history.txt | 22 +++-
js/admin.js | 17 +++
lib/updater/get.php | 94 +++++++-----
lib/updater/history.txt | 9 ++
lib/updater/updater.php | 241 ++++++++++++++++++-------------
9 files changed, 519 insertions(+), 144 deletions(-)
create mode 100644 classes/view_gettingstarted.php
create mode 100644 classes/view_gettingstarted_content.php
create mode 100644 css/admin.css
create mode 100644 js/admin.js
create mode 100644 lib/updater/history.txt
5. 그리고 저장소의 root 디렉토리로 돌아가시면 됩니다. 예제의 경우에는 "cd ../.." 하면 되겠네요.
[user@office SampleTheme/lib/billboard]$ cd ../..
[user@office SampleTheme]$
6. commit하고 push할 모든 준비가 끝났습니다. (push할 게 있고, remote 저장소가 있다면) "git status"를 입력하시면, 서브모듈의 경로가 수정되었다고 표시되는게 보일겁니다. 이게 우리가 바라던 바죠. 간단하게 경로를 add하고 commit합니다. commit하시면, 서브모듈의 commit 메시지가 update된게 나올것입니다.
[user@office SampleTheme]$ git status
# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: lib/billboard (new commits)
#
no changes added to commit (use "git add" and/or "git commit -a")
[user@office SampleTheme]$ git add lib/billboard
[user@office SampleTheme]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# modified: lib/billboard
#
마치면서...
짧은 시간이지만 Git에 대해 많이 배운거같습니다. Git사용하는것에 대한 더 자세한 내용을 보길 기대합니다. 이거 포스팅하는데 엄청난 시행착오를 겪었거든요. 그리고 제가 이 내용들을 자동화하는데 필요한 스크립트를 개발했고, 여러분들과 공유하고 싶네요.
수정할 내용이 있거나, 한수 가르쳐주실분은 덧글 남겨주시거나 여기로 (http://chrisjean.com/contact/) 연락주세요. ^^ 감사합니다.
'프로그래밍' 카테고리의 다른 글
unkown mozilla path MOZILLA_FIVE_HPME not set결 (0) | 2013.04.22 |
---|---|
svn external link 설정방법 (0) | 2013.04.19 |
Bresenham 선 그리기 알고리즘 (0) | 2013.04.10 |
NDK CallStack (0) | 2012.11.15 |
parallel make (0) | 2012.11.15 |