공공부하자개발 · 영어 학습 노트
협업·배포
Git버전 관리와 협업0/8 완료
  • 01저장소와 커밋
  • 02브랜치와 병합
  • 03되돌리기
  • 04원격 저장소
  • 05히스토리 정리
  • 06태그와 버전
  • 07협업 규칙
  • 08문제 해결
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › Git › 05 / 8

히스토리 정리

섹션 7진행 0 / 8
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6연습 문제7정리‹ 이전다음 ›

2. 핵심 원리

2.1 merge 와 rebase 의 결과 차이

같은 작업이라도 명령에 따라 이력 모양이 달라집니다.

text
merge (병합 커밋 M 을 새로 만듦)

main     A---B-------M
              \     /
feature        C---D

rebase (C, D 를 B 뒤에 C', D' 로 다시 적용)

main     A---B---C'---D'

merge 는 feature 의 커밋(C, D)을 그대로 두고 병합 커밋 M 만 추가합니다. rebase 는 C, D 를 새 커밋 C', D' 로 다시 만들어 해시가 바뀌고 이력이 한 줄이 됩니다.

2.2 git rebase main 의 동작

git switch feature; git rebase main 은 feature 에만 있는 커밋(공통 조상 이후)을 임시로 떼어낸 뒤, feature 브랜치를 main 의 최신 위치로 옮기고 떼어낸 커밋을 하나씩 새로 커밋합니다. 새로 커밋하므로 해시가 바뀝니다.

원본 커밋은 저장소 안에 한동안 남아 있다가(reflog 로 확인 가능) 가비지 컬렉션 대상이 됩니다.

2.3 rebase 충돌 해결 순서

충돌(conflict)은 재적용 중인 커밋의 변경과 새 밑동의 내용이 같은 줄을 건드릴 때 납니다.

  1. 충돌 파일을 열어 <<<<<<<·=======·>>>>>>> 마커를 정리합니다.
  2. git add <파일> 로 해결을 표시합니다.
  3. git rebase --continue 로 다음 커밋을 이어 적용합니다.

커밋 하나를 포기하려면 git rebase --skip, 처음 상태로 완전히 되돌리려면 git rebase --abort 를 씁니다.

2.4 황금률: 공유된 커밋은 rebase 하지 않는다

이미 push 해서 동료가 받아간 커밋을 rebase 하면 해시가 바뀝니다. 동료의 저장소와 이력이 어긋나 동료 쪽 push 가 거부되거나, 무심코 강제 push 하면 동료의 작업이 사라질 수 있습니다. 아직 아무도 받아가지 않은 개인 브랜치의 커밋만 rebase 합니다.

2.5 rebase -i 편집 화면과 명령어

git rebase -i HEAD~4 를 실행하면 편집기에 다음과 같은 할 일 목록이 열립니다.

text
pick 068b10f feat: 검증 메시지 UI 추가
pick f368be4 fix typo in 검증 메시지
pick d08c2ed feat: 검증 메시지 다국어 지원
pick 2d7049f wip: 다국어 문자열 정리

# 명령: pick 그대로, reword 메시지만 수정, edit 멈춰서 수정,
# squash 합치고 메시지도 합침, fixup 합치고 메시지 버림, drop 제외

줄 순서를 바꾸면 적용 순서가 바뀌고, pick 을 다른 단어로 바꾸면 그 커밋의 처리 방식이 바뀝니다. 대화형 편집이라 이 화면은 실행 결과가 아니라 예시입니다.

스크립트에서는 편집기 대신 GIT_SEQUENCE_EDITOR 에 sed 명령을 넣어 pick 을 fixup·squash 로 자동으로 바꿉니다.

bash
export GIT_SEQUENCE_EDITOR="sed -i -e '/fix typo/s/^pick/fixup/' -e '/wip: 다국어/s/^pick/squash/'"

메시지 reword 는 GIT_EDITOR 에 커밋 메시지 파일을 통째로 바꿔 쓰는 스크립트를 지정해 자동화합니다.

2.6 git commit --fixup 과 rebase -i --autosquash

수정할 대상 커밋이 뭔지 알 때는 메시지를 찾아 sed 로 표시하는 대신 --fixup 을 씁니다.

bash
git commit --fixup=<대상 커밋 해시>
git rebase -i --autosquash <대상 커밋 해시>^

--fixup 은 메시지를 fixup! <대상 커밋 메시지> 로 자동으로 짓습니다. --autosquash 는 그 메시지를 보고 편집 화면에서 대상 커밋 바로 뒤로 옮기고 fixup 으로 자동 표시합니다.

2.7 cherry-pick: 기본·범위·옵션

