git 은 파일을 세 공간 사이에서 옮기며 관리합니다. 작업 트리(working tree)는 실제로 파일을 편집하는 폴더이고, 스테이징(staging, index)은 다음 커밋에 포함할 변경을 모아두는 대기 영역입니다. 저장소(repository)는 커밋 이력이 저장되는 곳입니다.
작업 트리(working tree) 스테이징(staging, index) 저장소(repository)
Main.java(수정) ---- git add ----> Main.java(대기) ---- git commit ----> 커밋 이력에 기록
파일 상태:
untracked : git 이 아직 모르는 새 파일
modified : 커밋된 적 있고 이후 내용이 바뀐 파일
staged : add 로 스테이징에 올라가 커밋을 기다리는 파일
committed : 저장소에 커밋으로 기록된 상태git init 은 현재 폴더를 새 git 저장소로 만듭니다. -b main 옵션으로 첫 브랜치 이름을 지정합니다.
| 명령 | 동작 |
|---|---|
git init -b main |
현재 폴더에 새 저장소 생성, 기본 브랜치 main |
git clone <경로> |
기존 저장소를 통째로 복제(원격은 다음 레슨부터) |
설정은 적용 범위에 따라 세 단계로 나뉘고, 아래로 갈수록 우선순위가 높습니다.
| 범위 | 옵션 | 저장 위치 |
|---|---|---|
| system | --system |
git 설치 폴더 하위 |
| global | --global |
사용자 홈의 설정 파일 |
| local | (기본값) | 저장소 안 .git/config |
자주 쓰는 키는 user.name, user.email, core.autocrlf, init.defaultBranch 입니다. core.autocrlf 는 줄바꿈 문자 자동 변환 여부이고, 이 사이트 스크립트는 재현성을 위해 항상 false 로 둡니다.
git status 는 자세한 문장으로, git status -s 는 짧은 두 글자 기호로 보여줍니다.
| 기호 | 의미 |
|---|---|
?? |
untracked, git 이 모르는 새 파일 |
A |
스테이징에 추가됨 |
M |
작업 트리에서 수정, 아직 스테이징 안 됨 |
M |
수정 후 스테이징됨 |
D |
스테이징에서 삭제로 표시 |
R |
이름 변경(rename) |
두 글자 중 왼쪽은 스테이징(index) 상태, 오른쪽은 작업 트리 상태입니다. 둘 다 표시되면 스테이징 이후 다시 수정했다는 뜻입니다.
git add 는 작업 트리의 변경을 스테이징으로 옮깁니다. 파일 하나, 폴더 전체, 저장소 전체를 지정할 수 있습니다.
| 형태 | 대상 |
|---|---|
git add Main.java |
파일 하나 |
git add src/ |
폴더 전체 |
git add -A |
저장소 전체(삭제 포함) |
git add -p |
파일 안 일부 덩어리(hunk)만 선택 |
-p 는 파일 하나에서 바뀐 부분 중 일부만 골라 스테이징하는 대화형 모드입니다. 한 파일에 서로 다른 목적의 수정이 섞였을 때, 그중 하나만 먼저 커밋하고 싶을 때 씁니다.
-m "메시지" 로 한 줄 메시지를 바로 남기고, -am 은 수정된 추적 파일을 자동으로 add 까지 하고 커밋합니다. -am 은 새 파일(untracked)은 포함하지 않습니다.
메시지 규칙은 제목 50자 이내, 본문에는 무엇을 왜 바꿨는지 적습니다. 제목만으로 변경 내용이 짐작되면 본문은 생략해도 됩니다.
| 옵션 | 동작 |
|---|---|
--oneline |
커밋마다 한 줄, 짧은 해시 |
--graph |
브랜치 흐름을 그래프로 |
-p |
커밋별 diff 함께 |
--stat |
커밋별 변경 파일과 줄 수 요약 |
-n 2 |
최근 2개만 |
--since="날짜" |
특정 시각 이후 |
--author=kim |
작성자로 필터 |
git log -- Main.java |
특정 파일의 이력만 |
옵션은 git log --oneline -n 3 --author=kim 처럼 조합해서 씁니다.
git diff 는 비교 대상을 지정하지 않으면 작업 트리와 스테이징을 비교합니다.
| 명령 | 비교 대상 |
|---|---|
git diff |
작업 트리 vs 스테이징(index) |
git diff --staged |
스테이징 vs HEAD(마지막 커밋) |
git diff HEAD |
작업 트리 vs HEAD(스테이징 여부 무관) |
git diff C1 C2 |
커밋 C1 과 C2 사이 |
세 비교는 서로 다른 질문에 답합니다. "커밋 안 한 게 뭐지"는 git diff HEAD, "방금 add 한 내용이 뭐지"는 git diff --staged 로 확인합니다.
git show <해시> 는 커밋 하나의 메시지와 diff 를 함께 보여줍니다. --stat 을 붙이면 diff 대신 변경 파일 목록과 줄 수만 요약합니다.
커밋마다 내용과 이전 커밋, 작성자, 시각을 바탕으로 SHA-1 해시가 계산됩니다. 같은 내용이면 같은 해시가 나오므로 이 레슨 스크립트도 항상 같은 해시를 만듭니다. HEAD 는 지금 체크아웃한 브랜치가 가리키는 커밋을 나타내는 포인터이고, 브랜치 레슨에서 이동 원리를 더 다룹니다.
git rm 파일 은 작업 트리에서 파일을 지우고 삭제를 스테이징까지 합니다. git rm --cached 파일 은 파일은 남기고 추적만 그만두고, git mv 원본 대상 은 이름 변경·이동과 스테이징을 한 번에 합니다.
.gitignore 에 패턴을 적으면 해당 파일은 git status, git add -A 대상에서 빠집니다.
| 패턴 | 의미 |
|---|---|
*.class |
확장자가 class 인 모든 파일 |
target/ |
target 폴더 전체 |
!important.log |
위 규칙 예외로 다시 추적 |
이미 추적 중인 파일은 .gitignore 에 추가해도 계속 추적됩니다. git rm --cached 파일 로 추적만 뺀 다음 커밋해야 합니다.
자바 프로젝트 기본 .gitignore 는 다음과 같습니다.
target/
build/
*.class
*.log
.idea/
*.iml