시간이 좀 지난 글이지만 git을 공부하는 최고의 방법은 pro git을 읽어보라고 하신 응준님의 글을 읽고 공부를 시작해보게 되었다. 요새 서류랑 면접준비한다고 블로그를 좀 못썼는데.. 너무 오래 안쓴 것 같아서 다시 꾸준히 써보려고 한다. 일단은 가장 중요한 1~3단원만 정리해보자.
1. 버전 관리란?
버전 관리 시스템(VCS, version control system)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 가져올 수 있는 시스템이다.
1.1 로컬 버전 관리
흔히 나는 파일을 디렉토리에다가 복사한다음에 이름을 바꿔서 관리한다. 귀찮기도 하고 이방법이 제일 쉽다. 하지만 제대로 파일을 관리하려고하면 이렇게 하면 안될 것 같다. 로컬에서 간단한 데이터베이스를 사용해서 파일의 변경 정보를 관리하는 방법이 있다. 많이 쓰는 도구중에 RCS(Revision Control System)이 있다. 오늘날(지금도?)까지 많은 회사가 사용하고 있고 Mac OS X 운영체제에서도 개발도구를 설치하면 함께 설치된다. RCS는 기본적으로 Patch Set(파일에서 변경되는 부분)을 관리한다. 이 Patch Set은 특별한 형식의 파일로 저장한다. 그리고 일련의 Patch Set을 이용해서 모든 파일을 특정 시점으로 되돌릴 수 있다.
1.2 중앙 집중식 버전 관리(CVCS)
프로젝트를 진행하다 보면 다른 개발자와 함께 작업해야 하는 경우가 많다. 이럴 때 생기는 문제를 해결하기 위해 CVCS가 개발됐다. CVS, Subversion, Perforce 같은 시스템은 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout) 한다. 누가 무엇을 하고 있는지 알 수 있으니 관리자가 쉽게 관리할 수 있다. 단점은 중앙서버에 문제가 발생하면 그 동안 협업이 안되고 백업할 방법도 없다.
1.3 분산 버전 관리 시스템
Git, Mecurial, Bazaar, Darcs 같은 DVCS에서의 클라이언트는 단순히 파일의 마지막 스냅샷을 Checkout하지 않는다. 그냥 저장소를 전부 복제한다. 서버에 문제가 생기면 이 복제물로 다시 작업하고 서버를 복원하면 된다. 게다가 대부분의 DVCS 환경에서는 리모트 저장소가 존재한다. 다양한 방법의 협업이 가능하며 중앙집중식 시스템으로는 할 수 없는 워크플로를 다양하게 사용할 수 있다.
2. Git 기초
Git의 핵심을 뭘까? Git이 Subversion 같은 다른 VCS와의 가장 큰 차이점은 무엇일까? 데이터를 다루는 방법이다. 큰틀에서 봤을 때 VCS 대부분은 관리하는 정보가 파일들의 목록이다. Subversion 같은 시스템은 각 파일의 변화를 시간순으로 관리한다. Git은 이런식으로 데이터를 저장하지도 취급하지도 않는다. 대신 Git은 데이터를 파일 시스템 스냅샷으로 취급하고 크기가 아주 작다. Git은 커밋하거나 프로젝트의 상태를 저장할 때마다 파일이 존재하는 그 순간을 중요하게 여긴다. 파일이 달라지지 않았으면 Git은 성능을 위해서 파일을 새로 저장하지 않는다. 단지 이전 상태의 파일에 대한 링크만 저장한다. Git은 데이터를 스냅샷의 스트림처럼 취급한다.
Git은 거의 모든 명령을 로컬에서 실행하기 때문에 네트워크에 있는 다른 컴퓨터는 필요없다. 따라서 속도에서 다른 시스템보다 이점이 있다. 예를 들어 Git은 프로젝트의 히스토리를 조회할 때 서버없이 조회한다. 그냥 로컬 데이터베이스에서 히스토리를 읽어서 보여준다.
Git은 데이터를 저장하기 전에 항상 체크섬을 구하고 그 체크섬으로 데이터를 관리한다. 체크섬은 Git에서 사용하는 가장 기본적인(atomic) 데이터 단위이자 Git의 기본 철학이다. Git 없이는 체크섬을 다룰 수 없어서 파일의 상태도 알 수 없고 심지어 데이터를 잃어버릴 수도 있다. Git은 SHA-1 해시를 사용하여 체크섬을 만든다. 이를 통해 Git은 무결성을 보장한다.
Git으로 무얼 하든 Git 데이터베이스에 데이터가 추가된다. 되돌리거나 데이터를 삭제할 방법이 없다. 단 커밋을 하지 않으면 변경사항을 잃어버릴 수 있다. 일단 스냅샷을 커밋하고 나면 데이터를 잃어버리기 어렵다.
3. 세 가지 상태 (중요함)
Git은 파일을 Committed, Modified, Staged 이렇게 세 가지 상태로 관리한다.
(1) Committed이란 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미한다.
(2) Modified는 수정한 파일을 아직 로컬 데이터 베이스에 커밋하지 않은 것을 말한다.
(3) Staged란 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미한다.
Git 디렉토리는 Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. 이 Git 디렉토리가 Git의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone할 때 Git 디렉토리가 만들어진다.
워킹 디렉토리는 프로젝트의 특정 버전을 Checkout한 것이다. Git 디렉토리는 지금 작업하는 디스크에 있고 그 디렉토리 안에 압축된 데이터베이스에서 파일을 가져와 워킹 디렉토리를 만든다.
Staging Area는 Git 디렉토리에 있다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다 종종 인덱스라고 불리기도 하지만, Staging Area라는 명칭이 표준이 되어가고 있다.
Git으로 하는 일은 기본적으로 아래와 같다.
1. 워킹 디렉토리에서 파일을 수정한다.
2. Staging Area에 파일을 Stage해서 커밋할 스냅샷을 만든다.
3. Staging Area에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장한다.
Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified이다.
* Snapshot: 마치 사진 찍듯이 특정 시점에 파일시스템을 포착해 보관하는 기술. 백업과 다르게 데이터의 변경이 있기 전까지는 스토리지공간을 차지하지 않음. 또 메타데이터의 복사본에 해당하기 때문에 생성과 복원이 빠름.
* 무결성: 데이터의 정확성, 일관성, 유효성이 유지되는 것.
참고: Git pro책, https://git-scm.com/book/en/v2