형태 의미
git cherry-pick <해시> 커밋 하나를 현재 브랜치에 복사
git cherry-pick A..B A 는 제외, B 까지 포함해 여러 개
git cherry-pick -x <해시> 메시지에 원본 커밋 해시를 남김
git cherry-pick -n <해시> 커밋을 만들지 않고 스테이징까지만

범위 A..B 는 A 를 포함하지 않으므로 A 도 옮기려면 A^..B 로 씁니다. 충돌이 나면 rebase 와 같은 순서(수정 → add → --continue)로 풉니다.

2.8 merge --squash 와 rebase 의 squash 차이

이름은 비슷하지만 쓰는 자리가 다릅니다.

방법 대상 결과
git merge --squash 이미 나뉜 다른 브랜치 커밋 전체를 하나로 합쳐 내 브랜치에 커밋
rebase -i 의 squash 내 브랜치 안 커밋들 병합 전에 브랜치 자체를 정리

두 방법 모두 결과 커밋은 부모가 하나뿐인 일반 커밋입니다. git log --format="%h %p" 로 확인하면 부모 해시가 하나만 찍힙니다. 병합 커밋(부모 둘)이 아닙니다.

2.9 git pull --rebase 가 실무에서 쓰이는 이유

git pull 은 내부적으로 fetch 뒤 merge 를 해서, 로컬 커밋과 원격 커밋이 갈라졌으면 병합 커밋이 매번 생깁니다. git pull --rebase 는 merge 대신 rebase 를 써서 로컬 커밋을 원격 최신 뒤로 옮기므로 이력이 계속 한 줄로 유지됩니다.

자주 pull 하는 공용 브랜치에서는 git config pull.rebase true 로 기본값을 바꿔 매번 옵션을 쓰지 않게 합니다.

2.10 log --oneline --graph --all 로 전후 비교

--graph 는 브랜치 갈래를 선으로 그리고, --all 은 현재 브랜치뿐 아니라 모든 브랜치를 함께 보여줍니다. rebase 나 cherry-pick 전후에 이 명령으로 이력 모양이 원하는 대로 바뀌었는지 확인합니다.

text
* cad051f feat: 홈 화면 인사말 추가
| * 673935c feat: 로그인 폼 초기화 버튼 추가
| * eb8952d feat: 검증 메시지 다국어 지원 완료
| | * 3d0c052 fix: 홈 화면 null 체크 추가

feature/greeting, feature/login, hotfix/home-null 세 브랜치가 각자 다른 지점에서 갈라진 모습이 한 화면에 보입니다.

2.11 push --force-with-lease 가 필요한 이유와 조건

rebase 로 이미 push 했던 브랜치의 해시가 바뀌면 일반 git push 는 거부됩니다. 강제로 밀어 넣어야 하는데, git push --force 는 원격 상태를 확인하지 않고 덮어써 동료의 새 커밋을 지울 수 있습니다. git push --force-with-lease 는 내 remote-tracking 브랜치와 실제 원격이 같을 때만 덮어씁니다.

동료가 그 사이 push 했다면 내 remote-tracking 브랜치(origin/브랜치)가 오래된 상태이므로 --force-with-lease 가 거부합니다. fetch 로 최신을 받아 확인한 뒤 다시 시도합니다.

2.12 rerere 와 reflog

같은 충돌을 반복해서 겪는 rebase 라면 git config rerere.enabled true 로 rerere(reuse recorded resolution)를 켭니다. 한 번 해결한 충돌 패턴을 기억해 다음에 같은 충돌이 나면 자동으로 적용합니다. rebase 로 커밋을 잘못 지우거나 잃었을 때는 git reflog 로 직전 위치를 찾아 복구합니다. 자세한 사용법은 레슨 03(되돌리기)을 참고합니다.

핵심 원리
  • 2.1 merge 와 rebase 의 결과 차이
  • 2.2 git rebase main 의 동작
  • 2.3 rebase 충돌 해결 순서
  • 2.4 황금률: 공유된 커밋은 rebase 하지 않는다
  • 2.5 rebase -i 편집 화면과 명령어
  • 2.6 git commit --fixup 과 rebase -i --autosquash
  • 2.7 cherry-pick: 기본·범위·옵션
  • 2.8 merge --squash 와 rebase 의 squash 차이
  • 2.9 git pull --rebase 가 실무에서 쓰이는 이유
  • 2.10 log --oneline --graph --all 로 전후 비교
  • 2.11 push --force-with-lease 가 필요한 이유와 조건
  • 2.12 rerere 와 reflog
이전 섹션1 왜 배우는가2 / 7다음 섹션3 코드 예제