코딩하는 개굴이

[Git 이해하기] Git 이 관리하는 방법 본문

GIT

[Git 이해하기] Git 이 관리하는 방법

개굴이모자 2023. 7. 16. 23:32
반응형

Git 이란, 개발자들에게 뗄레야 떼기 힘든 소프트웨어 중 하나이다.
매 순간마다 사용하고 있으나, 실제로 정확히 어떤 역할을 하는지 어떤 상황에서 어떻게 명령해야하는지 주저될 때가 있다.
만일 제대로 모르는 상태에서 명령어를 사용하게 된다면 생각치 못한 결과를 만들어 크게 곤욕을 치를 수도 있다.
(경험담이기도 하다.)


따라서, 이번 포스팅에서는 깃의 베이스를 제대로 알아보고자 한다.

 

 


Git 의 등장

소프트웨어를 개발할 때 버전 관리 툴은 매우 필수적이다. 새로 코드를 작성하거나 기존 소스를 수정하거나 프로그래머는 소스의 과거 히스토리를 파악하거나 개발 시 현재 작업한 내역을 저장/보존해야한다. 이때 사용되는 툴이 버전 관리 툴이다. 버전 관리 툴은 현재 크게 SVN, Git 이렇게 2가지가 존재한다.

SVN (SubVersion)은 여러명이서 작업하는 프로젝트의 버전 관리나 각자 만든 소스틔 통합과 같은 문제들을 해결하기 위해 중앙에 저장소를 만들어 그곳에 소스를 저장해 소스 중복 및 충돌 등을 해결하기 위한 형상관리/소스 관리 툴이다.

SVN 의 경우, 반드시 리모트 서버를 두어야하고, 저장소를 1개만 두기 때문에 만일 불의의 사고로 데이터가 소실될 경우 복구가 어려울 수 있다. 그러나, 원격 저장소에서 클론 후 작업이 끝난 후 커밋만 해서 저장하면 되는 간단한 구조였지만, 그만큼 소스코드의 충돌 가능성 또한 높았다.

Git 은 2010년 초반 안드로이드의 대중화 후 혜성처럼 떠올라 현재 가장 많이 사용되는 버전 관리 툴로 자리잡게 되었다.

 

 


 

 

Git 의 장점

Git은 비록 초보자가 이해하기 어려운 사용법으로 처음엔 다수의 거부감을 불렀지만 버전 관리에 필요한 모든 기능들을 제공하며 무엇보다 분산 관리식 프로세스로 사용자들을 확보했다.

Git은 저장소/로컬 등 클론만 했다면 저장소 자체가 복구 가능하며 git 으로 작업햇던 파일들이 존재한다면 remote 의 저장소가 날아가도, local 이 날아가도 다른 사용자들이 git 브랜치를 보유하고 있다면 언제든지 복구가 가능하다.

버전관리로 PC 뿐 아니라 웹 상에서도 히스토리와 소스를 직접 볼 수도 있으며, 속도 및 데이터 사이즈, 비선형 개발에 대한 강력한 지원이 가능하다는 장점으로 매우 효율적인 버전 관리 솔루션을 제공하고 있다.

 

Git 의 낙관적 잠금( Optimistic Locking ) 사용

엄격한 잠금 (Strict locing) 을 사용했던 SVN 에 비해 Git 은 낙관적 잠금을 사용하는데, 엄격한 잠금은 특정 코드의 복사본은 한번에 한 사람만 가질 수 있는 반면, 낙관적 잠금은 대부분 서로 변경한 영역에 충돌이 없다는 가정을 하므로 다수의 개발자가 같은 파일에 있는 동일한 코드를 이용할 수 있도록 한다. 실제로 제대로 프로젝트에서 역할 분담을 잘 수행했다면 충돌이 발생할 일이 많거나 심각해지지 않는다.

 

Git 의 파일 추적

Git은 파일 자체를 추적하지 않고 내용 단위 즉, 파일 내부의 변수/함수를 구성하는 각 문자와 줄을 추적한다. 따라서 저장소의 전체 이력을 저장하는데 필요한 공간이 줄어들고, 두 파일 사이에서 함수와 클래스의 이동을 파악하거나, 복사된 코드가 어디에서 나온 것인지 등을 파악하는 작업이 가능하다. 또한 Git 은 빈 디렉토리를 추적하지 않는다. (실제로 패키지든 파일이든 하나를 추가한다고 하더라도 안에 파일이 없다면 인식되지 않는 것을 볼 수 있을 것이다.) 따라서 만약 빈 디렉터리를 추가하고자 한다면 해당 디렉터리 안에 빈 파일을 임의로 하나 생성해 넣어야한다.

 

 


 

 

Git 이 관리하는 방법

Git은 총 3가지 단계로 상태를 분류해 관리를 하고 있다. 이는 working directory, staging area, git directory로 단게를 분류하고 있고, 파일의 경우 Committed, Modified, Staged 이렇게 세가지로 해당 단계들을 넘나든다.

 

파일의 상태 분류

  • Commited: 데이터가 로컬 데이터베이스에 안전하게 저장되었다는 것을 말한다.
  • Modified: 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 상태를 말한다.
  • Staged: 현재 수정한 파일을 커밋할 것이라고 표시한 상태이다.

