Git 이란
개발 프로젝트를 할 때 Git 을 많이 사용한다. 협업을 위해서도 사용하고, 개인으로 프로젝트를 관리하기 위해서도 많이 사용한다.
보통은 Git 의 사용법만 적당히 익힌 뒤 사용하는 경우가 많아서 Git 의 기능을 제대로 사용하지 못하거나 충돌같은 문제가 생기면 제대로 대응하지 못하는 경우가 많다. 그렇기 때문에 Git 에 대해 알고 사용하자.
Git 이란
Git 은 컴퓨터 파일의 변경사항을 추적하고 협업을 하기 위한 분산 버전 관리 시스템이다.
Git 은 2005년에 리눅스 토발즈와 리눅스 커널 개발자들이 함께 개발 하였다. 2002년에 오픈소스 프로젝트 리눅스 커널은 BitKeeper 라고 하는 상용 분산 버전 관리 시스템을 사용하였다. 그런데 2005년에 BitKeeper 가 유료화가 되면서 리눅스 커널과의 관계가 틀어지고, 리눅스 토발즈와 개발자들이BitKeeper 를 사용하면서 배운 점을 바탕으로 Git 을 만든 것이다.
Git 의 목표
지금도 그렇고 Git 이 추구하는 목표는 다음과 같다.
-
빠른 속도
-
단순한 구조
-
비선형적인 개발(수천 개의 동시 다발적인 브랜치)
-
완벽한 분산
-
리눅스 커널 같은 대형 프로젝트에도 속도나 데이터 크기 면에서 유용할 것
버전 관리란
Git 에 대해 알기 위해서는 먼저 버전 관리에 대해 알아야 한다.
버전 관리 시스템(VCS, Version Control System)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템이다.
우리가 일상에서도 버전 관리 시스템을 쓰고 있는데 문서 되돌리기나, 포토샵에서 레이아웃 작업 이력 등도 모두 버전 관리 시스템이라 볼 수 있다.
VCS 를 사용하면 각 파일을 이전 상태로 되돌릴 수 있고, 프로젝트를 통째로 이전 상태로 되돌릴 수도 있고, 시간에 따라 수정 내용을 비교해볼 수 있고, 누가 문제를 일으켰는지도 추적할 수 있고, 누가 언제 만들어낸 이슈인지도 알 수 있다. 또한 파일을 잃어버리거나 잘못 고쳤을 때도 쉽게 복구할 수 있다.
버전 관리 종류
로컬 버전 관리
VCS 는 로컬 버전 관리부터 시작된다. 로컬 버전 관리는 서버없이 내 컴퓨터에서 간단한 데이터베이스를 사용해 파일의 변경 정보를 관리하는 시스템이다.
버전을 관리하기 위해 디렉터리로 파일을 복사하는 방법을 사용할 수 있는데 이러면 디렉터리가 지워지거나, 실수로 파일을 수정하거나 잘못 복사할 수 있다. 이러한 이유로 프로그래머들에 의해 VCS 가 탄생하였다. 하지만 로컬 버전 관리는 말그대로 내 컴퓨터에서만 사용하기 위한 것으로 협업이 어려운 단점이 있다.
중앙집중식 버전 관리
중앙집중식 버전 관리(CVCS, Centrolized Version Control System) 는 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout) 하는 시스템이다. 로컬 버전 관리로는 프로젝트 협업 등이 어렵기 때문에 만들어졌으며 Subversion(SVN) 같은 시스템이 대표적이다. 또한 관리자는 누가 무엇을 할지 관리할 수 있고, 모든 클라이언트의 로컬 데이터베이스를 관리할 필요 없이 VCS 하나를 관리하기 때문에 훨씬 쉽다.
하지만 CVCS 도 결점이 있는데 가장 대표적인 것이 중앙 서버가 다운되면 협업이 불가능하고, 백업할 방법도 없어진다. 그리고 중앙 데이터베이스가 있는 하드디스크에 문제가 생기면 프로젝트의 모든 히스토리를 잃는다.
분산 버전 관리 시스템
Git 과 같은 분산 버전 관리 시스템(DVCS, Distributed Version Control System)은 저장소를 전부 복제하는 방식의 시스템이다.
로컬 버전 관리나 중앙집중식 버전 관리의 결점들을 보완하여 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있고, 모든 Checkout 은 모든 데이터를 가진 진정한 백업이다. 대부분의 DVCS 환경에서는 리모트 저장소가 존재한다. 사람들은 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다. 계층 모델 같은 중앙집중식 시스템으로는 할 수 없는 워크플로를 다양하게 사용할 수 있다.
Git 의 특징
Subversion 이나 Perfoce 같은 것을 사용해봤다고 하면 개발한지 오래됐을 확률이 높다. Git 을 배우려면 SVN 등을 사용하던 경험을 버려야 한다고 하는데 작동 방식이 다르기 때문이다.
차이가 아닌 스냅샷을 저장한다
위에서 언급 했듯이 SVN 등과 Git 의 가장 큰 차이점은 데이터를 다루는 방법에 있다. SVN 등은 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리한다. 즉 데이터 기반 관리 시스템인 것이다. 예를들어 1 + 2 + 3 을 쌓아 간다면 되돌아 가기 위해서는 -3, -2 로 역산해 나가야 한다.
대신 Git 은 시간순으로 프로젝트의 스냅샷을 저장한다. 파일이 달라지지 않았으면 Git 은 성능을 위해서 파일을 새로 저장하지 않는다. 단지 이전 상태의 파일에 대한 링크(레퍼런스 참고)만 저장한다. 그렇기 때문에 Git 은 한 달 전의 파일과 지금의 파일을 로컬에서 찾는다. 파일을 비교하기 위해 리모트에 있는 서버에 접근하고 나서 예전 버전을 가져올 필요가 없다. Git 은 데이터를 스냅샷의 스트림처럼 취급한다.
스탭샷(snapshot) 이란
컴퓨터 파일 시스템에서 스냅샷은 과거의 한 때 존재하고 유지시킨 컴퓨터 파일과 디렉터리의 모임이다.
스냅샷은 마치 사진을 찍듯이 특정 시점에 파일 시스템을 포착해 보관한다고 해서 붙여진 이름이다. 스냅샷은 원본 데이터를 그대로 복사해 다른 곳에 저장하는 백업과 달리 초기 생성 시 혹은 데이터의 변경이 있기 전까지는 스토리지의 공간을 차지하지 않는다.
거의 모든 명령을 로컬에서 실행한다
Git 은 거의 모든 명령이 로컬 파일과 데이터만 사용하기 때문에 네트워크에 있는 다른 컴퓨터는 필요 없다. 프로젝트의 모든 히스토리가 로컬 디스크에 있기 때문에 모든 명령이 순식간에 실행된다. “가장 빠른건 역시 localhost” 와 같은 이치다. 그래서 Git 에서 프로젝트의 히스토리를 조회할 때 서버가 필요없다.
Git 은 무결성을 보장한다
Git 은 데이터를 저장하기 전에 항상 체크섬을 구하고 그 체크섬으로 데이터를 관리한다.
체크섬은 Git 에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git 의 기본 철학이다. Git 은 SHA-1 해시를 사용하여 체크섬을 만든다. 만든 체크섬은 40자 길이의 16진수 문자열이다. 실제 사용할 때에는 줄여서 8글자만으로도 사용이 가능하다. 파일의 내용이나 디렉터리 구조를 이용하여 체크섬을 구한다. 실제로 Git 은 파일을 이름으로 저장하지 않고 해당 파일의 해시로 저장한다.
체크섬(checksum) 이란
체크섬은 자료의 무결성을 보호하는 단순한 방법이다.
데이터에 checksum 을 추가하여 연산을 통해 checksum 이 맞아 떨어지는지 확인해 봄으로써 데이터가 손상되지 않았다고 알 수 있다.
예를들면 위조 및 변조 방지를 위해 추가하는 주민등록번호 끝자리가 있다. 주민등록번호를 앞의 12자리 숫자에 각각 순서대로 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 를 곱한 뒤 모두 더한다. 그리고 더한 값을 11로 나눠서 나온 나머지 값을 11에서 뺀 숫자와 주민등록번호 끝자리가 같으면 유효한 것이다.
Git 은 데이터가 추가 되기만 할 뿐이다
Git 으로 한 것이면 무엇이든 Git 데이터베이스에 데이터가 추가된다. 데이터를 되돌리거나 데이터를 삭제할 방법이 없다. 되돌리기나 삭제를 하면 되돌리거나 삭제 했다는 내역을 추가할 뿐이다.
세 가지 상태
Git 은 Committed, Modified, Staged 이렇게 세가지 상태로 관리한다.
-
Committed: 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미, Git 디렉터리 단계
-
Modified 는 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 것을 의미, 워킹 트리 단계
-
Staged: 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미, Staging Area 단계
Git 디렉터리는 Git 이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. Git 디렉터리가 Git 의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어 진다.
워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것이다. Git 디렉터리는 지금 작업하는 디스크에 있고 그 디렉터리안에 압축된 데이터베이스에서 파일을 가져와서 워킹트리를 만든다.
Staging Area 는 Git 디렉터리에 있다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다.
Git 의 프로세스는 다음과 같다.
-
워킹 트리에서 파일을 수정
-
Staging Area 에 있는 파일을 Stage 해서 커밋할 스냅샷을 생성
-
Staging Area 에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장
Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged 이다. 주로 스테이지에 올린다고 표현한다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified이다.
해당 포스팅은 Pro Git 을 참고하였습니다.