본문 바로가기

General/Git

Git, Git, Git, Git, Git이 뭐길래?

저는 약 3주 전까지만해도 Git을 써본적이 없었습니다. 그동안 SVN을 이용해서 버전관리를 했었어요. 그러다가, 3주쯤 전부터 프로젝트를 인수받으면서 Git을 접하게 되었는데요.

Git을 써보고 느낀건..... 정말 여러모로 편리하고 뛰어나다는 말밖에 할말이 없군요.




Git 이란? (wiki)


 기트(Git /ɡɪt/[1])는 프로그램 등의 소스 코드 관리를 위한 분산 버전 관리 시스템이다. 빠른 수행 속도에 중점을 두고 있는 것이 특징이다. 최초에는 리누스 토르발스 리눅스 커널 개발에 이용하려고 개발하였으나, 현재는 널리 사용되고 있다.

 Git의 작업 폴더는 모두, 전체 기록과 각 기록을 추적할 수 있는 정보를 포함하고 있으며, 완전한 형태의 저장소이다. 네트워크에 접근하거나 중앙 서버에 의존하지 않는다.

 현재 주니오 하마노(Junio Hamano)가 소프트웨어 관리를 감독하고 있다. Git은GNU 일반 공중 사용 허가서 v2 하에 배포되는 자유 소프트웨어이다. 




개발자Junio Hamano, 리누스 토르발스
최근 버전1.7.9.2 / 2012년 2월 23일
운영 체제POSIX
플랫폼크로스 플랫폼
종류버전 관리
라이선스GNU 일반 공중 사용 허가서 v2
웹사이트http://git-scm.com/




전 사실, svn을 쓰다가 git으로 넘어와서 그런지, 처음에는 개념이 잘 이해가 안되었었어요.


그저 git을 사용했던 사람들에게 들어서 이정도는 알고 있었죠.

  • 빠르다.
  • 모두가 원본을 가진다.   
  • local에서 대부분의 작업을 할 수 있다.


그리고 대부분의 VCS(version control system)처럼 git도 이런 개념들을 가지고 있습니다.

(svn에도 trunk, branch, tag가 있죠.)

  • master
  • branch
  • tag

svn을 쓰던 분들은 trunk가 master로 바뀌었다고 생각하면 됩니다.


'뭐가.. 어떻게 다르다는 거야?'

'그래서 그렇게 해서 어떻게 하겠다는건데?' 

음.... 이런 생각이 드실거에요. 


사실 subversion(svn)을 사용하면서 제가 느꼈던 힘들었던 부분은, 다른 사람과의 공동작업에 있어서 코드를 통합하는 경우(merge, commit)에 너무 많은 충돌을 경험했었다는 것이죠.


실제 버전이 관리되는건(사람들은 svn 서버에 있는 코드를 받아서 작업하는것) 서버에서 해주는 일이었기에, 어쨋든 작업을 하게 되면, 서버로 코드가 모이게 됩니다. 


이때 여러 사람이 동시에 작업하던 클래스나 파일이 있다면.... 이제부터 힘겨워지기 시작하는거죠. 


git을 사용하면 이런 대부분의 문제들에 대해서 자유로워질 수 있습니다.(라고 생각하는 중...)




Git을 혼자서 사용한다면

그저 그 자체로도 branch를 만들고, 코드를 commit하고 merge하는 등 모든 버전관리 기능을 다 사용할 수 있어요.


  • 자신의 컴퓨터에 있는 repository(local의 repository)에서 모든 것을 다 할 수 있다.


예를들면, 이런 느낌이에요.

subversion을 사용할때, 혼자서 svn 서버를 돌리면서, 혼자서 서버에 commit하고 등등을 한다면..

Git을 사용했을 때는, 혼자서 쓴다면 서버가 필요없죠. [local]에서 모든것을 다 할 수 있으니까요.

git에서는 자신의 local repository가 svn의 서버에 있는 repository처럼 동작한다는것이죠.




하지만 리누스 토발즈느님께서 Git을 그렇게만 쓰라고 만든게 아니지요.

(위 wiki 인용부에도 나와있지만, 원래는 리눅스 커널 개발에서 버전관리등을 하려고 개발한게 git이라고 하지요.)


Git은 DVCS(Distributed version control system)이잖아요. 

원격지의 repository에 연결을 해서 다같이 작업을 해야 제 맛(?)인게 git이라고 할 수 있어요.

