테크버킷 로고
Published on

Git 핵심 개념과 용어: 스테이징·커밋·브랜치 이해하기

Authors
  • 테크버킷
    Name
    테크버킷
    Twitter

요약: Git은 파일을 매번 통째로 복사하는 폴더 관리법이 아니라, 프로젝트의 스냅샷을 커밋으로 연결하는 도구입니다. working tree → staging area → repository의 흐름과 현재 커밋을 가리키는 HEAD를 이해하면 대부분의 기본 명령이 같은 지도 위에 놓입니다.

아직 Git을 설치하지 않았거나 사용자 정보를 설정하지 않았다면 macOS·Windows에 Git 설치하기: 설치 확인과 사용자 설정을 함께 읽어보세요. 설치 글은 운영체제별 설치와 설정에, 이번 글은 Git 명령 뒤에서 바뀌는 상태와 용어를 이해하는 데 초점을 맞춥니다.

Git 입문자가 막히는 이유는 명령이 많아서만은 아닙니다. 같은 파일이 작업 폴더, 스테이징 영역, 마지막 커밋에서 서로 다른 상태로 존재할 수 있고, 로컬 브랜치와 원격 브랜치도 이름이 비슷하기 때문입니다.

이번 글에서는 실제 작업 중 자주 만나는 용어를 서로의 관계 중심으로 정리합니다.

Git은 변경분보다 스냅샷으로 생각한다

Git 공식 문서는 Git이 데이터를 작은 파일 시스템의 스냅샷처럼 바라본다고 설명합니다. 커밋할 때 프로젝트 파일의 특정 상태를 기록하고, 바뀌지 않은 파일은 기존 데이터와 연결합니다.

사진 앨범에 비유하면 이해하기 쉽습니다.

commit A          commit B          commit C
프로젝트 상태 1 → 프로젝트 상태 2 → 프로젝트 상태 3

각 커밋은 다음 정보를 담습니다.

  • 선택한 파일들의 스냅샷
  • 작성자 이름과 이메일
  • 작성 시각과 커밋 메시지
  • 바로 이전 커밋을 가리키는 정보

그래서 Git의 이력은 독립된 백업 파일 더미라기보다, 앞뒤 관계가 연결된 커밋 그래프에 가깝습니다.

가장 중요한 세 공간

Git을 사용할 때 파일은 크게 세 공간을 오갑니다.

Working Tree              Staging Area             Repository
직접 수정하는 파일   →    다음 기록으로 선택   →    확정된 커밋 이력
                   git add                  git commit

Working Tree: 지금 수정하는 공간

편집기에서 보고 있는 프로젝트 파일입니다. 마지막 커밋과 비교해 파일을 바꾸면 modified, 새 파일을 만들면 아직 추적하지 않는 untracked 상태가 됩니다.

Staging Area: 다음 커밋의 설계도

git add로 선택한 변경이 모이는 공간입니다. Index라고도 부릅니다. 작업 폴더 전체를 자동으로 기록하는 대신, 이번 커밋에 어떤 변경을 포함할지 골라 하나의 의미 있는 기록을 만들 수 있게 해줍니다.

Repository: 커밋이 보관되는 공간

git commit을 실행하면 스테이징 영역의 상태가 로컬 저장소에 기록됩니다. 보통 프로젝트 안의 .git 디렉터리가 커밋, 브랜치와 설정 같은 Git 데이터를 관리합니다.

Modified, Staged, Committed

Git 공식 문서가 설명하는 파일의 대표 상태는 세 가지입니다.

  • Modified: 마지막 커밋 이후 파일을 수정했지만 아직 스테이징하지 않음
  • Staged: 다음 커밋에 포함할 수정본을 선택함
  • Committed: 변경이 로컬 저장소에 안전하게 기록됨

여기서 중요한 점은 staged가 파일 전체에 영구적으로 붙는 상태가 아니라는 것입니다. 파일을 add한 뒤 다시 수정하면 같은 파일에 staged 변경과 unstaged 변경이 동시에 존재할 수 있습니다.

git diff

위 명령은 작업 트리와 스테이징 영역의 차이를 확인합니다. 커밋에 실제로 들어갈 내용을 보려면 아래 명령을 입력합니다.

git diff --staged

git status는 파일의 분류를, git diff는 구체적인 변경 내용을 보여준다고 구분하면 좋습니다.

커밋은 저장 버튼이 아니라 설명 가능한 작업 단위다

커밋을 단순한 저장으로 생각하면 하루치 변경을 한 번에 담기 쉽습니다. 좋은 커밋은 나중에 다른 사람이 읽었을 때 왜 필요한 변경인지 한 문장으로 설명할 수 있는 크기입니다.

