포럼 회원으로 등록하신분만 다운로드가 가능합니다. 최대 업로드 가능한 용량은 20MB 입니다.
안녕하세요?
현재 국내에 GIT에 대한 제대로 된 문서가 없기에, GIT 사용자 가이드에 대하여 번역을 시작하게 되었습니다.
번역의 오류로 틀린 내용이 있을 수도 있으니, 오류 발견시 댓글을 남겨주시면 감사하겠습니다.
GIT 사용법 (ProGIT) - 1.2. GIT 개발 역사 / 1.3. GIT 기본 개념
원본 : ProGIT Book(http://progit.org)
번역 : 김재훈(이솝 임베디드 포럼, http://www.aesop.or.kr)
1.2. GIT 개발 역사
지금까지 컴퓨터 시스템의 개발 역사를 둘러보았을 때, 기존의 가치관에 대한 창조적 파괴를 주창하는 사람들이 생거나고,
이에 대한 많은 사람들의 수많은 논쟁 끝에 훌륭한 결과물이 탄생했던 경우가 많았습니다.
이 중에서 대표적인 결과물 중에 하나가 Linux 커널 개발 프로젝트 입니다.
Linux 커널은 매우 방대한 범위의 오픈 소스 소프트웨어 프로젝트의 하나 입니다.
1991년 Linux 커널이 최초로 개발되고 어느 정도 본격적인 범용 운영체제로써의 모양새를 갖추어 나가던 2002년 사이동안
이 소프트웨어에 대한 변경 사항은 패치 또는 파일로 보관하는 형태로 버전관리를 해왔습니다.
하지만, Linux 커널이 점점 방대해 지면서, Linux 커널 개발 프로젝트의 버전 관리를 위해 BitKeeper를 도입하여 사용하기 시작 했습니다. (BitKepper는 분산형 버전관리 시스템 중의 하나 입니다.)
2005년에 Linux 커널을 개발하고 있던 비영리 커뮤니티와 BitKeeper를 개발하고 있던 영리 기업사이의 협력 관계가 붕괴되었습니다. 따라서, Linux 커널을 개발하고 있던 비영리 커뮤니티는 그 동안에 BitKeeper를 사용하면서 쌓은 경험을 바탕으로 새로운 버전 관리 시스템을 독자적으로 개발하기로 하였습니다.
새로운 버전관리 시스템을 개발하면서 기본 목표는 다음과 같습니다.
빠른 속도, 간단한 소프트웨어 설계, 완전한 분산, 수천개 이상의 병렬 브랜치를 지원하여 Linux 커널과 같은 대규모 프로젝트를 효율적으로 취급 할 수 있는 시스템 이었습니다.
그리고, 이런 요구사항을 충족하기 위해 GIT가 개발되었습니다. 그리고, 그 이후 GIT는 지속적으로 사용하기 쉽고, 강력한 기능을 무장하면서, 초기의 개발 요구 사항을 충족할 수 있게 되었습니다.
오늘날 GIT는 가장 강력한 분산형 버전 관리 시스템으로, 거대한 소프트웨어 프로젝트에서 매우 효율적으로 동작할 수 있는 강력한 분기 관리 시스템(branching system)을 갖추게 되었습니다.
1.3. GIT의 기본
그럼, GIT는 무엇일까요? 이것은 GIT를 여러분이 이해하기 위해서 알아야 하는 가장 중요한 과제 입니다.
왜냐하면, GIT가 어떤 원리로 어떻게 동작하는지에 대한 이해가 있어야 GIT를 여러분이 효과적으로 사용할 수 있기 때문 입니다. GIT는 기존의 버전 관리 시스템과 개념이 많이 틀리기 때문에, GIT를 여러분이 배울 때에는 기존에 사용하던 Subversion이나, Perforce과 같은 다른 계열의 VCS에 대한 경험은 여러 분의 혼란만 가중 시키게 됩니다.
따라서, 기존의 버전 관리 시스템에 대한 지식은 잊고 새로 공부한다는 생각으로 GIT를 접근하는 것이 여러분이 GIT를 이애하는데 한층 도움이 될 것 입니다.
예를들어, GIT는 기존의 소스코드 버전관리 시스템과 유저 인터페이스가 비슷한 면이 있으나, 애매하게 틀리고, 소스 코드에 대한 정보를 저장하는 방식도 틀리기 때문에, 혼란만 가중 시킬 수 있기 때문 입니다.
1.3.1. GIT는 소스코드를 Snapshot 단위로 관리
GIT는 Snapshot 단위로 관리하며, Snapshot은 기존의 diff를 통해 소스코드의 변경 사항만 저장하는 방식이 아닙니다.
GIT와 다른 VCS(Subversion 및 기타 다른 종류의 버전 관리 시스템)와 가장 다른 점은 데이터를 다루는 방법 입니다.
개념적으로는, 기존의 VCS는 파일들을 기본으로 변경된 데이터들을 하나의 리스트로써 관리 합니다.
이러한 시스템(CVS, Subversion, Perforce, Bazaar 등)은, 그림 1-4와 같이 시스템이 보관하고 있는 파일을 집합과 시간을 기준으로 각각의 파일의 변경 사항을 저장하여 관리 합니다.
그림 1-4. 기존의 VCS는 파일의 변경 사항을 기준으로 버전을 관리 합니다.
반면에 GIT는 기존의 VCS와 달리 파일을 변경 사항을 기준으로 버전을 관리하지 않습니다.
대신에 GIT는 데이터를 미니 파일 시스템의 Snapshot의 집합과 같이 생각 합니다. 소스코드를 Commit(시스템에 소스 코드의 변경 사항을 기록하고 보존하는 명령) 할 때 또는 프로젝트의 현재 상태를 저장하고자 할 때, GIT는 기본적으로 그 시점의 모든 파일 상태에 대한 Snapshot를 찍어 그 Snapshot에 대한 정보를 저장합니다. 하지만, GIT는 효율성을 위해, 변경 사항이 없는 파일의 경우는 저장하지 않고, 이전에 저장된 동일한 파일은 저장하지 않고 현재의 Snapshot에 링크만 하게 됩니다. (변경되지 않은 파일은 새로운 Snapshot에 저장하지 않고, 기존의 파일에 대한 링크만 저장)
따라서, GIT는 데이터를 그림 1-5와 같은 형식으로 저장합니다.
그림 1-5. GIT는 프로젝트의 Snapshot을 찍어 데이터를 저장 합니다. (프로젝트를 통째로 저장)
이것이 GIT와 다른 VCS와의 가장 큰 차이점이며, 우리는 이것을 먼저 이해해야 합니다.
GIT는 기존의 VCS들이 사용하던 거의 모든 버전 관리 방식에 대한 개념을 탈피하고 있습니다.
데이터의 변경사항만을 추출하여 차곡 차곡 정리하는 기존의 VCS와 달리, GIT는 프로젝트에 대한 미니 파일 시스템을 구축하여 프로젝트 단위로 버전별로 통째로 저장하게 됩니다.
이런 방식을 통해 GIT가 얻을 수 있는 이점에 대해서는 제 3장의 Git Branching 부분에서 알 수 있습니다.
1.3.2. GIT는 거의 모든 조작을 로컬PC에서 수행
기존의 VCS는 데이터의 변경 사항을 입력(Commit)하려면, 대부분 네트워크에 연결된 다른 VCS 서버 시스템에 접근하여 저장을 합니다. 하지만, GIT는 대부분의 조작을 로컬 시스템에서 처리 합니다. 따라서 네트워크를 이용하여 다른 시스템에 접근하지 않습니다. 따라서, 대규모 프로젝트를 관리할 경우 GIT는 기존의 VCS와 달리 프로젝트를 Commit할 때 굉장히 빠른 속도로 처리를 합니다. GIT는 프로젝트의 변경 이력을 모두 로컬 디스크에 저장을 하기 때문에, 대부분의 버전 관리에 관련된 조작은 매우 짧은 순간에 끝나는 것 처럼 보이게 됩니다.
예를 들면, 프로젝트의 변경 이력을 열람하기 위해서는 기존 VCS와 달리 GIT는 원격 서버에 접속하여 프로젝트의 변경 이력을 받아올 필요가 없습니다. 단지, 직접 현재 PC에 저장된 로컬 데이터베이스로부터 읽어올 뿐입니다. 따라서, 불필요한 네트워크 조작없이 GIT는 프로젝트의 변경이력을 거의 즉석에서 빨리 알아낼 수 있습니다.
만약 어떤 파일의 현재 버전과 그 파일이 1개월 동안 변경된 사항을 알고 싶을 경우, 기존의 VCS의 경우 원격 서버에 접속하여, 원격 서버에 변경된 이력에 대한 추출을 요청하거나, 변경된 이력을 로컬 시스템에서 알아내기 위해 원격 서버에서 예전 버전의 파일을 가져와 추출을 하게 됩니다.
하지만, GIT의 경우는 이런 절차가 필요 없이 바로 로컬 시스템에서 변경 이력을 알아 낼 수 있습니다.
GIT는 기본적으로 프로젝트의 변경 이력을 저장하기 위해 네트워크에 접근할 필요가 거의 없기 때문에, 개발자가 비행기 또는 기차에 타서 소스 코드의 변경을 할 경우, 버전 관리를 위해 네트워크를 통해 원격 서버에 접속하지 않아도 됩니다.
또한 집에서 작업을 했을 경우, 서버가 방화벽에 막혀 접근하지 못한다 하더라도, 개발자는 그것과 상관 없이 프로젝트의 버전 관리 작업을 수행할 수 있습니다.
다른, 버전 관리 시스템에서 이런 것은 불가능 합니다. 예를 들면 Perforce에서는 버전 관리 서버를 접속할 수 없을 경우 거의 모든 버전 관리 작업을 수행할 수 없습니다.
Subversion이나, CVS의 경우 파일의 편집은 할 수 있지만, 변경 사항을 버전 관리 데이터베이스에 입력 할 수 없습니다.
(왜냐하면, 버전 관리 서버를 접속할 수 없기 때문 입니다.)
GIT의 이런 점은 기존 VCS와의 가장 큰 차이점의 하나이며, 개발자의 버전관리 방식을 근본적으로 바꿀 수 있는 매우 놀라운 개념 입니다.
1.3.3. GIT는 완전성을 가진다.
GIT에서 관리하는 모든 데이터는 버전 관리를 수행하기 위해 저장할 때, 모든 데이터에 대해 체크섬(Checksum)을 생성하며 , 체크섬을 기준으로 데이터를 복원 합니다. 이런 점은 GIT는 데이터베이스에 저장된 파일을 사용자가 임의로 변경할 수 없다는 것을 의미 합니다. 그리고 이 기능은 GIT의 가장 기본이 되며, GIT의 기본 개발 철학 입니다.
때문에, GIT는 데이터 베이스에 저장된 파일의 인위적인 변경 또한 오류 사항을 감지해 낼 수 있기 때문에, 설사 네트워크로 프로젝트 데이터를 전송중에 오류가 생긴다 하더라도, 오류가 발생한 파일을 사용자가 받을 일은 없습니다.
GIT의 체크섬 생성은 SHA-1 해쉬라 불리는 것을 이용합니다. SHA-1 해쉬는 16진수의 문자(0-9와 a-f로 구성)로 조합된 40개의 문자열로, GIT를 통하여 저장된 파일의 내용 또는 디렉터리의 구조를 바탕으로 계산 됩니다.
GIT에서 SHA-1 해쉬를 통하여 생성된 체크섬은 다음과 같이 보이게 됩니다.
24b9da6552252987aa493b52f8696cd6d3b00373
GIT는 SHA-1 해쉬를 많이 이용하기 때문에, GIT를 여러분이 이용하면서 이런 해쉬값을 자주 볼 것 입니다.
사실, GIT가 소스코드 파일을 저장할 때는, 파일명으로 저장하는 것이 아니라 이런 SHA-1 해쉬를 이용하며, SHA-1 해쉬 값을 해석하여 파일이 저장된 내부 데이터베이스 주소를 찾게 됩니다.
따라서, 인증되지 않은 누군가가 서버를 해킹하여 GIT 데이터베이스를 접근하더라도, 해석은 불가능하며, 인위적인 변경 또한 하지 못합니다.
1.3.4. GIT는 데이터를 추가만 한다.
개발자가 GIT를 사용할 경우, GIT는 거의 대부분 데이터베이스에 데이터를 추가하는 작업만 수행 합니다.
이미 저장된 데이터베이스를 어떤 방법에 대해 이전 시점으로 복원하거나, 데이터를 지우는 것은 매우 어렵습니다.
물론, 아직 Commit를 하지 않은 파일들의 경우 다른 VCS와 마찬가지로 파일을 지우거나 쉽게 변경할 수 있습니다.
하지만, GIT에 파일을 Commit 하고, 정기적으로 GIT의 데이터베이스를 다른 리포지터리(repository : 저장소)에 푸쉬(GIT가 현재 관리하고 있는 repository를 다른 서버 또는 PC의 repository에 전송하는 조작)을 한다면, 저장된 파일을 지우거나 변경하는 작업은 더욱 어려워 집니다.
이것은 사용자의 실수로 인해, 프로젝트 데이터가 망가지거나 손실되는 확률을 매우 줄여주며, 이것은 GIT를 이용하는 가장 큰 장점 중에 한 가지 입니다. GIT가 데이터를 어떻게 저장하고 있는지, 또한 사용자가 삭제한 파일을 복원하고자 할 때 GIT가 어떻게 복원하는 지에 대한 상세한 설명은 Chapter 9의 "Under the Covers" 항목을 참고하시기 바랍니다.
1.3.4. GIT는 파일을 저장하기 위해 세 가지의 상태를 가진다.
이 항목은 GIT를 효율적으로 이용하기 위해 알아야 하는 매우 중요한 사항 입니다.
GIT는 파일을 저장하기 위해, Working, Staging, Commit의 중요한 세가지 상태를 가집니다.
Commit 상태는 데이터가 GIT에 안전하게 저장되고 있다는 것을 의미합니다.
Working 상태는 파일의 변경 작업을 하고 있지만, 이것이 GIT의 데이터베이스에 아직 저장되지 않은 상태를 말합니다.
Staging 상태는 GIT 데이터베이스에 Commit를 하기 위해 현재 수정된 파일에 TAG를 붙인 상태를 의미 합니다.
이것은 GIT는 프로젝트를 Git 디렉터리, Working 디렉터리, Staging의 세가지 디렉터리에 나누어서 다음과 같이 관리 합니다.
그림 1-6. GIT의 Working, Staging, Git 디렉터리 명세
Git 디렉터리는, 해당 프로젝트를 위한 메타데이터(GIT가 관리하는 파일이나 디렉터리 등의 프로젝트에 대한 변경 이력 및 요약 사항 등)와 프로젝트의 데이터베이스가 위치 합니다. 이것은 GIT의 가장 중요한 부분으로 다른 컴퓨터로 부터 리포지터리(repository)를 클론(GIT 리포지터리를 복사 하는 것) 했을 때에, 가져오는 데이터 입니다.
Working 디렉터리는, 프로젝트의 단일 버전에 대한 체크아웃 데이터(변경 이력)가 저장 됩니다. 이것은 사용자가 언제나 쉽게 수정할 수 있도록 하기위해 로컬 디스크에 저장 됩니다.
Staging 디렉터리는, Working 디렉터리에서 변경된 이력을 모아놓은 집합 이라고 생각하시면 됩니다.
Git 디렉터리에 최종적으로 프로젝트를 저장하기 위해, 변경 이력을 모아놓는 임시 공간이라고 생각하면 됩니다.
여러분들이 GIT를 이용할 때 나오는 TAG와 Index는 여러가지 변경 이력을 어떤 시점에 한꺼번에 모아놓은 것 입니다.
Staging 디렉터리는 로컬 디스크에서 개인이 수행하는 비슷한 종류의 것이라고 생각 하시면 됩니다.
기본적인 GIT의 동작 순서는 다음과 같이 진행 됩니다.
1. 개발자는 작업 디렉터리에 있는 파일을 수정 합니다.
2. 수정된 파일들을 모아 정리하여 만든 Snapshot을 Staging 디렉터리에 추가하고 저장 합니다.
3. GIT 디렉터리에 저장 합니다. 이것은 Staging 디렉터리에 저장된 파일을 취득해,
앞으로 영구 불변의 상태를 유지하는 Snapshot로써 GIT 디렉터리에 저장하는 것 입니다.
만약 파일의 특정 버전이 GIT 디렉터리안에 있다고 한다면, 이것은 GIT 서버에 위탁 상태라고 봅니다.
만약 현재 파일이 수정되고 있고, 현재 Staging 디렉터리에 계속 더해지고 있다면, 이것은 Staging 상태 입니다.
그리고, 파일을 Checkout(원본 파일을 버전 관리 시스템으로 부터 받아오는 것)하고 나서 내용을 변경 했지만, Staging 되어 있지 않다고 한다면, 이것은 Working 상태 입니다.
제 2장에서는 이러한 상태와 어떻게 이것들을 이용하는지, 또는 어떻게 Staging 부분을 생략하는 지에 대해 자세하게 알아보도록 하겠습니다.
좋은 내용 감사합니다.ㅎ_ㅎ