그리고 github.com 에 repository를 등록하고 프로젝트를 올리고 해봐야 더 재밌죠.


git의 장점은 여러사람이 함께 프로젝트를 진행할때 알 수 있습니다.

git에서는 내가 코드를 작성하다가, 다른 사람이 진행하고 있는 branch에 가서 코드를 보거나 특정 부분에 가서(특정 commit이나 특정 tag) 코드를 보다가 다시 내가 작업하던 코드로 돌아오고 하는 것들이 너무나 자연스럽고 빠릅니다.




처음에 제가 최신의 마스터 소스코드를 받아왔다고 해 봅니다.(pull)

어떤 특정 부분을 지정해서 그 부분을 보고 있는 상태를 [checkout]이라고 합니다.

즉, 저는 master를 checkout해서 보고 있는 거죠.




이제 옆에 빨간색으로 보이는데로 이동을 해서 코드를 보고 싶습니다.

그러면 그저 그 부분으로 checkout을 하기만 하면 됩니다.



이렇게 그 부분(빨간색 branch의 어떤 특정 commit)으로 체크 아웃을 하면, 그 부분을 보게 되는거죠.


다시 원래의 마스터 최신 코드로 돌아오는것도 master의 최신 commit을 checkout 하기만 하면 됩니다.


이때, 내 컴퓨터(local)에는 물리적으로 한 세트의 소스코드만 존재한다는 것이죠.

소스코드의 세트를 여러개 받아놓고 작업을 할 필요가 없습니다. 예전에 작업하던 곳으로 돌아가더라도, 소스코드는 한 세트만 가지고 있으면 되는거죠.




이게 가능하게 되는건, git이 포인터를 사용하기 때문입니다.

이 말인즉슨, 각각의 branch, commit, tag에 대해서 git은 포인터로 처리를 하고 저장한다는 것입니다.


그래서 이 태그에서 저 태그로, 이 브랜치에서 저 브랜치로 옮겨 다니면서도 빠르게 문제없이 옮겨다니며 작업할 수 있는것이죠. 

단지 '내가 보고 있는 곳의 포인터를, 다른곳의 포인터로 바꿔치기' 하면 되는것이니까요.

(git을 2주-3주 정도 사용해 보며, [포인터를 바꿔치기한다]라고 저는 이해를 했습니다.)


(물론 작업을 진행하며 충돌이 날수도 있고 여러가지 문제로 예전상태로 checkout이 안되는 경우도 있긴합니다만, 그럼에도 불구하고 svn에 비해서는 너무 빠르고 자연스럽군요.)




git을 '여러 사람이 사용할 때, 장점을 잘 알 수 있다.'라는 얘기에서 좀 벗어났네요. 다시 돌아와서 얘기를 해보죠.


위에서 git은 local환경에서도 모든것을 다 할 수 있다.라고 했습니다.

git은 소스코드를 가진 모든 컴퓨터(모든 컴퓨터의 git repository)가 원본이 됩니다. 그래서 누군가의 컴퓨터가 망가지고, 어딘가의 소스코드가 날아가더라도, 원본 그대로의 프로젝트를 유지하기가 쉽죠.


거기에다가 local에서 모든것을 할 수 있다는 말은, 원본(내 컴퓨터의 repository도 원본이니까)에서 모든 작업을 다 할 수 있다는 것이니, 작업을 진행함에 있어서도 부담이 없습니다.

(물론, push라는 명령을 통해 메인 repository(remote라고 부르는)에 해당 사항을 적용 시켜주어야 합니다.)


이 말을 조금 다르게 하면, 내 컴퓨터에서 모든 작업을 다 하고, 해당 코드에 대한 안정성이 확보됬을때, 실제 원격의 master에 코드를 적용할 수 있다는 거죠. 그러면서도 중간중간 자신 혼자서 개발하면서 commit한 내용들에 대한 보관도 다 이루어 집니다(local에서도 commit을 할 수 있으니...).


혼자서, local에서만 작업을 했더라도, 개발 이력에 대해서 트래킹이 가능하죠.

svn이 하나의 메인 repository를 놓고 각각의 개발자들이 서브가 되어 자신이 개발한걸 메인 repository에 commit하는 형식이었다면,

git은 메인 repository는 존재하지만, 각각의 개발자들이 또 다른 원본의 repository를 가지면서 작업을 하게 됩니다. 그리고 자신의 컴퓨터(local)의 repository에 commit을 하게 되고, 안정성등이 확보가 된다면 메인(remote) repository에 push를 하는 방식이 되는 거죠. 이때 이 메인 repository는 실제 github enterprise일 수 있지만, 다른 누군가의 컴퓨터일수도 있습니다. 설정하기 나름이니까요.


