Let’s Git it (1)

3 minute read

이번 글은 Git의 탄생과 내부 동작 방식을 깊이 알아보고 이해하기 위한 시리즈의 첫 포스팅이다.

History of Git

리눅스 커널의 초기 유지보수 단계 (1991-2002) 시절에는 소프트웨어의 변경은 패치와 아카이브된 파일 형식으로 전달되었다. 2002년부터 리눅스 커널 프로젝트는 사유(proprietary) DVCS인 BitKeeper를 사용했으나, 2005년에 리눅스 커널 커뮤니티와 BitKeeper의 관계가 분열되며 해당 툴의 무료 사용권이 박탈되었다. 따라서 Linus Torvalds를 포함한 리눅스 개발 커뮤니티는 BitKeeper로부터 얻은 몇 가지 교훈을 통해 그들만의 툴을 개발하기로 결심한다.

그들은 새로운 툴에 다음과 같은 특징을 적용하고자 하였다.

  • 빠른 속도
  • 간단한 디자인
  • 비선형적(Non-linear) 개발에 대한 강력한 지원 (수 천개의 병렬적 브랜치)
  • 완전히 분산된
  • 리눅스 커널과 같은 대형 프로젝트를 속도와 데이터 사이즈 측면에서 효율적으로 다룰 수 있는

그러하여 2005년에 Git이라는 툴이 탄생하였고 지금까지도 오픈 소스로써 위 특징들을 자랑한다.

Linus Torvalds는 2005년 4월 7일 그의 첫 번째 Git commit 메시지를 다음과 같이 만들었다.

Initial revision of "git", the information manager from hell

이 커밋에 그는 README라는 파일을 포함시켰고, 첫번째 문단이 다음과 같았다.

GIT - the stupid content tracker

"git" can mean anything, depending on your mood.

 - random three-letter combination that is pronounceable, and not 
   actually used by any common UNIX command.  The fact that it is a
   mispronunciation of "get" may or may not be relevant.
 - stupid. contemptible and despicable. simple. Take your pick from the 
   dictionary of slang.
 - "global information tracker": you're in a good mood, and it actually
   works for you. Angels sing, and a light suddenly fills the room. 
 - "goddamn idiotic truckload of sh*t": when it breaks

This is a stupid (but extremely fast) directory content manager.  It  
doesn't do a whole lot, but what it _does_ do is track directory
contents efficiently.

Linus Torvalds는 리눅스 커널 개발을 위한 빠르고 효율적인 VCS가 절실하게 필요했던 것 같다. 메시지를 보면 그가 완성한 Git은 그가 원한 기본적인 기능들은 있지만, 많은 개선이 필요하다고 주장한다. (1주 만에 Git의 초기 기능을 다 개발한 것을 생각하면 납득이 간다)

더 나아가 그는 자신이 이기적인(egotistical) 사람이라, 자신이 만든 프로그램을 자기 이름을 본떠서 만든다고 하였다 - 첫째로 Linux, 그리고 Git. 참고로 git의 사전적 정의는 영국 슬랭으로써 “고집센, 이기적인 사람”을 의미한다.

It’s all about version control

Linus의 첫 커밋 메시지를 보면, git이 디렉토리 내용을 추적하고 관리해준다고 적어놨다. 다시 말해, git은 디렉토리에 포함된 내용의 버전을 관리해준다.

컴퓨터 파일 시스템에 존재하는 파일들은 시간이 지나면서 변경될 수있고, 특정 버전을 기록하거나, 다시 돌아가야 하는 일이 발생할 수도 있다. Git과 같은 Version Control System (VCS)은 파일들을 특정 버전으로 다시 되돌리거나, 두 버전 간의 변경 사항을 확인하거나, 문제점이 발생했을 때 누가 마지막으로 수정했는지 등의 정보를 모두 추적하도록 도와준다. 쉽게 말해, 파일을 실수로 잘못 변경하거나 지웠을 때, git이 우리에게 큰 도움이 될 수 있다. 그리고 Linus가 말했듯이 git은 매우 적은 오버헤드로 이를 효율적으로 수행한다.

Local VCS

많은 사람들이, 파일의 버전을 관리할 때, 파일을 여러 다른 timestamp별로 구분된 디렉토리에 복사하여 관리한다. 이는 매우 간단한 방법이지만 에러가 발생하기 쉽다 - 의도치 않은 디렉토리에 파일을 잘못 복사하거나 지울 수 있다.

이러한 이슈를 해결하기 위해, 프로그래머들은 파일들의 모든 변경 사항을 심플한 데이터베이스에 저장하는 로컬 VCS를 개발하였다.

local-vcs

인기가 많았던 툴 중에 하나가 Revision Control System (RCS)이다. RCS는 파일 버전 간의 diff (patch set)를 특정한 포맷으로 디스크에 저장해놓고, 이러한 패치들을 조합하여 특정 시간대에 파일이 어떻게 생겼었는지 재현할 수 있는 방식을 사용했다.

Centralized VCS

로컬에서 혼자 버전 관리는 된다고 하여도, 여러명의 개발자가 동일한 파일에 대해 협업을 할 때 또 다른 이슈가 발생하였다. 이 문제를 다루기 위해, Centralized Version Control Systems (CVCSs)가 개발되었다. CVS, Subversion, Perforce와 같은 CVCS들은 하나의 서버가 모든 버전의 파일들을 보관하고, 여러 명의 클라이언트들이 이 중앙 서버에서 파일들을 check out하는 방식을 사용한다. 이는 오랫동안 버전 관리의 표준 방식으로 사용되어 왔다.

cvcs

CVCS는 로컬 VCS와 비교하였을 때, 여러 명이 하나의 프로젝트의 버전 관리를 편하게 할 수 있다는 장점은 있었지만, 몇 가지 단점도 있다. 중앙 서버가 모든 파일 버전을 관리하기 때문에, 해당 서버가 다운된다면, 그 시간 동안에는 누구도 변경 사항을 저장할 수 없다. 그리고 만약 중앙 데이터베이스가 존재하는 하드 디스크가 날아가고 백업이 되어 있지 않다면, 각 프로그래머가 자신의 로컬에 가지고 있는 스냅샷 말고는 모든 것을 잃게된다. 로컬 VCS 또한, 특정한 곳에 프로젝트의 전체 히스토리를 보관하기 때문에, 모든 것을 잃을 수 있는 리스크가 존재한다.

Distributed VCS

위 문제점들을 해결하기 위해 분산 VCS가 나왔다. Git, Mercurial, Bazaar, Darcs와 같은 분산 버전 관리 시스템에서는 클라이언트가 파일들의 마지막 스냅샷을 check out하는 것에 그치지 않고, 프로젝트의 전체 히스토리를 포함하는 레포지토리 자체를 가져간다. 따라서, 여러 시스템이 특정 서버를 통해 협업을 하는 상태에서 서버가 죽는다고 하여도, 클라이언트 한 명의 레포지토리를 서버에 복사하여 다시 복구할 수 있다. 따라서, 클라이언트가 클론한 레포지토리는 모든 데이터의 완전한 백업으로 볼 수 있다.

dvcs

출처

https://git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git

https://en.wikipedia.org/wiki/Git

Leave a comment