예를 들어 로그인 오류 수정과 버튼 색상 변경은 파일이 같더라도 목적이 다릅니다. 가능하다면 두 커밋으로 나누는 편이 검토와 되돌리기에 좋습니다.

fix: prevent duplicate login requests
style: improve login button contrast

완벽하게 작은 커밋을 만들려고 작업을 지나치게 쪼갤 필요는 없습니다. 테스트 가능한 하나의 의도라는 기준으로 시작하면 충분합니다.

브랜치는 커밋을 가리키는 이동 가능한 이름이다

브랜치를 프로젝트 폴더의 복사본으로 생각하기 쉽지만, Git의 브랜치는 특정 커밋을 가리키는 가벼운 포인터입니다. 새 커밋을 만들면 현재 브랜치가 새 커밋으로 이동합니다.

A ← B ← C  main
         ↖ feature/login

feature/login에서 새 커밋 D를 만들면 해당 브랜치만 D를 가리킵니다.

A ← B ← C  main
         ↖ D  feature/login

새 브랜치를 만들고 이동하려면 아래 명령을 입력합니다.

git switch -c feature/login

기존 브랜치로 이동할 때는 -c를 빼고 입력합니다.

git switch main

브랜치는 메인 흐름을 안정적으로 유지하면서 기능 개발, 버그 수정, 실험을 분리하는 데 사용합니다.

HEAD는 지금 내가 서 있는 위치다

HEAD는 보통 현재 체크아웃한 브랜치를 가리키고, 그 브랜치는 현재 커밋을 가리킵니다.

HEAD → feature/login → commit D

그래서 HEAD를 기준으로 한 표현은 현재 위치에서 상대적으로 읽을 수 있습니다.

  • HEAD: 현재 커밋
  • HEAD~1: 현재 커밋의 첫 번째 부모, 보통 바로 이전 커밋
  • HEAD~2: 두 단계 이전 커밋

커밋 자체를 직접 체크아웃하면 HEAD가 브랜치에서 떨어진 detached HEAD 상태가 될 수 있습니다. 이 상태는 과거 코드를 확인할 때 유용하지만, 초보자는 새 작업을 시작하기 전에 git switch -c <새-브랜치>로 브랜치를 만드는 편이 안전합니다.

로컬 저장소와 원격 저장소

Git은 대부분의 기록 작업을 내 컴퓨터에서 수행합니다. 커밋을 만들었다고 GitHub에 자동으로 올라가는 것은 아닙니다.

로컬 저장소                      원격 저장소
main      ───── git push ─────→ origin/main
          ←──── git fetch ─────

remote와 origin

Remote는 연결된 다른 Git 저장소를 뜻합니다. origingit clone이 첫 원격 저장소에 흔히 붙이는 별칭일 뿐, 반드시 그 이름을 써야 하는 규칙은 아닙니다.

연결된 원격 저장소를 확인하려면 아래 명령을 입력합니다.

git remote -v

fetch, pull, push

  • git fetch: 원격의 새 커밋과 브랜치 정보를 가져오되 현재 작업 파일은 합치지 않음
  • git pull: 원격 변경을 가져온 뒤 현재 브랜치에 통합함
  • git push: 로컬 커밋을 원격 저장소로 전송함

pull을 단순 다운로드로 생각하면 예상하지 못한 merge commit이나 충돌을 만날 수 있습니다. 처음에는 git fetchgit status와 로그를 확인하고, 팀이 정한 merge 또는 rebase 방식으로 통합하는 습관이 이해에 도움이 됩니다.

merge와 rebase는 무엇이 다른가

두 명령 모두 서로 갈라진 커밋을 한 흐름으로 통합할 때 사용하지만 방식이 다릅니다.

Merge는 두 흐름의 공통 조상과 각 브랜치의 변경을 합쳐 필요하면 새 merge commit을 만듭니다. 실제로 갈라졌다 합쳐진 모양이 이력에 남습니다.

Rebase는 현재 브랜치의 커밋을 다른 기준점 위에서 다시 만든 것처럼 재배치합니다. 이력이 직선으로 정리되지만 기존 커밋 ID가 바뀝니다.

공유된 브랜치를 rebase하거나 강제 push하면 동료의 이력과 충돌할 수 있습니다. 팀 규칙을 모를 때는 혼자 사용하는 기능 브랜치에서만 연습하고, 이미 공유한 커밋의 이력을 임의로 다시 쓰지 않는 것이 안전합니다.

switch, restore, reset을 구분하기