이렇게, 내가 작업해서 내 local에 commit된 코드들을 메인 repository(어딘가의 remote repository)에 적용시키는것을 push라고 합니다. 어딘가의 remote repository에서 코드를 받아오는건 pull이라고 하고요. 

그리고 git은 여러 branch에서의 작업이 너무 쉽게 일어난다고 말했었죠. 이렇게 여러 branch에서 작업을 하다가, 하나의 branch를 다른 branch에(예를 들면 master와 다른 branch를) 통합하는 것을 merge라고 합니다.



master에서 branch를 하나 만들어 코드를 작업하다가, 다시 master에 merge를 통해 하나의 코드로 만든다라는 거죠. 


예를들어,



1. 프로젝트에서 bug가 발견되어, 이를 고쳐야 합니다. 하지만 master에서 작업하기에는 좀 껄끄럽죠. master는 안전성을 유지한 상태여야 하니까요. 이럴때, hotfix라는 branch를 하나 만들어서 작업을 진행하는거죠. 그 사이, master에는 완벽한 상태의 원본이 유지될거고, 저는 hotfix를 통해 버그를 수정할 수 있습니다. 그리고 작업이 끝나고나면 master로 merge를 하거나, 해당 커밋만 체리픽 할 수 있죠.


2. 제가 이런 작업을 진행하는 사이, 누군가는 서브기능을 추가하고 있을 수 있습니다. 단순하게 그 사람이 작업하는 branch를 sub라고 해볼게요. 그리고 그 사람은 작업을 마치고 나면 master와 sub를 merge하겠죠.


3. 그러는 사이, 누군가는 master에서 작업을 진행하고 있을수도 있죠. 열심히 commit, push를 하며 master의 코드를 고쳐나갈겁니다.


그리고 결국에 이런 1, 2, 3의 작업들을 통해 작성된 코드들은 master로 모이게 되겠죠.



그림으로 나타내 보면 이렇게 표현할 수 있습니다.



그림을 보시거나, git에 대한 설명을 여기저기서 보신 분들은 아시겠지만,

branch는 마스터로 부터 뻗어져 나온 가지입니다. 또 마찬가지로 master 또한 가지입니다. 가지보다는 기둥에 가깝겠지만요. master 라는 기둥(또는 가지, branch)로 부터 가지(branch)를 뻗어서 작업을 진행하다가, 다시 master라는 기둥(branch)으로 merge를 하는 것이죠. 가지는 한두개가 아닐 수 있고, 각각이 가지에서 작업하는 사람은 1명 이상이겠지요. 


그리고 각각의 가지 안에서는 commit, push, pull이라는 작업들이 계속해서 일어날 것이고, 

이런 작업들이 진행되는 동안, 파일들은 unstage, unmodified, modified, stage 상태를 왔다갔다 하겠죠.


저도 아직 많이 써보지 않아서 잘은 모르지만, 딱 요정도 눈높이로 보고 있을때, git을 시작하려는 사람들에게 설명하기 좋다고 생각이되어 짧게나마(?) 정리해두려고 글을 끄적여보았습니다.




 
 Git을 공부하며 참고한 링크들 

 실제 들어가본 페이지들은 더 많지만, 이 두 링크면 git을 사용하는데는 문제가 없을거에요.


 류광의 번역이야기

 http://occamsrazr.net/tt/254

 - git에 대한 설명과, 여러 링크들이 모여져 있습니다. 

   이 안에있는 링크들을 다 들어가 보셨다면 이미 git을 쓰고 계신것과 마찬가지.


 namhyung님의 노트 

 http://namhyung.springnote.com/pages/3132772

 - git 설명서에 대한 번역입니다. 생각 안날때 보면 많은 도움이 되요.


 terminal에서 command로 git을 사용하는게 부담된다면!

 저는 git을 source tree라는 툴로 사용하고 있습니다. app store에서 무료로 받을 수 있어요.

 업데이트도 자주되고, 편리성에서 매우 좋네요.

 http://itunes.apple.com/kr/app/sourcetree-git-hg/id411678673?mt=12

  



'General > Git' 카테고리의 다른 글

[Git] Git Setup for mac(Git 환경구축)  (0) 2011.12.21