명령어
- HEAD vs main (+특수 HEAD 종류 정리)
- Git 명령어 정리
- git describe
- git merge
- cherry-pick
- git pull --allow-unrelated-histories
- git reset
- revert
- git tag
- git reflog (git reset 후 커밋 복구)
HEAD vs main (+특수 HEAD 종류 정리)
1. 개요
용어 | 역할 | 예시 |
---|---|---|
| 현재 작업 중인 커밋을 가리키는 포인터 |
|
| 기본 브랜치 이름 (Git 2.28+ 기본 브랜치) |
|
2. 개념 비교
항목 | HEAD (포인터) | main (브랜치) |
---|---|---|
정체 | 특수 포인터 | 이름 있는 참조 |
용도 | "현재 내가 작업 중인 위치" 추적 | 커밋들을 연결하는 선 |
이동 가능성 | 하나만 존재, 항상 이동함 | 여러 브랜치 중 하나, 직접 이동 안 함 |
Git 명령어 관련 |
|
|
실제 저장 위치 |
|
|
3. 시각적 예시
A---B---C---D
↑
main
↑
HEAD
HEAD → main → D 커밋
git checkout main
→HEAD
가main
브랜치를 가리킴git checkout <커밋 해시>
→HEAD
가 Detached 상태
4. HEAD의 두 가지 상태
상태 | 설명 | 결과 |
---|---|---|
Attached HEAD | HEAD가 브랜치를 가리킴 | ✅ 정상 상태 (
) |
Detached HEAD | HEAD가 특정 커밋 해시를 직접 가리킴 | 🌀 브랜치가 아님, 새 커밋은 임시 상태 |
git checkout main # HEAD → main
git checkout a1b2c3d # HEAD → a1b2c3d (Detached)
5. 관련 명령어
명령어 | 설명 |
---|---|
| HEAD가 가리키는 브랜치 경로 확인 |
| HEAD 내용 확인 (
) |
| HEAD 기준 커밋 히스토리 확인 |
| HEAD 이동 이력 추적 (복구용) |
6. 요약 비교표
구분 | HEAD | main |
---|---|---|
유형 | 포인터 (현재 위치) | 브랜치 이름 |
갯수 | 항상 1개 | 여러 개 가능 |
의미 | 현재 체크아웃된 브랜치/커밋 | 브랜치(커밋 선형 연결) |
이동 가능 여부 | 명령어로 이동 가능 | 직접 이동 불가 (커밋 시 이동) |
7. 특수 HEAD 종류 정리
이름 | 설명 |
---|---|
| 현재 작업 중인 커밋 (or 브랜치) 포인터 |
|
|
|
|
| 직전의 |
|
|
|
|
8. 활용 예시
git reset --hard ORIG_HEAD # 직전 상태로 롤백
git merge feature # 병합 시 MERGE_HEAD 생성됨
cat .git/MERGE_HEAD # 병합 대상 커밋 확인
git fetch origin # FETCH_HEAD 갱신
cat .git/FETCH_HEAD
요약
| 현재 위치 추적 |
| reset/merge 전 원래 HEAD |
| fetch로 받아온 최신 원격 커밋 위치 |
| merge 병합 대상 커밋 |
Git 명령어 정리
1. Git Commit
1.1 개념
- Git은 디렉토리 전체의 스냅샷을 기록하지만, 실제로는 변경된 부분(delta)만 저장하여 가볍게 유지함.
- 대부분의 커밋은 그 위의 부모 커밋을 가리킴.
1.2 명령어
git commit
2. Git Branch
2.1 개념
- Git의 브랜치는 커밋에 대한 참조(reference)로 매우 가볍다.
- “하나의 커밋과 그 조상 커밋들을 포함하는 작업 내역”이라고 볼 수 있음.
- 브랜치를 많이 만들어도 성능이나 저장공간에 영향이 없음.
2.2 명령어
git branch -f <branch>
git checkout <branch> # 브랜치로 이동
3. Git Merge
3.1 개념
- Merge는 두 부모를 갖는 특별한 커밋을 만들어 병합을 수행.
- 모든 부모 커밋의 작업 내역을 포함함.
3.2 명령어
git merge <branch>
4. Git Rebase
4.1 개념
- 커밋들을 모아서 복사한 후, 다른 브랜치에 붙이는 방식.
- 커밋 로그를 한 줄로 정리 가능.
A에서 B로 리베이스
→ A의 기반(base)을 B로 변경.
4.2 명령어
git rebase <branch>
5. Git Checkout
5.1 개념
HEAD
는 브랜치나 커밋을 가리키는 이동 가능한 포인터.checkout
은 특정 브랜치나 커밋으로 이동시킴.HEAD
가 커밋을 직접 가리킬 때는 분리된 HEAD 상태.
5.2 명령어
git checkout <branch or commit>
6. 상대 참조 (Relative Reference)
6.1 기호 설명
^
: 한 커밋 위로~<n>
: 여러 커밋 위로
6.2 예시
git HEAD^
git HEAD~2
7. Git Reset & Revert
7.1 git reset
- 브랜치를 예전 커밋으로 이동시켜 변경 사항을 되돌림.
- 히스토리가 삭제됨, 공동 작업 시 주의 필요.
git reset <commit>
7.2 git revert
- 현재 브랜치에서 역 변경 커밋을 새로 만들어 안전하게 되돌림.
git revert <commit>
8. Git Cherry-pick
8.1 개념
- 원하는 커밋만 선택적으로 복사해서 HEAD 밑에 적용.
- 해시값을 명확히 알고 있을 때 유용.
8.2 명령어
git cherry-pick <commit1> <commit2> ...
9. Git Interactive Rebase
9.1 개념
- 체리픽처럼 커밋을 고르는 게 아니라 목록을 직접 수정해서 순서 변경, 제거 가능.
9.2 명령어
git rebase -i <base>
10. Git Tag
10.1 개념
- 커밋에 대한 영구적인 닻. 릴리즈 버전 등에 주로 사용.
- 브랜치와 달리 절대 움직이지 않음.
10.2 명령어
git tag <tag> <commit>
11. Git Describe
11.1 개념
- **가장 가까운 태그(tag)**를 기준으로 현재 위치를 설명함.
11.2 명령어
git describe <ref>
11.3 결과 형식
<tag>_<numCommits>_g<hash>
12. Git Clone
12.1 개념
- 원격 저장소를 로컬로 복제.
12.2 명령어
git clone <repo_url>
13. Git Remote
13.1 개념
- 원격 저장소와의 연결 정보
- clone 시 기본 이름은
origin
.
13.2 특징
origin/main
은 원격 브랜치, 체크아웃하면 분리된 HEAD 상태.
13.3 예시
git remote
git checkout origin/main
14. Git Fetch
14.1 개념
- 원격 저장소로부터 새 커밋 다운로드, 브랜치는 변경하지 않음.
14.2 명령어
git fetch <remote>
15. Git Pull
15.1 개념
fetch
+merge
를 한 번에 수행.- 원격 저장소와 로컬 브랜치 동기화.
15.2 명령어
git pull origin main
git diff HEAD origin/main # 차이 확인
16. Git Push
16.1 개념
- 자신의 커밋을 공개 및 공유. 원격 저장소에 업로드.
16.2 명령어
git push origin <branch>
17. Git fakeTeamwork
17.1 개념
- 협업자 또는 가상의 작업자 변경 내역을 로컬로 가져오는 시뮬레이션 개념.
git describe
1. Git Describe란?
git describe
는 현재 커밋(또는 ref)이 가장 가까운 태그로부터 몇 번째 커밋인지, 어떤 커밋인지 요약해주는 명령어이다.- 주로 버전 관리, 릴리즈 스크립트 자동화, 디버깅 시 위치 파악 등에 활용됨.
2. 기본 출력 형식
<tag>_<N>_g<short-hash>
항목 | 설명 |
---|---|
| 가장 가까운 태그 이름 |
| 태그 이후 몇 번째 커밋인지 (0이면 태그 본인) |
| 해당 커밋의 Git short hash |
3. 자주 쓰는 옵션
3.1 --tags
git describe --tags
- 기본 동작은 annotated tag만 검색.
--tags
를 붙이면 lightweight tag도 포함하여 검색.
3.2 --abbrev=0
git describe --abbrev=0
- 가장 가까운 태그 이름만 출력하고, 커밋 수나 해시는 생략됨.
- 릴리즈 버전명만 필요할 때 유용.
3.3 --exact-match
git describe --exact-match
- 현재 커밋이 태그와 정확히 일치할 때만 태그 이름을 출력.
- 그렇지 않으면 아무 출력도 하지 않음.
4. 사용 예시
git describe # v2.0.0-2-gabc1234
git describe --tags # lightweight 포함
git describe --abbrev=0 # v2.0.0
git describe --exact-match # v2.0.0 (태그된 커밋일 때만)
5. 주의사항
git describe
는 기본적으로 annotated tag만 대상으로 함.- lightweight 태그까지 포함하고 싶으면
--tags
옵션 사용. - 스크립트/자동화에서는 보통
--tags --abbrev=0
조합 사용. - 태그가 없는 경우, 결과가 출력되지 않거나 에러 발생 가능성 있음.
git merge
1. Git Merge란?
git merge
는 다른 브랜치의 변경사항을 현재 브랜치에 병합할 때 사용하는 명령어이다.
2. 기본 형식
git merge <브랜치명>
용어 | 설명 |
---|---|
현재 브랜치 | 병합이 적용될 대상 브랜치 |
| 병합할 소스 브랜치 (변경사항을 가져올 브랜치) |
📌 즉, 현재 브랜치 ← <브랜치명>
의 변경 사항을 병합
3. 사용 예시
git checkout main # main 브랜치로 이동 (병합 대상)
git merge feature/login # feature/login 브랜치를 main에 병합
🧠 의미:feature/login
의 변경사항을 main
브랜치로 가져오겠다는 뜻입니다.
4. 흐름 시각화
main ◀── 병합 ─── feature/login
↑
(HEAD 포인터)
5. 사용 절차
5.1 병합 대상 브랜치로 이동
git checkout main
5.2 병합 수행
git merge feature/login
6. 병합 결과
- ✅ Fast-forward merge: 브랜치가 갈라지지 않았다면 병합 커밋 없이 연결됨
- 🔀 Merge commit: 브랜치가 갈라졌다면 새 병합 커밋이 생성됨
7. 주의사항
항목 | 설명 |
---|---|
HEAD 위치 | 항상 병합될 대상 브랜치에 있어야 함 ( |
충돌 가능성 | 변경사항이 겹치는 경우 conflict 발생 가능 → 수동 해결 필요 |
커밋 전 병합 여부 | 병합 대상 브랜치의 작업이 커밋되지 않았다면 병합되지 않음 |
8. 추가 팁
- 병합 전 현재 브랜치가 최신 상태인지
git pull
로 동기화 권장 - 병합 후에는
git log
또는gitk
로 히스토리 확인 가능 - 병합 전략 지정 시
--no-ff
옵션 사용해 강제로 병합 커밋 생성 가능:
git merge --no-ff feature/login
cherry-pick
1. Git Cherry-pick이란?
git cherry-pick
은 다른 브랜치의 특정 커밋 하나만 골라 현재 브랜치에 적용하는 명령어이다.
"딱 필요한 커밋 하나만 따로 복사해오고 싶을 때" 사용한다.
2. 기본 문법
git cherry-pick <커밋 해시>
예:
git cherry-pick a1b2c3d
3. 시각화 예시
🎯 목적: feature
브랜치의 특정 커밋 C3
만 main
브랜치로 가져오기
📌 기존 상태
main: A---B
\
feature: C1---C2---C3---C4
git checkout main
git cherry-pick C3
📌 결과 상태
main: A---B---C3'
\
feature: C1---C2---C3---C4
🔄
C3'
는C3
와 동일한 내용이지만 다른 커밋 해시를 가진 복제 커밋한다.
4. 여러 커밋 cherry-pick
git cherry-pick <시작해시>^..<끝해시>
예:
git cherry-pick C2^..C4
→ C2, C3, C4를 현재 브랜치로 모두 적용
5. 충돌 발생 시
- 충돌 발생 시 수동 해결 필요
git add .
git cherry-pick --continue
- 중단하고 원래대로 되돌릴 때:
git cherry-pick --abort
6. 사용 예시 요약
상황 | 설명 |
---|---|
🔧 버그 수정 |
|
🎯 기능 분리 | 여러 기능 중 하나만 따로 적용 |
🧪 실험 | 실험용 브랜치에 특정 수정만 적용해서 테스트 |
7. cherry-pick vs merge vs rebase
명령어 | 적용 범위 | 히스토리 영향 | 특징 |
---|---|---|---|
| 전체 브랜치 | O (병합 커밋 생성) | 원본 히스토리 유지 |
| 전체 브랜치 | O (히스토리 수정) | 깔끔한 직선형 히스토리 |
| 개별 커밋 | O (복제 커밋 생성) | 선택 적용 가능 |
8. 주의사항
- 커밋 해시는 같아 보여도 내부적으로 새 커밋(C3′) 이 생성됨
- 여러 번 cherry-pick 시 중복 충돌이 발생할 수 있음
- 동일 커밋을 여러 브랜치에서 사용 시 히스토리 혼동 가능성 있음
git pull --allow-unrelated-histories
1. git pull --allow-unrelated-histories 란?
보통 서로 다른 프로젝트를 하나로 합치거나, 원격 저장소와 로컬 저장소가 서로 공통 조상을 갖지 않을 때 사용한다.
2. 오류 상황 예시
fatal: refusing to merge unrelated histories
🧨 언제 발생하나?
- 로컬에서
git init
으로 새 저장소 생성 후 커밋 - 원격 저장소(GitHub)에 다른 초기 커밋이 존재 (예: README.md)
- 이후
git pull origin main
시 위 오류 발생
3. 해결 방법
git pull origin main --allow-unrelated-histories
- 두 히스토리 병합 강제 수행
- 이후 충돌(conflict)이 발생할 수 있으니 수동으로 해결 필요
4. 사용 예
# 로컬 초기화
git init
git remote add origin https://github.com/user/repo.git
# 강제 병합
git pull origin main --allow-unrelated-histories
5. 주의사항
- 한 번만 사용하면 충분: 병합이 끝나고 연결되면, 이후부터는 일반
git pull
로도 작동합니다. - 병합 충돌 발생 가능성이 크므로 사용 후 커밋 기록 확인 필수
6. 관련 옵션
옵션 | 설명 |
---|---|
| 병합 대신 리베이스로 히스토리 깔끔하게 유지 |
| 병합하되 커밋은 직접 하고 싶을 때 |
| 충돌 시 우선할 히스토리 선택 |
git reset
1. Git Reset 이란?
git reset
은 Git에서 브랜치의 현재 위치(HEAD)를 다른 커밋으로 되돌리거나, 스테이징 상태를 해제하거나, 작업 디렉토리까지 초기화하는 명령어이다.
"방금 했던 커밋/추가/수정... 지우고 다시 하고 싶어!" 할 때 사용한다.
2. reset 동작 범위 비교
옵션 | HEAD 이동 | Staging Area 변경 | 작업 디렉토리 변경 |
---|---|---|---|
| ✅ O | ❌ 그대로 | ❌ 그대로 |
| ✅ O | ✅ 초기화 | ❌ 그대로 |
| ✅ O | ✅ 초기화 | ✅ 완전 초기화 |
3. 시각화 예시
현재 상태:
A---B---C---D (HEAD)
↑
현재 브랜치
git reset --soft B
결과:
A---B (HEAD)
↑
스테이징 영역에는 C, D의 변경사항이 유지됨
git reset --hard B
결과:
A---B (HEAD)
↑
C, D 커밋은 완전히 제거됨 (작업 디렉토리도 초기화)
4. 옵션별 설명
🔹 --soft
git reset --soft <커밋해시>
- 커밋만 되돌림
- 변경사항은 스테이징 상태로 유지됨
📌 사용 예:
커밋 메시지를 실수했을 때, 커밋만 취소하고 다시 커밋하고 싶을 때
🔹 --mixed
(기본 옵션)
git reset --mixed <커밋해시>
- 커밋 & 스테이징만 초기화
- 작업 디렉토리는 그대로 남음
📌 사용 예:
add만 하고 아직 커밋 안 했을 때,
git add
를 되돌리고 싶을 때
🔹 --hard
git reset --hard <커밋해시>
- 커밋, 스테이징, 작업 디렉토리 전부 초기화
📌 사용 예:
모든 변경사항을 완전히 삭제하고 과거 상태로 돌리고 싶을 때
⚠️ 복구 불가한 경우가 많으므로 주의!
5. 실습 예시
# 초기 커밋 3개 생성
echo "a" > a.txt && git add . && git commit -m "A"
echo "b" > b.txt && git add . && git commit -m "B"
echo "c" > c.txt && git add . && git commit -m "C"
git log --oneline
# 마지막 커밋을 취소하고 이전 상태로 복귀
git reset --soft HEAD~1 # C는 스테이징 상태로 돌아감
git reset --mixed HEAD~1 # C는 unstage됨
git reset --hard HEAD~1 # C는 완전히 삭제됨
6. git reset
vs git revert
비교
명령어 | 기존 커밋을 | 새로운 커밋? | 안전성 | 사용처 |
---|---|---|---|---|
| 삭제함 | ❌ X | 위험 | 혼자 쓰는 브랜치, 최근 실수 복구 |
| 보존함 | ✅ O | 안전 | 협업 브랜치, 히스토리 보존 필요 시 |
✅ 요약
옵션 | 설명 | 주의 사항 |
---|---|---|
| 커밋만 취소, staging은 그대로 | 메시지 실수 복구에 유용 |
| 커밋 + staging 취소, 작업물은 유지 | 기본값 |
| 커밋 + staging + 작업물 전부 취소 | 되돌릴 수 없음 *주의 |
revert
git tag
1. Git 태그란?
- **Git 태그(Tag)**는 프로젝트의 커밋 히스토리에서 중요한 지점을 영구적으로 표시하는 기능이다.
- 브랜치와 다르게, 태그는 절대 이동하지 않으며 단순히 커밋을 가리키는 고정 포인터 역할을 한다.
- 주로 버전 릴리즈, 큰 기능 병합 후, 배포 이력 저장 등에 사용된다.
2. 브랜치와 태그의 차이
항목 | 브랜치 | 태그 |
---|---|---|
역할 | 작업을 이어가는 지점 | 이정표(마일스톤) 고정 지점 |
상태 | 계속 이동함 (새 커밋이 생기면 이동) | 고정됨 (절대 이동하지 않음) |
커밋 가능 여부 | 가능 | 불가능 (태그에서 커밋 시 분리된 HEAD) |
대표적 용도 | 기능 개발, 병합 관리 | 릴리즈, 버전 마킹 |
3. 태그 종류
3.1 Lightweight Tag (경량 태그)
- 단순히 커밋을 가리키는 라벨만 붙임
- 메타데이터 없음 (작성자, 날짜, 메시지 등 기록 X)
git tag v1.0.0
3.2 Annotated Tag (주석 태그)
- 릴리즈용으로 사용
- 작성자, 날짜, 메시지 포함. GPG 서명도 가능
git tag -a v1.0.0 -m "Release version 1.0.0"
4. 태그 명령어 모음
4.1 태그 목록 보기
git tag
4.2 특정 커밋에 태그 달기
git tag v1 <커밋해시>
4.3 태그 체크아웃
git checkout v1
- 결과: 분리된 HEAD(detached HEAD) 상태
- → 커밋할 수 없으며, 하려면 새 브랜치를 생성해야 함
git checkout -b new-branch-from-v1
4.4 태그 삭제
git tag -d v1
4.5 원격 저장소에 태그 푸시
git push origin v1
- 모든 태그 푸시
git push origin --tags
4.6 원격에서 태그 삭제
git push origin --delete tag v1
5. git describe: 태그 활용한 위치 설명
5.1 사용법
git describe
- 현재 HEAD에서 가장 가까운 태그 기준으로 현재 커밋을 설명
v1.0.0-2-g9f23a1c
v1.0.0
→ 가장 가까운 태그-2
→ 태그 이후 2번째 커밋g9f23a1c
→ 현재 커밋 해시 요약
6. 주의사항
- 태그는 브랜치처럼 체크아웃할 수 있지만, 작업을 이어갈 수는 없음
- 커밋하려면 새 브랜치를 만들어야 함:
git checkout -b fix-hotbug v1.0.0
7. 태그 사용 예시
# 최신 커밋에 경량 태그
git tag v2.0.0
# 과거 커밋에 주석 태그
git tag -a v1.0.0 <커밋해시> -m "Initial release"
# 태그 확인
git tag
# 태그 푸시
git push origin --tags
✅ 마무리 요약
목적 | 명령어 예시 |
---|---|
태그 생성 |
|
주석 태그 |
|
태그 보기 |
|
태그 푸시 |
|
태그 전체 푸시 |
|
태그 삭제 |
|
원격 태그 삭제 |
|
태그 기준 커밋 설명 |
|
git reflog (git reset 후 커밋 복구)
1. 상황 예시
git reset --hard HEAD~1
이 명령어로 가장 최근 커밋이 삭제되었고, 스테이징/작업 디렉토리도 초기화됨.
2. git reflog
란?
Git에서 브랜치가 가리키던 과거 위치들을 기록해 놓은 로그입니다.
git reflog
실행하면 다음과 같은 출력이 나온다.
c3d9f7b HEAD@{0}: reset: moving to HEAD~1
e7a1b2a HEAD@{1}: commit: 구현 완료
...
→ 이때 HEAD@{1}
이 우리가 잃어버린 커밋이다.
3. 복구 방법
git reset --hard HEAD@{1}
또는 해시값 직접 지정:
git reset --hard e7a1b2a
→ 이 명령으로 삭제된 커밋과 작업 내용 복원 완료!
추가 팁: 안전하게 복원하기
👉 --hard
는 위험하니, 안전하게 복원하려면 브랜치를 새로 만들어서 이전 커밋으로 가도 된다.
git checkout -b recovery HEAD@{1}
📌 정리
명령어 | 설명 |
---|---|
| HEAD, 브랜치 이동 이력 확인 |
| 과거 커밋 상태로 복원 |
| 복구 브랜치 생성 (더 안전) |