오래된 자료에서는 checkout 하나로 브랜치 이동과 파일 복원을 모두 설명하기도 합니다. 처음 배울 때는 목적이 분명한 명령을 사용하면 이해하기 쉽습니다.

  • git switch: 브랜치를 만들거나 이동
  • git restore: 작업 트리 또는 스테이징 영역의 파일 복원
  • git reset: 브랜치나 스테이징 영역의 기준을 옮김

특히 git reset --hard는 커밋되지 않은 변경을 잃을 수 있습니다. 인터넷의 해결 명령을 그대로 실행하기 전에 git status로 현재 상태를 확인하고, 필요한 파일을 별도로 보관하세요.

충돌은 오류가 아니라 선택 요청이다

두 브랜치가 같은 부분을 다르게 수정하면 Git이 어느 내용을 남겨야 할지 자동으로 결정하지 못할 수 있습니다. 이것이 merge conflict입니다.

충돌이 발생했다고 저장소가 망가진 것은 아닙니다. Git이 다음 선택을 사용자에게 넘긴 상태입니다.

  1. git status로 충돌 파일을 확인합니다.
  2. 파일의 충돌 표시를 읽고 최종 내용을 직접 편집합니다.
  3. 테스트한 뒤 해결한 파일을 git add합니다.
  4. merge나 rebase 안내에 따라 작업을 완료합니다.

충돌 해결 중에는 무작정 다른 명령을 이어가기보다 git status가 알려주는 다음 단계를 읽는 것이 가장 중요합니다.

초보자에게 권하는 작업 루틴

아래 순서를 반복하면 Git의 상태가 눈에 들어오기 시작합니다.

git status
git diff
git add <파일>
git diff --staged
git commit -m "변경 이유를 설명하는 메시지"
git log --oneline --decorate -5

실제 협업에서는 작업 전 원격 상태를 확인하고 새 브랜치를 만드는 과정이 추가됩니다.

git fetch origin
git switch -c feature/my-task origin/main

팀마다 최신 main을 반영하는 규칙이 다르므로 pull, merge, rebase 중 무엇을 쓸지는 프로젝트 문서를 우선하세요.

성공적인 입문을 위한 습관

  • 명령 실행 전후에 git status를 확인합니다.
  • git add .부터 실행하기보다 커밋할 파일을 의도적으로 고릅니다.
  • git diff --staged를 보고 커밋합니다.
  • 커밋 메시지에는 작업 내용보다 변경 이유가 드러나게 씁니다.
  • 생성 파일, 비밀 키와 환경 변수는 .gitignore로 제외합니다.
  • reset --hard, clean, 강제 push는 영향을 이해하기 전까지 피합니다.
  • 문제가 생겼을 때 오류 메시지와 현재 브랜치, git status 결과를 함께 기록합니다.

자주 생기는 오해

add는 GitHub에 올리는 명령이다

아닙니다. git add는 로컬 스테이징 영역에 다음 커밋 후보를 올립니다. GitHub 전송은 커밋 후 git push가 담당합니다.

커밋하면 다른 사람도 바로 볼 수 있다

로컬 커밋은 내 저장소에만 있습니다. 원격 저장소로 push한 뒤 권한이 있는 사람이 볼 수 있습니다.

브랜치를 바꾸면 기존 변경이 사라진다

Git은 가능한 경우 커밋하지 않은 변경을 새 브랜치에도 유지합니다. 다른 브랜치의 파일과 충돌할 가능성이 있으면 이동을 막습니다. 변경이 애매하게 따라다니지 않도록 커밋하거나 작업 단위를 분리하는 편이 좋습니다.

stash는 임시 커밋과 완전히 같다

git stash는 작업 트리를 잠시 비울 때 편리하지만, 이름 없는 임시 보관을 계속 쌓으면 어떤 작업인지 찾기 어려워집니다. 장시간 유지할 작업은 의미 있는 브랜치와 커밋으로 남기는 편이 명확합니다.

브랜치를 동시에 열 수는 없을까

브랜치는 작업 흐름을 분리하지만 일반적인 저장소 폴더에는 한 번에 한 브랜치의 파일만 펼쳐집니다. 긴 작업 중 긴급 수정이 들어오면 커밋하거나 stash한 뒤 브랜치를 바꾸고, 작업이 끝나면 다시 원래 문맥으로 돌아와야 합니다.

이 불편을 해결하는 Git 기능이 git worktree입니다. Git Worktree가 필요한 이유: 여러 브랜치를 동시에 작업하기에서 worktree의 등장 배경, 기본 명령과 AI 코딩 에이전트 관리 도구 Orca가 이를 활용하는 방식을 살펴봅니다.

참고 자료