포스트

Git 기본 개념: init, add, commit, checkout, reset

Git의 작업 디렉터리, stage, commit과 reset 개념 정리

Git 기본 개념: init, add, commit, checkout, reset

Git은 파일의 변경 이력을 기록하고 필요한 시점으로 돌아갈 수 있게 해 주는 버전 관리 프로그램입니다. 단순히 파일을 저장하는 도구라기보다는, 프로젝트가 어떤 과정을 거쳐 현재 상태에 도달했는지를 기록하는 도구에 가깝습니다.

이번 글에서는 Git을 처음 사용할 때 자주 접하는 init, add, commit, checkout, reset의 역할을 정리해 보겠습니다.

git init

git init은 현재 디렉터리를 Git 저장소로 만드는 명령입니다.

git init

명령을 실행하면 현재 디렉터리 안에 .git이라는 숨김 디렉터리가 생성됩니다. .git에는 커밋 기록, 브랜치 정보, 설정 등 Git이 버전을 관리하는 데 필요한 데이터가 저장됩니다.

여기서 .git은 파일이 아니라 디렉터리입니다. 또한 git init을 실행했다고 해서 현재 파일이 바로 하나의 버전으로 저장되는 것은 아닙니다. 버전을 만들려면 저장할 변경 사항을 선택하고 커밋하는 과정이 필요합니다.

git add와 git commit

git commit은 프로젝트의 현재 상태를 하나의 버전으로 기록하는 명령입니다. 정확히 말하면 작업 중인 모든 파일을 바로 저장하는 것이 아니라, 스테이징 영역(staging area)에 올라온 변경 사항을 하나의 커밋으로 만듭니다.

이 과정을 이해하려면 Git에서 사용하는 세 영역을 구분해야 합니다.

작업 디렉터리(Working Tree) → 스테이징 영역(Staging Area) → 로컬 저장소(Repository)

  • 작업 디렉터리(Working Tree): 실제로 파일을 만들고 수정하는 공간
  • 스테이징 영역(Staging Area): 다음 커밋에 포함할 변경 사항을 모아 두는 공간
  • 로컬 저장소(Local Repository): 커밋으로 확정된 버전이 저장되는 공간

파일을 수정하면 변경 사항은 먼저 작업 디렉터리에만 존재합니다. 이 상태에서 git add를 실행하면 해당 변경 사항이 스테이징 영역에 올라갑니다.

git add README.md

그다음 git commit을 실행하면 스테이징 영역에 있는 변경 사항이 하나의 버전으로 기록됩니다.

git commit -m “Update README”

따라서 기본적인 흐름은 다음과 같습니다.

파일 수정 → git add → git commit

파일을 수정한 뒤 git add를 하지 않고 커밋하면, 수정한 내용은 해당 커밋에 포함되지 않습니다. 스테이징 영역에 다른 변경 사항도 없다면 Git은 커밋할 내용이 없다고 알려 줍니다.

현재 각 파일이 어느 상태에 있는지는 git status로 확인할 수 있습니다.

git status

스테이징 영역이 필요한 이유

그렇다면 git commit으로 모든 변경 사항을 한 번에 저장하지 않고, 중간에 스테이징 영역을 두는 이유는 무엇일까요?

하나의 작업 중에도 서로 다른 목적의 변경이 섞일 수 있기 때문입니다. 예를 들어 기능 코드와 문서 파일을 함께 수정했지만 기능 코드만 먼저 커밋하고 싶을 수 있습니다. 이때 원하는 파일만 git add하면 서로 관련된 변경을 하나의 커밋으로 묶을 수 있습니다.

git add src/app.py

git commit -m “Add login validation”

아직 스테이징하지 않은 변경은 작업 디렉터리에 그대로 남아 있으므로 다음 커밋에서 따로 처리할 수 있습니다. 스테이징 영역은 커밋의 범위를 직접 선택할 수 있게 해 주는 완충 지대인 셈입니다.

git checkout

커밋을 쌓다 보면 이전 버전의 코드가 어떻게 작성되어 있었는지 확인하고 싶을 때가 있습니다. 먼저 git log로 커밋 해시를 확인할 수 있습니다.

