Git 교육 완료 후, 내용 축약&정리하여 공유합니다.
주의! 일부 빠진 내용이나 미흡한 내용이 있을 수 있습니다.
Git vs SVN
차이점
아래 보여지는 차이점들은 모두 큰 프로젝트를 많은 개발자가 동시에 개발하기에 용이하도록 발전되어졌다.
아래의 차이점으로 git의 장점으로 생각하는
Offline commit
Fast commit, branch
Easy merge
Data safe
등이 존재할 수 있다. ( 그외의 주장하는 장점들 : http://thkoch2001.github.io/whygitisbetter/ )
시스템 구조 차이
중앙집중식 버전 관리 vs 분산 버전 관리
VS
저장 방식의 차이
델타 vs 스냅샷
VS
Git 구조
Git Object
간단하게 보면 git은 위의 3개의 object로 구성되어 있다.
- 위의 object들은 repository하위의 .git/object 디렉토리에 타입 구분 없이 존재한다.
- 'git cat-file '명령어로 해당 object가 어떤 타입인지 알 수 있다.
Blob object : file 별로 object가 존재한다.
단, file 내용이 동일 할 경우, 하나의 ojbect가 생성되어 해당 링크를 공유한다.
Ex ) a.txt와 b.txt의 내용이 hello로 동일할 경우, blob object는 하나만 생성된다.
Tree object : 하위 링크로 blob과 tree를 가지게 된다.
tree는 file system의 directory에 대응된다.
Commit object : commit 별로 생성되는 object이다.
tree의 링크, commiter의 내용 등을 담고 있다.
아래 그림은 branch reference가 추가된 모습니다.
Tree object는 각각 version의 snapshot상태를 기록하고 commit은 그 tree를,
Branch 는 해당 commit을 링크로 가지게 된다.
이렇게 함으로써 branch & merge가 빠르고 쉬운 구조를 가지게 된다.
※ HEAD
Head는 현재 branch를 가리키는 값이다.
기존 SCV 들과 달리 git에서는 별도의 branch를 만들기위해 소스복사, 새로운 디렉토리경로를 가질 필요가 없다.
HEAD 의 값을 변경함으로써 동일한 Working directory 에서 다른 branch의 작업을 진행할 수 있게 된다.
(개인적으로 가장 큰 장점이라고 생각. )
Git Repository
Git은 분산 버전 관리를 지원하기 위해 작업을 진행하는 각각의 클라이언트에 Repository 뿐만 아니라 Stage(=index)까지 가지고 있다.
새로운 파일의 추가/변경 등에 의한 변경 점을 add 명령어로 stage에 반영하고 반영된 내용을 내부 repository에 commit하는 방식이다.
Git Branch & Merge ( rebase )
merge
Git에서 merge 는 새로운 commit을 만드는 형태로 진행된다.
Git에서는 모든 obejct들에 대해서는 수정하지않고 새로운 object 생성과 ref를 바꿔주는 형태로만 진행된다.
위의 iss1~iss3 까지의 branch를 생성한 형태를 merge하게 되면 아래 와 같이 변형된다.
branch iss1을 master와 merge하여 c9 가 생성되었다.
branch iss2를 c9와 merge하여 c10 생성
branch iss3 을 c10과 merge 하여 c11 생성
최종적으로 master는 c11링크를 가지게 된다.
rebase
그런데 위와 같이 merge를 진행할 경우, 각 branch들은 살아있고, 복잡한 구조를 유지하게 된다.
이 경우를 피하여 순차적인 형태로 변형하는 것을 rebase라고 한다.
위의 첫번째 모델을 rebase를 이용하여 변형할 경우 아래와 같이 변형된다.
branch iss1 의 base를 C1에서 C4로 rebase하여 C2' 로 변경
그런데 여기서 branch iss2(c6)을 master에 rebase하면 c5가 사라져 commit history가 사라지게 된다.
commit history를 남기기 위해서는 --no--ff ( no fast-forward ) 옵션으로 fast forward 기능을 사용하지 않아야 한다.
ref : http://rangken.github.io/blog/2013/git-rebase-merge/
Git Flow
Git에서 Git Flow 방식으로 사용하는 것을 제안하고 있고 그 모델은 아래와 같습니다.
http://nvie.com/posts/a-successful-git-branching-model/
Git Flow에서는 master(origin) branch는 신성한 branch이기 때문에 해당 branch에서는 작업을
하지 않도록 제안합니다.
- Branch
master : 프로젝트 orginal code를 가지고 있습니다.
develop : master로부터 생성되어 개발 중인 코드를 가지게 됩니다.
feature : develop으로부터 생성되어 구현 기능별로 작업 내역을 가지게 됩니다.
기능 구현이 완료되어 develop으로 merge 후에는 사라지게 됩니다.
release: develop으로부터 생성되어 개발 완료되어 배포 버전의 코드를 가지게 됩니다.
이 branch는 추후 master로 merge됩니다.
Master로의 merge 이전의 bug는 release branch에서 수정합니다.
hotfixes : master로부터 생성되는 branch로 hotfix가 필요할 때에만 생성되는 branch입니다.
Git Flow의 작업 절차는 아래와 같이 진행합니다.
- 최초 master branch 생성
- master 로부터 develop branch 생성
- 기능 A와 B를 개발하기 위한 feature branch A와 B를 각각 생성
- 기능 A와 B를 병렬로 개발
- A와 B를 develop branch로 merge
- QA 및 배포를 위해 develop으로부터 release branch 생성
- release에서 직접 bug fix
- release branch의 배포
- release branch를 master branch로 merge
- Live에서 장애 발생
- Master branch로부터 hotfix branch 생성
- 수정 후, fotfix branch 를 master와 develop branch로 merge
Git 용어 차이
Git에서는 기존 SCM 과의 구조적/절차적 차이로 동일한 용어를 다른 의미로 사용하게 됩니다.
이해를 돕기 위해 자주 사용되는 명렁어에 대해서 아래와 같은 표를 만들어 보았습니다.
|
SVN | p4 | Git |
branch | branch | X (≒ workspace ) | Branch (≒ workspace in p4) |
checkout | 원격 repository로부터 data를 가져온다. | 해당 파일을 수정하기 위한 준비 | 해당 branch로의 작업 branch변경 ( = HEAD 변경) |
commit | 수정된 파일을 원격 repository에 반영한다. | Checkout한 파일을 원격 repository에 반영한다. | Stage에 반영된 파일을 내부 repository에 반영한다. |
위의 Git 기능(branch, checkout, commit) 만으론 기존 SCM에서 사용했던 기능을 지원할 수 없습니다.
일반적으로 사용하는 기능을 Git 에서 Git Flow 절차에 따른 방식으로 보면 아래와 같습니다.
other SCM | Git |
checkout | develop branch로부터 feature branch생성 |
commit | add 명령어로 stage(=index)에 추가 Commit 명령어로 내부 repository에 반영 push 명령어로 원격 repository feature branch에 반영 Feature branch를 develop branch에 merge |
ref : http://ndpsoftware.com/git-cheatsheet.html#loc=index;
Git 명령어 및 branch 관련 명령어를 연습하기에 좋은 사이트가 있어서 추가합니다. 강추!!
http://learnbranch.urigit.com/