깃은 형상관리 시스템이다.

학습 순서
기본적인 Git 사용법 → 변경 사항 관리 → 협업 & 고급 기능
이번 주 키워드
- Working Directory
- git reset & git revert
- git stash
- Conflict
- git rebase
- cherry-pick
1. Working Directory
우선, 깃의 추적 여부에 따라 `Untracked`와 `Tracked`로 나뉨. 여기서 깃의 추적이라고 함은 깃이 관리하는 파일인가를 뜻하는데, 깃의 관리 기준은 "git add를 한 번이라도 하였는가?"로 이해하면 쉬움.
- git add를 한 번도 하지 않은 새 파일 → Untracked
- git add를 한 번이라도 한 파일 → Tracked
파일이 한 번이라도 git add 된 경우 Tracked 상태가 유지되며, 해당 파일은 수정 여부에 따라 `Unmodified`와 `Modified` 상태로 나뉨.
이해하기 쉽게 시간순으로 예시를 들자면, 아래와 같음.
Untracked → Staged → Unmodified → Modified → Staged → (...)
*최초 생성 후 `Untracked`였던 파일은 git add를 통해 커밋 준비가 된 `Staged` 상태가 되며, 이 파일은 git commit을 통해 `Unmodified` 상태가 됨. 이후 변경 사항이 생기면 `Modified`, 이를 git add 하면 다시 `Staged` 상태가 됨.
요지는 "작업 디렉토리 내에서 이런 식으로 파일 상태가 바뀌더라." 정도로 이해하자는 것임.
2. git reset & git revert
두 명령어 모두 브랜치를 특정 커밋의 상태로 되돌리는 역할을 함. 그러나 방식에서 차이가 있음. git reset은 되돌리고 싶은 커밋 이후의 기록을 없애버리지만, git revert는 기존 이력을 유지하면서 취소하는 새 커밋을 추가함. 쉽게 말해 git reset은 히스토리를 수정하지만 git revert는 히스토리를 유지함.
🔹git reset
- 특정 커밋 이후의 변경 사항을 없앰. 되돌린 기록이 남지 않음.
🔹git revert
- '특정 커밋을 취소하는 새로운 커밋'을 생성해 기록을 남김.
핵심은 타 개발자와 협업할 때 git reset을 지양하자는 것임. 공유된 브랜치에서 git reset을 사용하는 경우 혼란은 물론이고 문제가 생길 수 있음. 협업 환경이라면 git revert를 통해 안전하게 사용하는 것을 추천함.
📌 더 알아보기
git reset의 경우 상황에 따른 세 가지 옵션이 존재함. 이 옵션들 간의 차이를 이해하려거든, 일단 `HEAD`, `Staging Area`, `Working Directory`를 먼저 이해할 필요가 있음.
Working Directory | git status에서 변경 사항이 감지되는 영역 (실제로 파일을 수정하는 작업 공간) |
Staging Area (Index) | git add 후 들어가는 영역 (git commit 준비가 된 파일이 저장되는 공간) |
HEAD | git checkout 된 Commit (현재 브랜치의 최신 Commit) |
*쉽게 비유해서 Working Directory (초안 작성) → Staging Area (발표할 원고 정리) → HEAD (최종 발표된 문서)임.
git reset 시 따로 옵션을 지정하지 않은 경우 --mixed가 기본값이 되며, 각 옵션에 따른 특징은 아래와 같음.
옵션 | HEAD (브랜치 이동) | Index (스테이징 초기화) | WorkingDirectory 영향 |
--soft | ✅ 변경 | ❌ 유지 | ❌ 유지 |
--mixed (기본값) | ✅ 변경 | ✅ 초기화 | ❌ 유지 |
--hard | ✅ 변경 | ✅ 초기화 | ✅ 초기화 (삭제) |
🔹git reset --soft HEAD^
- 해당 커밋이 취소되며 HEAD가 이전 커밋으로 이동할 뿐임. 파일은 Staging Area에 그대로 남아 있으며, git commit을 하면 다시 원래대로 돌아감.
🔹git reset --mixed HEAD^
- 해당 커밋과 git add 한 기록이 사라지지만, 파일 수정 내용은 그대로 남아 있음. git add, git commit을 통해 다시 돌아갈 수 있음.
🔹git reset --hard HEAD^
- 해당 커밋 이후의 모든 작업이 사라지며 되돌릴 수 없음. 되돌린다기보다는 진짜 삭제에 가까운 개념임.
git revert <Commit ID>
*다시 말하지만, 어차피 협업할 일이 잦을텐데 git revert를 사용하는 편이 좋을 듯함. 근데 알아두어야 할 게, git revert는 기본적으로 한 번에 하나의 커밋만 되돌림. 그래서 여러 커밋을 되돌리고 싶다면 git revert도 여러번 해주어야 함.
# 커밋 히스토리 예시
A - B - C - D - E (현재 HEAD)
# C, D, E 커밋 되돌리기
git revert E
git revert D
git revert C
# 최종 모습
A - B - C - D - E - E' - D' - C'
2-2. git checkout & git switch
본 포스트에서 `HEAD`를 설명하며 git checkout을 언급하게 되었는데, 문득 세션 중에 git checkout과 git switch가 비슷한 기능이라는 식으로 언급되었던 게 기억남. 근데 분명 차이가 있기 때문에 둘 다 존재하는 것이란 확신이 생겨 찾아봄.
찾아본 결과, git checkout과 git switch는 둘 다 브랜치를 변경하는 기능을 하지만 분명한 차이가 있었음. 요점만 말하자면 git switch는 더 명확하고 안전한 방식으로 분리된 명령어임.
git checkout | 브랜치 이동 + 특정 커밋 체크아웃 + 파일 변경 취소 | 다양한 기능을 한 명령어에 포함 |
git switch | 브랜치 이동 전용 | 브랜치 변경만 가능 (더 직관적) |
*더 쉽게 말해서, git switch는 git checkout의 브랜치 변경 기능만 분리한 명령어임. (Git 2.23 도입)
좀 더 심화해서 보면 git checkout은 기능이 많이 포함되어 헷갈릴 수 있음. 그래서 쪼개져 나온 것이 git switch와 git restore이므로 git switch + git restore 조합을 사용하는 것을 권장함.
3. git stash
git stash는 작업 중인 변경 사항을 임시로 저장하고 나중에 다시 적용하는 기능임. 말 그대로 변경 사항을 커밋하지 않고도 임시로 저장할 수 있기에 유용한 명령어라고 볼 수 있음.
🔹주요 명령어
- git stash
- git stash list
- git stash apply
- git stash pop
- git stash drop
- git stash clear
git stash # 변경 사항이 stash에 저장됨. (작업 디렉토리 클린)
git stash list # 저장된 stash 목록을 확인함.
git stash apply # 가장 최근의 stash 변경 사항을 다시 적용함. (stash 유지)
git stash pop # 가장 최근의 stash 변경 사항을 다시 적용함. (stash 삭제)
git stash drop stash@{0} # 특정 stash를 삭제함. (stash@{0}은 가장 최근 stash)
git stash clear # 저장된 모든 stash를 삭제함.
💡 `git stash`는 언제 사용할까?
- 브랜치를 변경해야 하는데 아직 커밋하기 애매할 때.
- 급하게 다른 작업을 해야 할 때.
4. Conflict
브랜치를 병합(git merge)하거나 리베이스(git rebase)할 때 충돌(conflict)이 발생할 수 있음. 따라서 충돌에 대한 해결 방법을 아는 것이 필수적임.
🔹근본적인 해결 방법 (모든 브랜치, 수동)
# 충돌 파일 예시
<<<<<<< HEAD
// 현재 브랜치 변경 사항
=======
// 병합 대상 브랜치 변경 사항
>>>>>>> feature-branch
- git status로 충돌 파일 확인
- 충돌 파일을 열어 <<<<<<<, =======, >>>>>>> 표시된 부분을 수정
- 수정 후 git add <파일명>
- git commit으로 충돌 해결
🔹병합 및 리베이스 중단 (임시 해결)
- git merge --abort → 병합 중단
- git rebase --abort → 리베이스 중단
🔹특정 브랜치 수락 (선택되지 않은 브랜치 내용 버리기)
git checkout --ours conflicted-file.txt # 현재 브랜치의 변경 사항만 유지
git checkout --theirs conflicted-file.txt # 병합 대상 브랜치의 변경 사항만 유지
5. git rebase
`git rebase`는 브랜치의 기반(base)을 다른 브랜치로 변경하는 명령어임.
🔹 사용법
git checkout feature-branch git rebase main
- feature-branch를 main 브랜치 위에 다시 쌓음.
💡 `git rebase`는 왜 사용할까?
- 커밋 이력을 깔끔하게 정리하기 위해 (merge 대신 rebase 사용)
- 협업할 때 다른 사람이 변경한 최신 코드 위에서 작업을 이어가기 위해
단, 이미 공유된 브랜치에서는 git rebase를 하면 안 됨. 기록이 변경되기 때문임.
6. git cherry-pick
특정 브랜치의 특정 커밋만 골라서 다른 브랜치에 적용하는 명령어임. 아래 사이트를 통해 연습해 볼 수 있음.
↓ 링크 ↓
https://learngitbranching.js.org/?locale=ko
🔹 사용법
git cherry-pick <커밋 해시>
💡 `git cherry-pick`은 언제 사용할까?
- 다른 브랜치에서 필요한 변경 사항만 가져오고 싶을 때
- 긴급 버그 수정(commit)만 특정 브랜치에 반영할 때
'멋쟁이사자처럼 > 정기 세션' 카테고리의 다른 글
[🦁3] 객체 지향 설계: OOP (2) | 2025.03.28 |
---|---|
[🦁2] Web App & Spring MVC #2 (2) | 2025.03.23 |
[🦁2] Web App & Spring MVC #1 (0) | 2025.03.21 |