UseModWiki소스수정을 CVS에서 Git를 사용하는 걸로 옮긴 것까진 어찌어찌 했는데... 막상 소스 수정할 때 적용하려니 너무 헷갈려서, 정리를 좀 해야겠음
-
- 1. CVS를 쓰던 당시
-
- 2. Git 에서
-
-
- 2.1. 저장소를 몇 개나 사용할 것인가
-
- 2.2. 대략 계획하길...
-
- 2.3. 이런 식으로 진행하면 되려나
-
3. 브랜치 트리 보기
-
- 4. Comments
-
1. CVS를 쓰던 당시
일단 CVS를 쓰던 당시 어떻게 했냐 하면... 아주 간단했다.
-
usemodkr
디렉토리 - 공개용 버전을 개발하는 디렉토리
-
wiki
디렉토리 - 이 GyparkWiki에 사용되는 디렉토리. 설정파일, 스타일쉬트, 매크로, wiki.pl 등이 수정됨
보통 다음과 같은 순서로 소스수정 작업을 함
-
usemodkr
디렉토리에서 작업한다.
- 잘 동작한다 싶으면 버전 올리고
CVS Repo
로 commit
- 이 시점에서 tarball로도 만들어서 wiki 디렉토리에 업로드
- tarball을 만드는 건 이 디렉토리에서 하지 않고, 임시 디렉토리를 만들고 거기에 Repo의 내용을 체크아웃한 후 다시 압축
-
wiki
디렉토리로 이동
- CVS Repo에 올라온 커밋을 update한다
wiki
쪽에서 update를 수행할 때, 대부분의 경우는 usemodkr
에서 고친 부분이 고스란히 wiki
에 있는 소스에도 반영이 되지만, 간혹 wiki
쪽에서 독자적으로 고친 부분과 충돌이 일어날 때가 있다.
- 스타일쉬트 등에 충돌이 발생하면 홈페이지 화면이 이상해지는 정도이지만, *.pl파일에 충돌이 발생하면 실행이 안 되므로 홈페이지에 접속하면 서버 에러가 난다.
- 재빨리 충돌을 해결하고 병합하지 못하면 장애가 오래 지속될 터라, update하기 전에 wiki.pl 파일을 백업해두었다가, 충돌이 일어나면 백업한 파일을 임시로 사용하고 충돌이 발생한 부분을 부랴부랴 수정한다.
이렇게 충돌이 발생하면, 아무리 짧은 시간이라 해도 서버 에러가 나는 등 영향을 받는 것이 제일 불만이었다.
wiki
로 바로 update하지 않고, wiki
와 동일한 상태로 수정이 되어 있는 디렉토리(wiki_test
라고 하자)를 하나 더 만들어서 거기에서 먼저 update하여 테스트한 후 이상이 없으면 그 때 wiki
에서 update하는 방법을 고려한 적이 있었는데 (오래전 일이라 잘 기억나지 않지만) 이 경우 다음 세 가지가 문제였다:
- 가끔 내 홈페이지에만 적용할 수정 사항이 추가되면, 이걸
wiki
와 wiki_test
에 동일하게 적용해야 하는데 이걸 CVS로 어떻게 해야 할 지 몰라서 수작업으로 하려니 힘들었다.
-
wiki_test
와 wiki
두 곳에 있는 소스가 완전히 동일하면 좋겠지만, 홈페이지주소간단히하기를 적용하자니 wiki
에 있는 소스는 반드시 "wiki"라는 이름의 디렉토리에 있을 때만 제대로 동작했다. 따라서 wiki_test
는 저 주소간단히하기 패치를 적용하지 않은 상태로 두어야 하므로 이 두 디렉토리의 소스가 또 서로 달라져야 했다.
- 결정적으로,
wiki_test
에서 update를 해서 충돌이 발생한다는 걸 알았다 해도, wiki
에서도 충돌이 발생할 것이라는 걸 미리 알 수 있을 뿐, wiki
에서 update할 때는 충돌이 발생하지 않고 곧바로 merge가 될 수 있게 하는 방법을 알 수 없었다. 기껏해야 수작업으로 충돌을 해결한 파일을 미리 만들어두었다가 wiki
에서 update한 후 재빨리 덮어쓰는 정도였는데, 두번째 이유 때문에 wiki_test
와 wiki
사이의 소스도 좀 달라야 했기 때문에 미리 wiki
에 덮어쓸 파일을 만드는 것도 은근히 손이 많이 가는 일이었음
CVS에도 브랜치란 개념이 있었으니 이걸 잘 쓰면 어떻게 일관성있게 통합할 수 있었을 것 같긴 한데, 굳이 그것까지 공부하고 싶지 않았었음.
2. Git 에서
이게 아주 오묘한데... 솔직히 말하면 Git 말고 Mercurial이 초반 습득 난이도가 낮고 명령어가 덜 많다는 얘기를 듣고는 그걸 익힐 걸 그랬나 하고 후회하는 중이다 -_-;; 뭐 막상 hg를 썼다면 Git가 기능이 정말 많다던데 그걸 쓸 걸 그랬나 하고 후회하고 있을지도. 암튼 내가 Git를 제대로 이해하고 있는지 자신이 없지만.
2.1. 저장소를 몇 개나 사용할 것인가
어쨌거나, 몇 개의 저장소를 유지할 지를 먼저 고민해봤는데,
-
wiki
하나만 사용하면서 공개용과 gyparkwiki용 브랜치를 각각 운영
- 브랜치를 바꿀 때마다 홈페이지가 엉망이 될 것임. 고려할 필요 없이 기각
-
usemodkr
에서 공개버전 작업, wiki
에서 gyparkwiki 버전 작업
- 처음에는 이것도 괜찮아보였다. usemodkr에서 작업한 master 브랜치를 wiki에서 pull하고, 여기에 gyparkwiki용 브랜치를 따로 두었다가 master의 수정 사항을 merge하면 되지 않을까 싶었던 것
- 그러나 차후에 gyparkwiki쪽에서만 뭔가를 수정할 경우 그걸 테스트할 공간이 없다는 것을 깨달음
-
usemodkr
에서 공개버전 작업. wiki_test
에서는 usemodkr의 변경을 pull한 후 gyparkwiki 버전 작업 및 테스트. wiki
에서 wiki_test의 변경을 pull하여 반영
- CVS에서 불편했던 점(gyparkwiki가 오작동하는 시점이 생긴다는 것)을 해결해 보려고 떠올린 건데, 해보지는 않았음
- 결국 pull이란 것도 일종의 merge이니까, 그럴거면 굳이 wiki_test 저장소를 따로 두느니 usemodkr 저장소 안에서 브랜치를 나누어 사용하는 거나 다를 바 없다는 생각이 들었음
- 또한 CVS에서처럼 wiki_test와 wiki저장소 사이에도 소스가 일부 달라져야 하기 때문에, wiki_test에서 wiki로 한번에 넘겨주기 위해서는 wiki_test쪽에서도 브랜치가 두 가지가 있어야 했다. (주소짧게하기 패치를 적용하지 않고 새 기능을 테스트하는 브랜치와, wiki와 동일한 소스를 유지하는 브랜치)
-
usemodkr
에서 공개버전, gyparkwiki 테스트, 최종 gyparkwiki 버전 전부를 브랜치로 나누어 작업하고, 최종 결과를 wiki
에서 pull해서 바로 적용
- 일단 이렇게 해 보기로.
- 걱정은 usemodkr에서 작업하던 걸 github로 보내다가 gyparkwiki 버전이나 다른 개발 버전까지 push하게 되는 사고가 나지 않을까 하는 건데, 한두번 해보니 지금처럼만 하면 그럴 일은 없을 듯
2.2. 대략 계획하길...
아래는 설 연휴 전후로 구상하고 PC에서 간단한 저장소를 만들어 테스트하면서 좌충우돌을 거쳐 나온 것들.
일단 이런 형태로 UseModKr
디렉토리를 저장소로 꾸몄다.
---A---B---C master
\
S mywiki
첫번째 희망
앞으로 소스를 수정해 나가더라도, 항상 위와 같이
공개용 master 브랜치 + 내 홈페이지용 수정 = mywiki 브랜치
형태를 유지했으면 좋겠다고 생각했음
- 소스 수정이 일단락되면 mywiki 브랜치를 위한 S를 master에 rebase
희망:
---A---B---C---D---E---F UseModKr/master
\
S' UseModKr/mywiki
- 그런데 실제로 해 보면 이렇게 하면 곤란하다. mywiki 브랜치를 pull하는 쪽에서는, 기존의 S와 새로 바뀐 S'가 다른 커밋이니까 히스토리에 두 번 들어가며 merge가 되어 버림
wiki 디렉토리 쪽에서 merge하면 이렇게 보인다:
---A---B---C---S---D---E---F---S' wiki/mywiki
^ ^
- S와 S'의 변경내역이 동일하기 때문에 소스가 크게 꼬이지는 않지만, history를 볼 때 아주 눈에 거슬린다. 포기.
차선책(물론, 희망사항)
새로 작업할 때마다 추가되는 커밋들을 rebase해서, 두 브랜치가 서로 병행해서 자라는 형태도 떠올려 보았음
- 원래는 이걸 피하려고 앞의 구성을 떠올린 거였지만...
피하고 싶었음:
---A---B---C---D---E---F master
\
S---D'--E'--F' mywiki
- 이 경우는 wiki디렉토리 쪽에서 pull했을 때 앞에서와 같이 커밋이 중복되는 문제도 없고, mywiki 브랜치의 히스토리가 선형으로 예쁘게 나오는 게 장점
- 그러나, 이렇게 브랜치를 구성하기 위해서는 계속 rebase를 반복해야 하는데 이 절차가 매우 귀찮다. 실제로는 이 두 브랜치 말고 두개의 브랜치가 더 필요한 터라, rebase가 세 번 이상 수행되어야 하고 네 개의 브랜치에 동일한 변경 내역(D,E,F)가 각각 네 개씩 서로 별개의 커밋으로 존재하게 된다.
- 히스토리를 선형으로 만들기 위해서 너무 많은 수고를 하는 것 같아서 결국 포기
별 수 없이
애초에 위와 같은 구성을 희망했던 이유가, Git의 merge란 게... CVS를 쓸 때처럼 단지 소스가 병합되는 것이 아니라, 서로 별개의 브랜치 상에 있는 커밋을 다시 한 곳에서 이어서 진행하는 형태로 구성되더라. (사실 내가 CVS를 제대로 알고 쓰던 게 아니라서 확신은 없다) 그래서 history를 보면 자꾸 갈라졌다 합쳐지는게, 내겐 아직 적응하기가 힘들다. 최대한 rebase 기능을 써서, 변경내역이 하나의 선으로 나타나게 하고 싶었던 것.
- merge 를 하면 이렇게 된다 (
O
가 merge를 나타내는 커밋)
정말 피하고 싶었음:
---A---B---C---D---E---F master
\ \
S-----------O mywiki
추가로 필요한 브랜치들
여기에 추가로, 신경써야 할 게 더 있었다.
추가하려는 기능이 특정 Perl 모듈이 필요한 경우가 있다. 나는 서버에 root권한이 없어서 내 홈 계정에 모듈을 설치해야 하는데, 이 경우 위키 소스에는 @INC
배열에 내 홈 계정 경로를 추가해서 모듈을 찾을 수 있게 해야 한다. 그러나 공개할 소스에는 그 부분이 들어 있으면 안 된다. 이렇게, 작업하는 동안에는 테스트를 위해서 수정되었다가, 최종 공개 시점에는 원상복구시켜놔야 하는 부분이 있다. 그래서 그 부분을 별도의 브랜치로 뽑았다.
I devel_base
/
---A---B---C master
\
S mywiki
게다가 앞에서도 적었지만, mywiki 브랜치 쪽에도 문제가 있는게... 홈페이지주소간단히하기를 적용해 놨더니만, 작업하던 디렉토리에서 mywiki 브랜치를 체크아웃한 후 테스트를 해 보려 했더니, 링크들이 죄다 wiki/ 디렉토리로 걸리는 바람에 링크만 클릭했다 하면 작업 디렉토리를 벗어나버린다. 따라서 주소간단히하기 적용을 일단 취소해놔야 한다. 즉 mywiki를 테스트하려 해도 선행작업이 필요하고, 테스트가 끝난 후 실제로 내 홈페이지에 적용하기 직전에 그 선행작업 부분을 다시 되돌려야 한다는 얘기.
I devel_base
/
---A---B---C master
\
S mywiki
\
W mywiki_test
테스트는 I와 W커밋에서 시작해야 하는데, 최종 결과는 그 두 커밋은 빠져야 하고 C와 S의 라인에서 바로 이어져야 한다...는게 상황을 아주 귀찮게 만들고 있다.
그럼 전에 CVS로는 이런 문제가 없었냐 하면... 그 때는 아예 방법을 몰라서 매번 손으로 I와 W에 해당하는 작업을 해주고, 테스트가 끝난 후 다시 찾아서 지워줬다 -_-;;; 그래서 사실, 버전업된 위키소스 tar.gz 파일을 공개한 후에야 그걸 지우지 않았다는 걸 깨닫고 부랴부랴 다시 고치고 압축해서 공개하고 한 적도 많음.
2.3. 이런 식으로 진행하면 되려나
그럼 실제로 소스수정할 때 어떤 식으로 할 지 순서를 적어보자. 이 문서를 작성하는 시점에서는 계속 간단한 저장소를 가지고 테스트만 해 봤고 실제로 위키소스를 수정하며 적용해보지는 못 했다.
1. UseModKr
저장소 - CVS에서 갓 넘어온 상태
-
I devel_base (공개버전 테스트에 필요한 로컬 수정)
/
---A---B---C master (공개될 버전)
\
S mywiki (내 홈페이지 버전)
\
W mywiki_test (내 홈페이지 테스트에 필요한 로컬 수정)
2. 새로운 기능을 추가 하기 위해서 devel_base에서 topic 브랜치 분기. 그냥 devel_base에서 고쳐도 되겠지만, 브랜치를 분기하면 하다가 아니다 싶으면 브랜치를 없애면 되니까 더 나을 듯.
$ git co -b topic devel_base
[ 작업하고 커밋하고 반복 ]
T1--T2 topic
/
I devel_base
/
---A---B---C master
\
S mywiki
\
W mywiki_test
3. 잘 된다 싶으면 master에 일단 합치자.
- 그냥 merge하면
I
가 끼어들어버리니까 곤란. 여기는 정말 rebase해야 함
$ git rebase --onto master devel_base topic
-
T1--T2 topic
/
| I devel_base
|/
---A---B---C master
\
S mywiki
\
W mywiki_test
4. devel_base의 경우는 외부에 push되는 일 없는 브랜치니까, 맘대로 rebase 가능. 다음 번에 새로운 기능을 추가할 때 간편하게 할 수 있도록, 지금 끝으로 빼두자.
(devel_base)$ git rebase topic
-
I devel_base
/
T1--T2 topic
/
---A---B---C master
\
S mywiki
\
W mywiki_test
5. 이제 master는 topic과 합친다.
(master)$ git merge topic1
-
I devel_base
/
---A---B---C--T1--T2 master, topic
\
S mywiki
\
W mywiki_test
- 이 시점에서 github에 push를 하거나, tarball을 만들어 배포할 수 있다. 즉 공개용 버전은 여기까지 하면 끝
6. 이제 gyparkwiki에 적용할 버전을 만들자. 이 디렉토리에서 테스트를 하려면 W
위에서 해야 하므로, merge한다.
$ git co mywiki_test
(mywiki_test)$ git merge master
-
I devel_base
/
---A---B---C--T1--T2 master, topic
\ \
S \ mywiki
\ \
W-------O mywiki_test
- 이 상태에서 브라우저를 새로고침하면, 동일한 URL인데 공개버전의 모습에서 내 홈페이지의 모습으로 싹 바뀐다. 이거 아주 재미있다 :-)
7. 별 문제가 없으면, 이제 S
에 master를 merge한다.
$ git co mywiki
(mywiki)$ git merge topic1
-
I devel_base
/
---A---B---C--T1--T2 master, topic
\ |\
S-----O \ mywiki
\ \
W-------O mywiki_test
- 물론 mywiki 브랜치는
wiki
디렉토리에서만 완전히 제대로 동작한다. (홈페이지주소간단히하기 적용 때문에) 따라서 mywiki_test와 달리 mywiki 브랜치는 이 상태에서 테스트를 하는 게 불편하다. 페이지 링크를 클릭하는 순간 현재 디렉토리를 빠져나가 wiki디렉토리 쪽으로 넘어가버리니 주의해야 함
- 그러나 적어도 topic을 merge할 때 충돌이 발생하면 이 시점에서 해결할 수 있다! wiki 디렉토리에는 충돌을 해결한 버전을 보낼 수 있으므로, CVS를 쓸 때와 같이 홈페이지가 갑자기 에러가 나거나 하는 일을 방지할 수 있다.
8. topic 브랜치는 이제 필요 없으니 지워도 되고, 기록을 위해 남기고 싶으면 남겨도 될 듯 (그러나 그런 용도라면 tag를 쓰는 게 나으려나)
$ git branch -d topic
9. 이제 wiki
디렉토리 쪽에서는 여기 있는 mywiki 브랜치를 가져간다.
$ cd ../wiki
(mywiki)$ git pull
- 홈페이지 소스 업데이트가 순식간에 이루어질 것이다. (물론 희망사항이지만, 딱히 문제가 될 부분이 없음)
10. 이후에 또 새로운 기능을 추가한다면 UseModKr
저장소의 모습은 아마도 다음과 같을 것이다.
-
I devel_base
/
---A---B---C--T1--T2--T3--T4 master, new_topic
\ |\ |\
S-----O-\-----O \ mywiki
\ \ \
W-------O-------O mywiki_test
10-1. 생각해보니 mywiki는 rebase를 하면 곤란하니 merge를 한다 치고, mywiki_test는 매번 저렇게 merge할 게 아니라, mywiki까지 작업이 끝난 후에 W 커밋만 뒤로 옮겨 붙여도 될 듯?
-
I devel_base
/
---A---B---C--T1--T2--T3--T4 master, new_topic
\ | |
S-----O-------O mywiki
\
W' mywiki_test
- 그런데 이렇게 하려면 뭔가 절차가 복잡해보이네... 일단 mywiki_test 포인터를 W까지 reset하고, 그 다음 다시 rebase해야 하려나.
(mywiki_base) $ git reset --hard W # 일단 W지점까지 롤백하고
(mywiki_base) $ git rebase mywiki # mywiki 뒤로 붙임
3. 브랜치 트리 보기
음, Git에서는 디렉토리를 묘사하는 오브젝트의 명칭이 tree라서, 여기서도 트리라고 말하면 혼동의 여지가 있겠지만, 달리 좋은 표현이 떠오르지 않네.
암튼, 현재 저장소에 있는 모든 브랜치의 내역을 전부 보고 싶으면
git log --pretty=oneline --all --graph --decorate
등으로 할 수는 있겠지만 아무래도 GUI 툴도 쓰게 된다.
그런데 msysgit에 같이 있는 gitk를
gitk --all
와 같이 실행하면... 어떻게든 브랜치들의 진행 라인을 왼쪽 컬럼부터 채워서 적으려고 하는지 자꾸 갈라졌던 브랜치들의 라인이 틈만 나면 왼쪽으로 다시 합쳐지려고 한다.
말로 설명하기 복잡하니 그림으로: 현재 위키소스수정을 하면서 매번 새로운 토픽 브랜치를 만들어 작업하고, 끝나면 master 브랜치에 합치는 식으로 하려고 노력하고 있다. 그러면 하다가 아니다 싶으면 브랜치를 바로 날려버리면 되니까. 그래서 브랜치가 9개일 때의 상황인데, gitk의 출력을 도저히 내가 알아보기 힘들어서 다시 엑셀에 정리를 좀 해 보았다. 엑셀에서는 한 컬럼이 하나의 브랜치고 아래에서 위쪽으로 진행이 되고 있고, 빨간 선은 브랜치가 새로 분기하는 거고 파란 점선은 merge이다.
암튼 gitk의 출력은 너무 알아보기 힘들어서, 다른 게 없나 싶어서 gitk 매뉴얼 페이지 마지막에 있는 다른 툴을 알아봤는데,
- [QGit] - 스크린샷 보면 알겠지만 좀 낫다. 하나의 브랜치는 최대한 직선으로 나타내준다. 문제는 2009년에 마지막 업데이트가 있었는데 현재 사용되지 않는 git repo-config 라는 명령을 호출하기 때문에 실행할 때마다 에러가 나고, 캐릭터셋 옵션을 읽지 못해서 한글이 깨져나온다. 옵션 들어가서 UTF-8로 바꿔주면 되는데 옵션 들어갈 때, 세팅 바꾸고 저장할 때마다 에러창이 자꾸 떠서 매우 귀찮다.
- [Gitview] - 파이썬 스크립트. 파이썬과 PyGTK가 설치되어 있어야 한다. 이유는 모르겠는데 실행해도 빈 화면만 뜨고 전혀 저장소 내용이 안 나와서 포기. 이것도 2009년이 마지막 버전이라 그런가.
- [tig] - 이건 리눅스 터미널 화면에서 쓰는 거라서, 윈도우에서 쓰려면 일단 소스 컴파일부터 난항. 반대로 홈페이지 작업을 하기 위한 서버에서 바로 볼 수 있겠다 싶어 서버에 설치는 했는데, 단축키가 너무 많다! 생긴 건 참 예쁘고 기능도 많아 보이긴 함
엑셀로 매번 정리하는 것도 화딱지 나는 일이라서 -_-; Perl 스크립트(GitFancygraph)를 만들어 git의 출력을 가지고 재배열하게 해보았다.
브랜치들 간의 커밋들의 진행관계를 나타내주는 [git-todo 플러그인]도 참고.
4. Comments
주인장분류 컴퓨터분류