git log –oneline

특정 커밋으로 이동하려면 다음 명령을 사용합니다.

git checkout 커밋-해시

이렇게 커밋을 직접 체크아웃하면 특정 브랜치가 아닌 커밋을 바라보는 detached HEAD 상태가 됩니다. 과거 코드를 잠시 살펴보는 용도로는 문제가 없지만, 이 상태에서 새로운 작업을 계속할 생각이라면 새 브랜치를 만드는 편이 안전합니다.

최근 Git에서는 역할이 많은 checkout 대신 브랜치나 커밋 이동에는 switch, 파일 복원에는 restore를 사용하는 방법도 권장합니다.

특정 커밋을 확인할 때는 다음 명령을 사용합니다.

git switch –detach 커밋-해시

main 브랜치로 돌아갈 때는 다음 명령을 사용합니다.

git switch main

git checkout - 또는 git switch -는 직전 커밋으로 이동하는 명령이 아닙니다. 바로 전에 체크아웃했던 브랜치나 위치로 돌아가는 명령입니다.

git switch -

현재 커밋의 바로 이전 버전을 확인하고 싶다면 HEAD~1을 사용할 수 있습니다.

git switch –detach HEAD~1

git reset

git checkout이나 git switch가 다른 커밋을 잠시 확인하거나 작업 위치를 옮기는 데 주로 사용된다면, git reset은 현재 브랜치가 가리키는 커밋 자체를 이전 위치로 옮길 때 사용합니다.

흔히 “커밋을 지운다”고 표현하지만, 정확히는 현재 브랜치의 포인터를 지정한 커밋으로 이동시키는 동작입니다. 이전 커밋이 즉시 완전히 삭제되는 것은 아니며, 일정 기간 reflog에 남아 복구할 수 있는 경우도 있습니다.

git reset의 동작은 –soft, –mixed, –hard 옵션에 따라 달라집니다.

옵션커밋 위치스테이징 영역작업 디렉터리
–soft이동유지유지
–mixed이동초기화유지
–hard이동초기화초기화

git reset –soft

–soft는 현재 브랜치의 커밋 위치만 옮깁니다. 스테이징 영역과 작업 디렉터리는 그대로 유지됩니다.

git reset –soft HEAD~1

직전 커밋을 취소하되, 그 내용을 다시 커밋할 수 있도록 스테이징된 상태로 남기고 싶을 때 사용할 수 있습니다.

git reset –mixed

–mixed는 커밋 위치와 스테이징 영역을 이전 상태로 되돌리지만, 작업 디렉터리의 파일은 그대로 둡니다.

git reset –mixed HEAD~1

–mixed는 git reset의 기본 옵션이므로 다음 두 명령은 같은 동작을 합니다.

git reset –mixed HEAD~1

git reset HEAD~1

직전 커밋을 취소하고 변경 사항도 스테이징 영역에서 내리되, 실제로 수정한 파일 내용은 남기고 싶을 때 적합합니다.

git reset –hard

–hard는 커밋 위치와 스테이징 영역뿐만 아니라 작업 디렉터리까지 지정한 커밋의 상태로 되돌립니다.

git reset –hard HEAD~1

git reset –hard를 실행하면 커밋하지 않은 변경 사항을 잃을 수 있습니다. 복구하기 어려울 수 있으므로 실행 전에 git status로 현재 상태를 확인해야 합니다.

정리

각 명령의 역할을 간단히 정리하면 다음과 같습니다.

명령역할
git init현재 디렉터리를 Git 저장소로 초기화
git add다음 커밋에 포함할 변경 사항을 스테이징
git commit스테이징된 변경 사항을 하나의 버전으로 기록
git checkout브랜치나 특정 커밋으로 작업 위치를 이동
git reset현재 브랜치의 커밋 위치와 필요에 따라 스테이징 영역, 작업 디렉터리를 재설정

처음에는 git add와 git commit을 하나의 동작처럼 생각하기 쉽습니다. 하지만 스테이징 영역을 이해하고 나면 원하는 변경만 골라 커밋할 수 있고, reset의 각 옵션이 어떤 영역에 영향을 주는지도 훨씬 명확해집니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.