Git 개념 잡기

들어가며

본 포스트에서는 Git은 무엇이고 왜 쓰는지, Git이 어떻게 파일의 버전을 추적하는지 알아보겠습니다. 본 포스트 이후에는 Branch, Staging 등 여러가지 개념들과 함께 실질적으로 Git을 활용하는 방법을 다룰 예정입니다.

Git

Git은 프로젝트의 버전을 관리하기 위해 사용하는 분산 버전 관리 시스템(DVCS, Distributed Version Control System)입니다. 파일의 변경 사항을 추적하여 프로젝트의 버전을 관리할 수 있으며, 이를 레포지토리(Repo/Repository)라는 하나의 단위로 묶어 원격 서버에서 관리함으로써 프로젝트에 참여하는 사람이라면 누구든 언제 어디서나 해당 프로젝트를 로컬 환경에 내려받아 작업할 수 있도록 합니다.

왜 쓰나요?

Git, 특히 GitHub 등의 서비스를 통해 온라인으로 활용 가능한 버전 관리 서비스는 현재 프로그래머의 필수 덕목입니다. 왜 그렇게까지 Git을 사용하는지 알아보겠습니다. 정말 많은 장점이 있지만, 여기에서는 순수하게 Git 클라이언트의 장점만을 알아보겠습니다.

편리한 버전 관리

프로그램이 커질수록, 다른 모듈이나 라이브러리와의 연계가 많아질수록 변화를 주기가 어려워집니다. 한 번 수정했다가 잘못됐을 때 이전으로 돌아가기 힘든데, 프로그램이 클수록 그러한 경향이 더욱 심해지기 때문입니다. 루미큐브 해보셨나요? 친구들끼리 루비큐브를 즐기다 보면 크게 한 번 바꿔보려다가 꼬였는데 돌아가지도 못하는 참사가 발생하곤 합니다.

물론 Ctrl-Z를 사용할 수는 있겠지만, 큰 변화를 되돌리는 데 이것만으로는 부족한 경우가 많죠. 이때 Git을 잘 활용하면 모든 변경사항을 보존할 수 있으므로, 작업 이전 시점으로 파일을 되돌리기 쉽습니다.

그뿐이 아닙니다. 모든 변경사항을 보존할 수 있다는 것은, 작업 이전 시점뿐만이 아니라 그 전의 어느 시점의 상태이든 다시 복원해낼 수 있다는 뜻입니다. 프로그램이 변화해 온 히스토리를 살피면서 흐름을 파악하는 데도 용이합니다. 어떤 파일들의 어느 부분을 누가 언제 작업했는지 파악할 수도 있어 업무에서 정말 소중한 존재입니다.

분산 버전 관리 시스템인 Git은 서버에 작업물과 히스토리를 게시하여 이를 로컬에 복제한 후 작업합니다. 만약 로컬에서 문제가 발생했다면 원격 저장소에 저장된 파일과 히스토리를 그대로 다시 받아 작업하면 그만입니다. 또한 서버에서 작업하는 만큼 함께 작업하는 누구나 쉽게 접근할 수 있으며 작업물을 공유하고 서로의 진행 상황을 추적, 병합하는 최고의 방법이 되었습니다.

여러 버전 관리 방법의 자세한 내용과 변천 과정은 아래의 문서를 참고해 주세요!

Git - 버전 관리란?

릴리스

프로그램의 미덕 중 하나는 재사용입니다. 잘 작성한 모듈이 있다면, 다른 프로젝트에서 같은 기능을 하는 모듈을 새로 작성하기보다 기존의 모듈을 가져다 사용하는 방식을 택할 것입니다.

하지만 프로그램은 언제나 변합니다. 단순 리팩터링뿐만 아니라 각종 기능을 추가하거나 기존의 잘못된 구현을 고치는 경우도 많죠. 제 코드를 다른 사람이 활용할 수 외부에 노출한 API가 수정되는 일도 잦습니다. 그런데 이미 기존의 제 코드를 이용하고 있던 사람들은 제가 코드를 수정할 때마다 자신의 코드도 수정해야 하는 걸까요? 아니면, 그 때문에 제가 제 코드를 수정하지 못하는 건 아닐까요?

물론, 그래서는 안 됩니다. 그래서 잘 작성된 안정적인 버전을 다른 사람들이 이용하도록 발표(Release)합니다. 재사용 단위로서, 이러한 릴리스 버전은 해당 코드를 사용하는 개발자들이 주목하는 사항입니다. 기능 개선이나 보안 문제 해결 등 해당 코드를 사용하는 프로젝트에 굉장히 중요하게 작용하는 내용이 있다면 빠르게 적용해야 하며 각 환경마다 가용한 버전이 다를 수도 있는 등 여러 이유가 있습니다.

