GIT 은 소스 레파지토리 시스템인데 그 중에 특별히 '분산' 개념이 들어가 있습니다. 다른 레파지토리랑 (
cvs, svn) 비교를 많이 하지만 '분산' 이라는 점에서 많은 차별점이 있습니다. 원래 태어날 때도 여타 소스 레파지토리에 '분산' 기능이 없기 때문에 태어났기도 합니다.
조금 쉽게 이해를 하자면,
GIT 은 기본적으로 제 Local 에 레파지토리를 가지고 있는 방식이라고 볼 수
있습니다. 즉 중앙 개념이 희박합니다. Local 에서 리비젼 관리가 완벽하게 이루어 집니다. Remote (원격) 개념은 공동 작업을 할 때 필요하다고 보면 될 것입니다. 결국 push / pull 은 원격에만 관여하는 것이고 나머지 기능들은 Local 에서 소스 관리하는 기능이라고 보시면 됩니다. (자질 구레한 것은 따지지 말기로 하죠 ㅎㅎ)
그렇다면 가장 헷갈리기도 하고 잘 쓰기가 어려운 merge / branch 개념을 git 에서는 필수적으로 사용할 줄 알아야 하는데 그 내용을 살펴보기로 하겠습니다.
시나리오
1. 웹 사이트에서 일을 하는 중
2. 새로운 스토리에 맞춰서 브랜치를 생성함
3. 위에서 생성한 브랜치에 무엇인가 작업을 하는중
이슈가 발생하고 핫픽스를 (hotfix) 해야 합니다. 이는 다음과 같은 절차로 할 수가 있습니다.
1. 운영 브랜치로 바꾸고
2. 핫픽스를 추가할 브랜치를 생성합니다.
3. 핫픽스가 테스트 됐다면, 핫픽스 를 머지(merge) 하고, 운영 브랜치로 밀어넣습니다. (push)
4. 원래 하던 작업으로 돌아가서 계속 일을 합니다.
커밋이 세번 일어난 브랜치라고 가정합니다. 세번째 커밋을 master 가 가르키고 있는것에 주목합니다. 이 때 이슈가 발생했습니다. 이슈를 처리하기 위해서 브랜치를 만듭니다.
$ git checkout -b iss53
Switched to a new branch "iss53"
iss53 으로 브랜치를 만듭니다. 이 명령은 실은 두가지 명령이 하나로 합쳐진 것입니다.
$ git branch iss53
$ git checkout iss53
이렇게 하는 것이지만 귀찮으니 축약 버젼을 쓰기로 합니다.
iss53 브랜치가 생성 됐기 때문에 2개의 브랜치가 공존하는 형태가 됩니다. C/C++ 언어의 포인터 개념과 비슷하군요
그리고 그 브랜치에서 무엇인가 작업을 하고 커밋을 합니다. 가령 예를 들자면
$ emacs index.html
$ git commit -a -m 'added a new footer [issue 53]'
이런식으로 (원문의 vim 을 emacs 로 바꿨습니다.)
이제 이 와 같이 브랜치의 모습이 바꼈을 것입니다. 이제 작업한 내용을 합쳐야 합니다. 다시 master 브랜치로 바꾸어 줍니다.
$ git checkout master
Switched to branch "master"
이제 핫픽스 해줘야 하는 경우 입니다. 브랜치를 만들고 수정을 가하고 commit 을 합니다.
$ git checkout -b hotfix
Switched to a new branch "hotfix"
$ emacs index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix]: created 3a0874c: "fixed the broken email address"
1 files changed, 0 insertions(+), 1 deletions(-)
이 과정이 끝나면 위와 같은 형태로 브랜치들이 정리될 것입니다. 이제 머지(merge)를 해야 할 시간이 왔습니다.
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast forward
README | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
master 로 브랜치를 변경하고 합치는 것에 유의하셔야 합니다.
master 와 hotfix 브랜치가 같은 곳을 지정하고 있습니다. 이제 브랜치(포인터) 하나를 삭제해 줍니다.
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
그리고 다시 원래 하던 작업으로 돌아가서 작업을 계속 합니다.
$ git checkout iss53
Switched to branch "iss53"
$ emacs index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53]: created ad82d7a: "finished the new footer [issue 53]"
1 files changed, 1 insertions(+), 0 deletions(-)
그러면 위와 같은 형태의 브랜치 모습이 될 것입니다.
구체적으로 merge 부분을 자세하게 보는 것과 컨플릭트(conflict)를 해결하는 방법은 원문을 살펴 보세요