Git 의 3가지 단계

  • Git Directory: 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳으로, Git의 핵심이다. 다른 컴퓨터에 있는 저장소를 클론할 때, Git Directory 가 만들어진다.
  • Working Directory: Git Directory 가 디스크에 있는고 그 디렉터리에 압축된 데이터베이스가 있는데, 그곳에서 파일을 가져와 Working Directory 를 만든다. 이는 특정 버전을 checkout(체크아웃) 한 것이다.
  • Staging Area: Git directory 안에 존재하며, 단순한 파일이고, 곧 커밋 할 파일들에 대한 정보를 저장한다. 인덱스라고 불리기도 한다.
스냅샷이란? Git의 작동 방식은 기본적으로 스냅샷 방식이다. 이는 파일의 상태 전체 를 그대로 저장해 비교하는 방식이다.
반대로 SVN 의 경우 델타 방식을 사용하는데, 이는 파일의 변화가 생겼을 때, 변화된 사항만 기록하는 방식이다.

언뜻 보았을 때 차이점만 저장하는 것이 효율적인 것이 아닌가 하는 생각이 들 수 있지만,
만일 파일이 100번 수정된 이력이 있는 상태에서, 52번째 수정된 파일 상태를 보고 싶다고 가정해보자.
그럴 경우 델타 방식은 1번을 기반으로 52번까지의 변화를 모두 받아와 연산하여 산출해 주어야한다.
그러나, 스냅샷 방식은 그 52번의 수정 사항을 바로 불러오기반 하면 되고,
버전 별의 차이점을 보고 싶다면 두 스냅샷을 비교하기만 하면 된다.

추가로 SVN이 시간 순으로 관리하면서 파일들의 집합을 통으로 저장하는 방식을 취한다면,
Git은 데이터를 파일 시스템의 스냅샷의 연속으로 취급하고 크기가 매우 작다.
따라서, 커밋하거나 프로젝트의 상태를 저장할 때마다 파일이 존재하는 그 순간을 매우 중요하게 여긴다.
파일이 달라지지 않았다면 파일을 새로 저장하지도 않고 다만
이전 상태의 파일에 대한 링크만 저장하여 데이터를 스냅삿의 스트림 처럼 취급한다.

 

Git 이 하는 일

위 내용을 기반으로 이제 이해할 수 있을 것이다. Git 이 하는 일은 기본적으로 아래와 같다.

  • Working Directory 에서 파일을 수정한다.
  • Staging area에 파일을 Stage 해서 커밋할 스냅샷을 만든다.
  • Staging area 에 있는 파일들을 커밋해 Git Directory 에 영구적인 스냅샷으로 저장한다.

Git 디렉터리에 있는 파일들은 모두 Committed 상태이며, 파일을 수정하고 Staging area 에 추가되었다면 해당 파일은 Staged 상태이다. 또한 Checkout 후 수정했지만 아직 Staging area 에 추가되지 않았다면 Modified 상태인 것이다.

 

 


 

Git 의 무결성

Git은 모든 데이터를 저장하기전에 체크섬 (해시) 를 구하고, 그 체크섬으로 데이터를 관리한다. 체크섬은 Git에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git의 기본 철학이기에 Git 없이는 체크섬도 무의미하고 데이터를 잃어버릴 수도 있다. Git은 SHA-1 해시를 이용해 체크섬을 만든다. 만든 체크섬은 40자 길이의 16진수 문자열로, 파일의 내용이나 디렉터리 구조를 이용해 체크섬을 구하며, 파일의 이름 도한 저장하지 않고 해당 파일의 해시로 저장한다. SHA-1 의 예시는 아래와 같다.

7b1558c92a7f755d8343352d5051384d98f104e4

 

왜 SHA-1 해시일까?

SVN 과 같은 중앙 집중식 버전 관리 시스템을 이용하면, 서버가 각 커밋에 고유 번호를 할당하는 것으로 모든 것이 충분했는데,

분산 환경에서 작업 중이라면 그렇게 간단하지 않다.

 

두명이 동일한 코드를 이용해 작업하는 상황을 가정해보자. 그럴 경우 누가 커밋한 것인지 어찌 판단해야할까?

 

Git 은 이를 SHA-1 해시를 이용해 문제를 해결한다. SHA 는 보안 해시 알고리즘 (Secure Hash Algorithm) 의 약자이다.

SHA 는 데이터에 대한 짧은 문자열이나 요약 메시지 만으로도 다른 해시와 충돌할 가능성이 거의 없도록 설계되었으므로, Git 은 커밋하는 사람의 정보, 현재 시각과 같은 저장소의 몇가지 메타데이터를 이용해 커밋 명을 생성한다. 이런 정보를 조합해 다른 커밋과 충돌할 가능성이 낮은 고유한 해시를 생성한다. 이렇게 생성된 40자리의 해시 값은 기억하기 어렵고 불필요하게 길기 때문에, Git에서는 짧은 해시를 이용할 때는 7자리의 문자열을 이용하기도 한다.

 

 


 

참고 링크

반응형

'GIT' 카테고리의 다른 글

LFS 를 적용해보자! (feat. Trouble Shooting)  (1) 2023.07.14
[Git] Pull Request 를 Git 에 끌어오자!  (0) 2023.04.17
Comments