GitHub에 릴리스된 버전들. 자료는 LLM 라이브러리인 llama.cpp의 Releases

Git을 잘 활용한다면, 작업하던 버전 중 다른 사람들이 이용해도 문제 없을 버전을 골라 릴리스하는 데 활용할 수 있습니다. 해당 기술 스택의 생태계가 더욱 풍부해지고, 더욱 많은 사람들이 편리하게 새로운 프로그램을 만들어낼 수 있는 배경이 됩니다.

협업

여러 사람들과 함께 작업하다 보면 서로의 작업 내용을 어떻게 합칠지 고민이 됩니다. 고등학생 시절, Git에 대해 아무것도 모를 때는 프로젝트 폴더째로 압축한 파일을 서로 메일로 주고받으면서 작업했던 기억이 있습니다. 하지만 짐작하시듯, 이러한 방식은 전혀 바람직하지 않습니다.

Git은 협업을 위한 최적의 환경이기도 합니다. 차차 설명할 예정이므로 간단히 이야기하자면, Git은 여러 작업 히스토리를 하나로 병합하고 관리하는 기능을 제공하므로 여러 명이 작업하더라도 번거로운 과정 없이 쉽게 프로젝트를 진행할 수 있습니다. GitHub 등의 서비스를 이용하면 코드 리뷰, 조직 관리, 자동화 등 정말 많은 기능을 활용하면서 프로젝트를 진행할 수 있고, 이러한 기술을 최대한 잘 활용하는 것이 유능한 프로그래머의 최소 요건이 되었습니다.

Git 버전 관리의 기본

Git은 파일의 변경 과정을 모두 스냅샷(Snapshot)으로 저장합니다.

이미지 클릭 시 원본 페이지 이동

위 이미지는 Git이 버전을 관리하는 방식을 나타냅니다.

버전 1의 파일 A, B, C는 시간이 지남에 따라 여러 수정을 거치게 됩니다. 첫 업데이트인 버전 2에서는 A와 C만 수정하여 각각 A1, C1이 되었고 B는 수정하지 않은 상태입니다. 이때 Git은 A1과 C1 파일은 새롭게 생성하지만, 디스크 공간을 절약하고 성능을 개선하기 위해 변경 사항이 없는 B는 파일을 그대로 복제하지 않고 원본 파일에 대한 링크만 제공합니다. 버전 2에서 3으로 넘어가면서 C1만을 수정하고 A1와 B는 수정하지 않았으므로 버전 3의 A1은 버전 2의 A1을, B는 버전 1의 B를 향하는 링크가 됩니다.

Git을 활용하면 향후 어떤 변경 사항이 발생하더라도 다시 이전 상태로, 즉 이전 버전으로 다시 돌아올 수 있습니다. 위 이미지처럼 변경 사항이 쌓임에 따라 여러 버전이 존재할 수 있으며 하나의 버전을 하나의 커밋(Commit)이라고 합니다.

위 두 가지 변경 사항에 각각 "주문 추가"와 "주문 내용 변경"이라고 이름을 붙이겠습니다. 이렇게 변경 사항을 저장하는 단위는 커밋, 여기에 붙이는 이름을 커밋 메시지(Commit Message)라고 이해하시면 됩니다.

각 줄에 커밋 ID와 커밋 메시지가 나타납니다. 위로 갈수록 최근에 저장된 커밋입니다

이렇게 변경 사항이 쌓이고 쌓여 히스토리가 되고, 위와 같이 프로젝트가 진행되는 과정을 보여 주게 되는 것입니다. 앞서 언급한 예시를 위 형태로 나타낸다면, 아마 히스토리는 다음과 같이 나올 것입니다.

* f23fk3f (HEAD -> master) 주문 내용 변경
* 2jdk2d2 주문 추가

말씀드린 사항 외 여러가지 기능들은 위와 같은 버전 관리 방법을 바탕으로 더욱 풍부한 사용성을 제공하기 위한 것으로, 다음 포스트부터 천천히 설명드리도록 하겠습니다. 우선은, Git이 변경 사항을 저장하는 방식에 대해서만 확실하게 알고 가도록 합시다.

마치며

이 내용은 Git을 활용하여 개발하는 방식의 원리 중 아주 일부분만 보여드린 것으로, 자세한 사항은 다음 포스트부터 차근차근 알아가 보도록 하겠습니다!

다음 글

Git 설치 및 설정부터 기초 사용법까지
Git 설치부터 SSH Key 등록, Repository 생성, 기본적인 명령어들까지