본문 바로가기

책/프로 Git

분산 환경에서의 Git-2 - 프로젝트에 기여하기 - 비공개 소규모 팀

비공개 소규모 팀

보통 서브버젼 같은 중앙 집중형 버젼관리 시스템에서 사용하던 방식을 사용한다.

  • 물론 Git이 가진 오프라인 커밋, 브랜치기능도 사용한다.
  • 가장 큰 차이점은 서버가 아닌 클라이언트에서 Merge를 한다는 점이다.

두 개발자가 저장소를 공유하는 시나리오를 살펴보자.

 

개발자 John은 저장소를 Clone하고 파일을 수정 로컬에 커밋한다.

$ git clone john@githost:simplegit.git
$ cd simplegit/
$ vim lib/simplegit.rb
$ git commit -am 'removed invalid default value'

 

개발자 Jessica도 저장소를 Clone하고 나서 파일을 하나 새로 추가하고 커밋한다.

$ git clone jessica@githost:simplegit.git
$ cd simplegit/
$ vim TODO
$ git commit -am 'add reset task'

 

Jessica는 서버에 커밋을 Push한다. 

# Jessica's Machine
$ git push origin master
...
To jessica@githost:simplegit.git
   1edee6b..fbff5bc  master -> master

 

John도 서버로 커밋을 Push하려고 한다.

# John's Machine
$ git push origin master
To john@githost:simplegit.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'john@githost:simplegit.git'

 

Jessica의 Push는 성공했지만, John의 커밋은 서버에서 거절된다.

  • 서브버젼에서는 서로 다른 파일을 수정하는 이런 Merge 작업은 자동으로 서버가 처리한다.
  • Git은 로컬에서 먼저 Merge를 해야한다. 

John은 Push하기 전에 Jessica가 수정한 커밋을 Fetch하고 Merge한다.

$ git fetch origin
...
From john@githost:simplegit
 + 049d078...fbff5bc master     -> origin/master

 

Fetch하고 나면 John의 로컬 저장소는 다음과 같이 된다.

 

John은 Jessica가 저장소로 Push했던 커밋이 있는 브랜치를 로컬 저장소에 가져 왔지만 Push하기 전에 Fetch한 브랜치를 Merge해야 한다.

$ git merge origin/master
Merge made by the 'recursive' strategy.
 TODO |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

 

Merge가 잘 이루어지면 John의 브랜치는 다음과 같다.

 

John은 Merge하고 나서 자신이 작업한 코드를 확인후 Push 한다.

$ git push origin master
...
To john@githost:simplegit.git
   fbff5bc..72bbc59  master -> master

 

John의 저장소는 다음과 같다.

 

동시에 Jessica는 issue54 토픽 브랜치를 만들고 3번 커밋한다.

 

Jessica는 John의 작업을 적용하려면 Fetch를 해야한다.

# Jessica's Machine
$ git fetch origin
...
From jessica@githost:simplegit
   fbff5bc..72bbc59  master     -> origin/master

 

Jessica의 저장소는 다음과 같이 된다.

 

Jessica는 issue54(토픽) 브랜치 작업을 마치고 어떤 내용이 Merge 되는지 git log 명령으로 확인한다.

$ git log --no-merges rigin/master ^issue54 
commit 738ee872852dfaa9d6634e0dea7a324040193016
Author: John Smith <jsmith@example.com>
Date:   Fri May 29 16:01:27 2009 -0700

   remove invalid default value

 

Jessica는 모든 내용을 Merge하기 전에 우선 master 브랜치로 checkout 한다.

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.

 

먼저 issue54 브랜치를 Merge 한다.

  • Fast-forward로 Merge 되었다. 
$ git merge issue54
Updating fbff5bc..4af4298
Fast forward
 README           |    1 +
 lib/simplegit.rb |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

 

다음 John의 커밋(origin/master)을 Merge 한다.

$ git merge origin/master
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
 lib/simplegit.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

 

위와 같이 Merge를 하면 Jessica의 저장소는 다음과 같다.

 

origin/master 브랜치가 Jessica의 master 브랜치로 나아갈(reachable) 수 있기 때문에 Push는 성공한다.

$ git push origin master
...
To jessica@githost:simplegit.git
   72bbc59..8059c15  master -> master

 

Push한 후 Jessica의 저장소는 다음과 같다.

 

여기서 살펴본 예제가 가장 간단한 상황이다. 

  1. 토픽 브랜치에서 수정하고 로컬의 master 브랜치와 Merge한다.
  2. 작업한 내용을 프로젝트 공유 저장소에 Push 하고자 할 때에는 우선 orgin/master 브랜치를 fetch하고 Merge한다.
  3. Merge한 결과를 다시 Push한다.