Git 구조 되짚어보기

뾰족머리삼돌이·2025년 1월 21일
0

기타

목록 보기
3/7
post-thumbnail

Git의 기본구조를 파악하고 있다면, 실제로 Git을 사용할 때 어느단계에서 문제가 발생했고 원인이 무엇인지 대략적으로 파악할 수 있다. 따라서, 이번 포스팅에서는 대략적인 Git의 구조에 대해 기록할 예정이다.

Git

Git은 소스코드 관리를 위해 가장 많이 사용되는 스냅샷 기반의 분산 버전 관리 시스템(DVCS)이다. 다른 소스코드 관리도구와 비교했을 때, 가장 특징적인 부분은 분기를 나눠 처리할 수 있는 모델에 있다.

즉, 특정 상태(버전)에서의 코드정보를 복제하여 마음대로 수정한 뒤에 실제로 반영할지 결정할 수 있다는 점이다.
당연하게도 수정 전의 상태로 되돌리는 것이 가능하기때문에 마음놓고 코드를 수정해도 된다.

이때문에 하나의 메인 소스코드를 두고 다수의 사람들이 각자의 복제본으로 작업할 수 있게된다.

커밋 기록 기반으로 생성한 스냅샷으로 소스코드를 관리하며, 각 branch의 상태는 해당 커밋기록에서의 최신상태를 참조하는 형식이다. 변경된 데이터만 스냅샷을 생성하며 참조 및 압축을 통해 저장되므로 저장공간이 크게 낭비되지 않는다.

기본 구조

앞서 소개했던 메인 소스코드는 원격 저장소(GitHub, GitLab 등)에 저장된다.
사용자는 이 원격저장소에 있는 소스코드를 복제(clone) 하여 사용자의 컴퓨터로 가져온다.

복제된 소스코드는 사용자의 워크스페이스와 로컬 저장소에 저장되며, 로컬 저장소 중에서도 main(master) 분기로 관리된다. 이렇게 코드를 가져오게되면 원격 저장소의 소스코드와는 독립적인 작업환경을 가지게 된다.

이미지에서 확인할 수 있듯이 사용자 컴퓨터 내에서 소스코드(Git 객체)는 workspace, index, local repository로 구분된다. 각각의 단계는 아래와 같이 표현할 수 있다.

workspace : 흔히 사용하는 파일시스템
index : 커밋을 통해 로컬 저장소에 저장되기 이전의 파일관리, add명령으로 stage된 파일들이 저장된다
local repository(.git 폴더) : 원격 저장소와 독립적으로 log, history, commit, diff 등을 관리

라이프사이클로 일반적인 Git과 GitHub의 사용을 표현하자면 아래 형태가 된다.
원격저장소 =(clone)=> 워크스페이스 =(add)=> 인덱스 =(commit)=> 로컬저장소 =(push)=> 원격저장소

로컬 저장소의 소스코드를 원격 저장소에 반영하기 위해서는 원격 저장소(ex: GitHub) 계정정보가 필요하다.
또한, 원격 저장소 타겟 Branch의 최신상태와 일치해야하며 그렇지 않을경우에는 pull이나 fetch, merge로 최신화 해야한다.

추가적인 내용

Git 에서는 add, commit 등 외에도 fetch, merge, pull 등의 명령이 존재한다.
또한, main(master) 브랜치에서 다른 브랜치로 분기를 생성하고, 작업을 처리하는 것도 가능하다.

fetchpull은 모두 원격저장소의 소스코드로 로컬저장소의 내용을 업데이트하는 명령어다. 따라서 해당 명령을 동작시키면 로컬 저장소에 새로운 내용들이 반영되며, pull의 경우 워크스페이스도 원격저장소의 내용으로 업데이트된다.

merge의 경우, 원격 저장소와 동기화된 로컬 저장소의 내용을 워크스페이스와 병합하는 작업이 이뤄진다.

pull은 원격저장소의 내용이 로컬저장소와 워크스페이스에 모두 동기화되므로, fetchmerge가 모두 이뤄지는 명령이다.

앞선 이미지에 나타난 명령을 추가로 알아보자면, 아래와 같다.

  • checkout : 특정 branch나 커밋 상태로 동기화하는 명령어
    워크스페이스의 내용이 변경되는 작업
  • diff : 트리나 인덱스 간의 변경사항을 표시하는 명령어
    워크스페이스의 내용이 변경되지는 않으나 워크스페이스 단계에서 비교사항을 확인할 수 있음

로컬 저장소( .git )

원격 저장소의 소스코드를 clone을 통해 가져오게되면 항상 생성되는 디렉토리가 있다.

바로, .git이라는 디렉토리인데 기본적으로 숨김처리가 되어있어서 따로 설정을해줘야 표시된다.
이 디렉토리는 앞서 살펴봤던 구조에서 로컬 저장소를 의미한다.

내부에는 인덱스에 대한 내용도 포함되며, 이 디렉토리와 같은 위치 혹은 하위에 존재하는 모든 파일들은 관리대상이 된다.

git의 관리대상에서 제외되어야하는 파일이 있다면 .gitignore 파일로 따로 관리해줘야한다.

로컬저장소는 변경사항이 원격저장소로 반영되기 이전에 거치는 최종단계로, 사용자 컴퓨터에서의 모든 git 관련 기록들이 저장된다. 따라서, 이 디렉토리가 삭제된다면 로컬에서의 모든 작업기록이 사라지므로 주의해야한다.

Branch

맨 처음 소개했듯이 Git이 가진 가장 특징적인 부분은 소스코드의 버전을 나눠서 관리할 수 있다는 점이다.
이는 Branch라는 명칭으로 불리며 메인 소스코드에서 원하는 시점에 생성할 수 있다.

이렇게 생성된 Branch는 기준이 되는 Branch의 모든 내용을 복사해서 가진다고 볼 수 있다.
따라서, 기준 Branch와 독립적으로 소스코드를 관리할 수 있으며 원하는 때에 특정 Branch와 병합하는 것도 가능하다.

Git에 의해 관리되는 소스코드는 커밋 시점마다의 상태가 모두 다르다.
이러한 소스코드들은 커밋 해시값으로 관리되며, 현재 작업중인 Branch나 커밋을 가리키는 포인터 HEAD라고 부른다.

이런 해시값들은 git log 명령으로 확인할 수 있다.

위 이미지를 살펴보면 현재 작업중인 branch가 main이고, 원격 저장소의 main branch와 동기화되어 있다는 것을 파악할 수 있다.

$ git branch test
$ git checkout test

위 명령어로 Branch를 생성하고 작업 Branch를 변경하면 위와 같이 로그가 출력되는 것을 알 수 있다.

작업 Branch가 test로 변경되었으며,
원격 저장소의 main과 동기화 되어있고,
로컬 저장소의 main에서 분기된 branch라는 것을 알 수 있다.

참고 및 이미지 출처

0개의 댓글