Git의 기본 흐름: 저장소 만들기(
init) → 상태 확인(status) → 스테이징(add) → 커밋(commit) → 기록 확인(log) → 되돌리기(restore,reset,revert).
JavaScript와 Python에 이어 Git을 배우기 시작했다. Git은 파일의 변경 이력을 버전으로 저장하고 관리하는 도구다. 오늘은 로컬에서 저장소를 만들고, 파일을 커밋하고, 잘못했을 때 되돌리는 데까지 했다.
Git은 터미널(Windows에서는 Git Bash)에서 명령어로 쓴다. 저장소를 만들 폴더부터 터미널 명령어로 준비한다.
$ cd c: # change directory: 현재 위치를 C 드라이브로 옮긴다
$ mkdir git-practice # make directory: git-practice 라는 폴더를 만든다
$ cd git-practice # 그 폴더로 이동한다
| 명령어 | 뜻 |
|---|---|
cd 경로 | 현재 작업 위치(폴더)를 옮긴다 |
mkdir 이름 | 폴더(디렉토리)를 만든다 |
ls -al | 폴더 안의 모든 파일을 자세히 보여 준다 |
필기의 폴더 이름은
jw-git이었다. 여기서는git-practice로 적었다. 터미널 프롬프트에 찍히는 컴퓨터 이름과 계정 이름도 뺐다.
git init$ git init
Initialized empty Git repository in .../git-practice/.git/
git init은 현재 폴더를 Git 저장소로 초기화한다. 이제 Git이 이 폴더의 변경 사항을 관리할 수 있다.
ls -al로 폴더 안을 보면 .git이 생긴 것을 확인할 수 있다.
$ ls -al
drwxr-xr-x ... .
drwxr-xr-x ... ..
drwxr-xr-x ... .git
ls는 파일 목록, -a(all)는 숨김 파일까지 모두, -l(long)은 자세한 형식으로 보여 준다. -al과 -la는 같다..git은 이름이 .으로 시작하는 숨김 폴더라서 -a가 있어야 보인다..git 폴더다. .git을 지우면 이력이 사라진다.필기에는 "
ls -la는.git디렉토리를 생성"이라고 적혀 있는데,.git을 만드는 것은git init이고ls -al은 이미 있는 것을 보여 주는 명령어다.
커밋에는 누가 했는지가 기록된다. 처음 한 번은 이름과 이메일을 설정해야 커밋이 된다.
$ git config --global user.name "Tom"
$ git config --global user.email "tom@example.com"
(여기서는 예시 값이다. 실제로는 본인 이름과 이메일을 쓴다.)
Git에서 파일은 세 단계를 거친다. 이 구조를 알아야 이후 명령어들이 이해된다.
작업 디렉토리 ──(git add)──▶ 스테이징 영역 ──(git commit)──▶ 저장소(.git)
(파일을 고치는 곳) (다음 커밋에 넣을 것을 모아 두는 곳) (커밋 이력이 쌓이는 곳)
| 영역 | 설명 |
|---|---|
| 작업 디렉토리(Working Directory) | 내가 실제로 파일을 만들고 수정하는 폴더 |
| 스테이징 영역(Staging Area) | 이번 커밋에 포함할 변경 사항을 골라 올려 두는 곳 |
| 저장소(Repository) | 커밋으로 확정된 이력이 저장되는 곳 |
add와 commit을 따로 두는 이유는 여러 파일 중 일부만 골라서 커밋할 수 있게 하기 위해서다.
git status: 지금 어떤 상태인가$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
git status는 작업 디렉토리와 스테이징 영역의 상태를 알려 준다. 파일을 하나 만들고 다시 확인해 보자.
$ echo hello > a.txt # a.txt 파일을 만들고 hello를 적는다
$ git status
Untracked files:
(use "git add <file>..." to include in what will be committed)
a.txt
Untracked는 아직 Git이 추적하지 않는 파일이라는 뜻이다.
git add: 스테이징$ git add a.txt # 특정 파일을 스테이징 영역에 추가
$ git status
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: a.txt
| 명령어 | 의미 |
|---|---|
git add 파일명 | 특정 파일을 스테이징 영역에 추가 |
git add . | 현재 디렉토리(.)의 모든 변경 사항을 스테이징 영역에 추가 |
Changes to be committed는 "다음 커밋에 들어갈 것"이라는 뜻이다.
git commit: 커밋$ git commit -m "첫 커밋: a.txt 추가"
[main (root-commit) 5c1195f] 첫 커밋: a.txt 추가
1 file changed, 1 insertion(+)
create mode 100644 a.txt
git commit -m '메시지'는 스테이징된 변경 사항을 메시지와 함께 저장한다. 커밋 메시지는 "무엇을 했는지"가 한눈에 보이게 적는다. 앞의 5c1195f는 이 커밋의 해시(고유 번호)인데 사람마다 값이 다르게 나온다.
git log: 커밋 이력$ git log
commit 5c1195fc653b8cdd1b244a17ae9452a7780025c1
Author: Tom <tom@example.com>
Date: Fri Sep 18 10:00:00 2026 +0900
첫 커밋: a.txt 추가
git log는 커밋 히스토리를 보여 준다. 해시, 작성자, 날짜, 메시지가 나온다. 커밋이 쌓이면 길어지기 때문에 한 줄로 줄여서 보는 옵션을 자주 쓴다.
$ git log --oneline
abfe12b c 추가
b539022 b 추가
7040ee0 a 수정
5c1195f 첫 커밋: a.txt 추가
| 명령어 | 의미 |
|---|---|
git log | 커밋 이력을 자세히 표시 |
git log --oneline | 한 줄로 간략하게 표시 (해시 앞 7자리 + 메시지) |
git log --oneline --branches | 한 줄 형식으로 모든 브랜치의 커밋을 표시 |
--branches는 브랜치가 여러 개일 때 의미가 생기는 옵션이다. 브랜치가 하나뿐인 지금은 --oneline과 결과가 같다. (브랜치는 다음 노트에서 다룬다)
이미 커밋한 파일을 고치면 status에 modified로 나온다.
$ echo world >> a.txt # >> 는 파일 끝에 이어 쓰기
$ git status -s
M a.txt
$ git diff # 무엇이 바뀌었는지 보기
hello
+world
git diff는 변경된 내용을 줄 단위로 보여 준다. +가 붙은 줄이 추가된 줄(world), 앞이 비어 있는 줄은 그대로인 줄(hello)이다.
-s는 status를 짧게 보는 옵션이다. 줄 앞의 기호가 상태를 나타낸다.
| 표시 | 의미 |
|---|---|
?? | 추적되지 않는 새 파일 |
A | 스테이징된 새 파일 |
M (M이 오른쪽) | 수정됨, 스테이징 전 |
M (M이 왼쪽) | 수정됨, 스테이징 후 |
git commit -am: 추적 중인 파일만 한 번에$ git commit -am "a 수정"
[main 7040ee0] a 수정
1 file changed, 1 insertion(+)
-am은 -a(add)와 -m(message)를 합친 것으로, 이미 추적 중인(tracked) 파일의 변경 사항을 스테이징하고 바로 커밋한다. git add를 생략할 수 있어서 편하다.
한 가지 주의할 점이 있다. 새로 만든 파일은 포함되지 않는다.
$ echo b > b.txt
$ echo more >> a.txt
$ git commit -am "a 수정2" # a.txt 만 커밋된다
$ git status -s
?? b.txt # b.txt 는 여전히 추적되지 않는 상태
새 파일은 먼저 git add로 Git에게 알려야 한다. 이후 예제에서는 git add .와 git commit -m을 썼다.
Git의 큰 장점이 실수를 되돌릴 수 있다는 점이다. 어느 단계(작업 디렉토리, 스테이징, 커밋)에서 되돌리느냐에 따라 명령어가 다르다.
git restore: 작업 디렉토리의 변경 취소$ echo world >> a.txt
$ git restore a.txt # 스테이징 전의 수정을 버리고, 마지막 커밋 상태로
$ cat a.txt
hello
git restore 파일명은 아직 스테이징하지 않은 수정을 취소하고 마지막 커밋 상태로 돌려놓는다. 수정한 내용은 사라진다.
git restore --staged: 스테이징 취소$ echo world >> a.txt
$ git add a.txt
$ git status -s
M a.txt # 스테이징됨
$ git restore --staged a.txt # 스테이징만 취소 (수정 내용은 남아 있다)
$ git status -s
M a.txt # 수정은 그대로, 스테이징 전 상태
git restore --staged 파일명은 add를 취소한다. 파일 내용은 그대로 두고 스테이징 영역에서만 뺀다.
| 상황 | 명령어 | 수정 내용 |
|---|---|---|
| 수정만 했다 (add 전) | git restore 파일 | 사라진다 |
add까지 했다 | git restore --staged 파일 | 남는다 (스테이징만 취소) |
git reset: 커밋 취소이미 커밋까지 한 것을 취소할 때는 reset을 쓴다. 옵션에 따라 취소한 뒤 변경 사항이 어떻게 되는지가 다르다. 커밋이 a 수정 → b 추가 → c 추가 순서로 쌓여 있는 상태에서 확인했다.
git reset HEAD^ (기본값, --mixed): 마지막 커밋을 취소한다. HEAD는 현재 가리키는 커밋이고 ^는 그 바로 이전이다.
$ git reset HEAD^
$ git status -s
?? c.txt # c 파일은 남아 있지만 추적 안 되는 상태
$ git log --oneline
b539022 b 추가 # 'c 추가' 커밋은 사라졌다
커밋은 취소되지만 파일은 지워지지 않고, 스테이징도 풀린 상태가 된다.
git reset --soft HEAD^: 커밋만 취소하고 변경 사항은 스테이징된 채로 둔다.
$ git reset --soft HEAD^
$ git status -s
A c.txt # 스테이징까지 된 상태로 남아 있다
바로 다시 git commit만 하면 되므로, 커밋 메시지만 다시 쓰고 싶을 때 편하다.
git reset --hard HEAD^: 커밋을 취소하고 파일 변경까지 모두 지운다.
$ git reset --hard HEAD^
HEAD is now at b539022 b 추가
$ ls
a.txt b.txt # c.txt 가 사라졌다
| 명령어 | 커밋 | 스테이징 | 작업 파일 |
|---|---|---|---|
reset --soft | 취소 | 유지 | 유지 |
reset (--mixed, 기본) | 취소 | 취소 | 유지 |
reset --hard | 취소 | 취소 | 삭제 |
필기에는
reset --hard가 "되돌리고 싹 다 지움",reset --soft가 "특정 커밋으로 되돌림"이라고 적혀 있다. 표로 비교하면--soft도--hard도 모두 특정 커밋으로 되돌리는 것이고, 차이는 그 뒤에 남은 변경 사항을 어떻게 하느냐다. 또git reset HEAD^는 변경 사항을 지우지 않는다. 지우는 것은--hard뿐이다.
HEAD^ 대신 커밋 해시를 쓰면 원하는 시점으로 돌아갈 수 있다. 예를 들어 git reset --hard 5c1195f는 첫 커밋 상태로 되돌린다.
--hard는 파일까지 지우므로 조심해야 한다. 그래도 Git에는 git reflog가 있어서 reset으로 사라진 커밋의 해시를 찾아 다시 되돌릴 수 있다. (이 기록은 일정 기간 뒤 정리된다)
git revert: 기록은 남기고 취소$ git revert --no-edit b539022 # 'b 추가' 커밋을 취소하는 새 커밋을 만든다
[main b1e746f] Revert "b 추가"
1 file changed, 1 deletion(-)
delete mode 100644 b.txt
$ git log --oneline
b1e746f Revert "b 추가"
b539022 b 추가
7040ee0 a 수정
5c1195f 첫 커밋: a.txt 추가
git revert 해시는 그 커밋의 변경을 거꾸로 적용하는 새 커밋을 만든다. 기존 b 추가 커밋은 이력에 그대로 남고, 그 위에 Revert "b 추가"가 쌓인다. (--no-edit는 커밋 메시지 편집 창을 열지 않는 옵션이다)
| 구분 | reset | revert |
|---|---|---|
| 방식 | 커밋을 이력에서 삭제 | 취소하는 새 커밋을 추가 |
| 이력 | 사라진다 | 남는다 |
| 쓰는 곳 | 아직 공유하지 않은 내 로컬 커밋 | 이미 공유한(push한) 커밋 |
이미 다른 사람과 공유한 이력을 reset으로 지우면 서로의 기록이 어긋나기 때문에, 공유한 커밋은 revert로 되돌리는 것이 안전하다.
| 명령어 | 설명 |
|---|---|
git init | 현재 디렉토리를 Git 저장소로 초기화 |
git status | 작업 디렉토리와 스테이징 영역의 상태 확인 |
git add . | 현재 디렉토리의 모든 변경 사항을 스테이징 |
git add 파일명 | 특정 파일을 스테이징 |
git commit -m '메시지' | 스테이징된 변경 사항을 커밋 |
git commit -am '메시지' | 추적 중인 파일의 변경 사항을 스테이징하고 바로 커밋 |
git log | 커밋 히스토리 표시 |
git log --oneline | 커밋 히스토리를 한 줄로 표시 |
git log --oneline --branches | 한 줄 형식으로 브랜치별 커밋 표시 |
git restore 파일명 | 스테이징 전의 수정을 취소 |
git restore --staged 파일명 | 스테이징을 취소 |
git reset HEAD^ | 가장 최근 커밋 취소 (변경 사항은 남김) |
git reset --soft 해시 | 해당 커밋으로 되돌림 (스테이징 유지) |
git reset --hard 해시 | 해당 커밋으로 되돌리고 변경 사항까지 삭제 |
git revert 해시 | 커밋을 취소하는 새 커밋을 만들고 기록은 남김 |
add) → 스테이징 → (commit) → 저장소다.git status로 지금 어느 단계인지 확인하고, git log --oneline으로 이력을 한 줄씩 본다.commit -am은 이미 추적 중인 파일만 대상이라 새 파일은 add가 필요하다.restore, 스테이징 취소는 restore --staged, 커밋 취소는 reset(변경 사항을 어떻게 할지는 --soft/--mixed/--hard), 공유한 커밋은 revert.reset --hard는 파일까지 지우므로 쓰기 전에 현재 상태를 확인한다.Tags: Git git init git add git commit git log git reset git revert 버전관리 개발자 학습기록