• git fixup은 이전 μ»€λ°‹μ˜ λ‚΄μš©μ„ μˆ˜μ •ν•˜κΈ° μœ„ν•œ 특수 컀밋 생성 μ˜΅μ…˜
  • git rebase --autosquash와 ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ 컀밋 νžˆμŠ€ν† λ¦¬λ₯Ό κΉ”λ”ν•˜κ²Œ μ •λ¦¬ν•˜λŠ” μ›Œν¬ν”Œλ‘œμš°
  • fixup!, amend! μ ‘λ‘μ‚¬λ‘œ λŒ€μƒ 컀밋을 μžλ™ μ‹λ³„ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜

ν•΄λ‹Ή κ°œλ…μ΄ ν•„μš”ν•œ 이유

  • μ½”λ“œ 리뷰 ν›„ μˆ˜μ •μ‚¬ν•­μ„ κΈ°μ‘΄ 컀밋에 κΉ”λ”ν•˜κ²Œ λ³‘ν•©ν•˜κ³  싢을 λ•Œ
  • 컀밋 νžˆμŠ€ν† λ¦¬λ₯Ό 논리적 λ‹¨μœ„λ‘œ μœ μ§€ν•˜λ©΄μ„œ μ μ§„μ μœΌλ‘œ μˆ˜μ •ν•  λ•Œ
  • μˆ˜λ™μœΌλ‘œ interactive rebaseμ—μ„œ pick β†’ fixup λ³€κ²½ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ„ μ—†μ• κΈ° μœ„ν•΄

AS-IS

sequenceDiagram
    autonumber
    participant Dev as Developer
    participant Git as Git

    Dev->>Git: git commit -m "Add login feature"
    Dev->>Git: git commit -m "Fix typo in login"
    Dev->>Git: git commit -m "Add logout feature"
    Dev->>Git: git commit -m "Fix login validation"
    Note over Git: νžˆμŠ€ν† λ¦¬κ°€ μ‚°λ°œμ  ❌<br/>login κ΄€λ ¨ μˆ˜μ •μ΄ 흩어져 있음

TO-BE

sequenceDiagram
    autonumber
    participant Dev as Developer
    participant Git as Git

    Dev->>Git: git commit -m "Add login feature"
    Dev->>Git: git commit --fixup HEAD~2 (typo μˆ˜μ •)
    Dev->>Git: git commit -m "Add logout feature"
    Dev->>Git: git commit --fixup HEAD~3 (validation μˆ˜μ •)
    Dev->>Git: git rebase -i --autosquash main
    Note over Git: νžˆμŠ€ν† λ¦¬κ°€ 깔끔 βœ…<br/>"Add login feature" (μˆ˜μ • 포함)<br/>"Add logout feature"

μ„ ν–‰ κ°œλ…: Interactive Rebase

interactive rebase (git rebase -i)λŠ” 컀밋 νžˆμŠ€ν† λ¦¬λ₯Ό λŒ€ν™”ν˜•μœΌλ‘œ νŽΈμ§‘ν•˜λŠ” κΈ°λŠ₯.

git rebase -i HEAD~5   # 졜근 5개 컀밋을 νŽΈμ§‘ λŒ€μƒμœΌλ‘œ μ—΄κΈ°

μ‹€ν–‰ν•˜λ©΄ 에디터에 todo λ¦¬μŠ€νŠΈκ°€ μ—΄λ¦Ό:

pick abc1234 feat: Add login
pick def5678 fix: typo
pick ghi9012 feat: Add logout
pick jkl3456 fix: login validation

각 μ€„μ˜ pick을 λ‹€λ₯Έ λͺ…λ ΉμœΌλ‘œ λ°”κΏ€ 수 있음:

λͺ…λ Ήμ„€λͺ…
pick (p)컀밋 κ·ΈλŒ€λ‘œ μ‚¬μš©
reword (r)컀밋 λ©”μ‹œμ§€λ§Œ λ³€κ²½
edit (e)μ»€λ°‹μ—μ„œ λ©ˆμΆ°μ„œ μˆ˜μ • κ°€λŠ₯
squash (s)이전 컀밋에 ν•©μΉ˜κΈ° (λ©”μ‹œμ§€ ν•©μΉ¨)
fixup (f)이전 컀밋에 ν•©μΉ˜κΈ° (λ©”μ‹œμ§€ 버림)
drop (d)컀밋 μ‚­μ œ

μ€„μ˜ μˆœμ„œλ₯Ό λ°”κΎΈλ©΄ 컀밋 μˆœμ„œλ„ 변경됨.

μ„ ν–‰ κ°œλ…: Squash vs Fixup

λ‘˜ λ‹€ 컀밋을 이전 컀밋에 ν•©μΉ˜λŠ” λ™μž‘μ΄μ§€λ§Œ 컀밋 λ©”μ‹œμ§€ μ²˜λ¦¬κ°€ 닀름:

pick abc1234 feat: Add login feature
squash def5678 fix: typo in login

β†’ 에디터가 열리며 두 λ©”μ‹œμ§€λ₯Ό ν•©μ³μ„œ νŽΈμ§‘ κ°€λŠ₯

pick abc1234 feat: Add login feature
fixup def5678 fix: typo in login

β†’ fixup μ»€λ°‹μ˜ λ©”μ‹œμ§€λŠ” μžλ™μœΌλ‘œ 버림, 원본 λ©”μ‹œμ§€λ§Œ μœ μ§€

squashfixup
μ½”λ“œ λ³€κ²½ν•©μΉ¨ν•©μΉ¨
컀밋 λ©”μ‹œμ§€λ‘ λ©”μ‹œμ§€ ν•©μ³μ„œ νŽΈμ§‘μ›λ³Έ λ©”μ‹œμ§€λ§Œ μœ μ§€
에디터열림열리지 μ•ŠμŒ
μš©λ„λ©”μ‹œμ§€λ„ λ³΄μ‘΄ν•˜κ³  싢을 λ•Œμ‘°μš©νžˆ μˆ˜μ •λ§Œ λ°˜μ˜ν•  λ•Œ

μ„ ν–‰ κ°œλ…: Autosquash

--autosquashλŠ” fixup!, squash!, amend! 접두사가 뢙은 컀밋을 μžλ™μœΌλ‘œ μ •λ ¬ν•˜κ³  λͺ…령을 λ³€κ²½ν•΄μ£ΌλŠ” μ˜΅μ…˜.

μˆ˜λ™ interactive rebaseμ—μ„œλŠ”:

  1. 에디터 μ—΄λ¦Ό
  2. fixup 컀밋을 직접 λŒ€μƒ 컀밋 μ•„λž˜λ‘œ 이동
  3. pick β†’ fixup으둜 직접 λ³€κ²½

autosquashλ₯Ό μ“°λ©΄ 이 과정이 μ „λΆ€ μžλ™ν™”:

git rebase -i --autosquash main
# μžλ™μœΌλ‘œ μ΄λ ‡κ²Œ 정리됨:
pick abc1234 feat: Add login feature
fixup def5678 fixup! feat: Add login feature   ← μžλ™ 배치 + μžλ™ fixup
pick ghi9012 feat: Add logout feature

κΈ°λ³Έκ°’μœΌλ‘œ μ„€μ •:

git config --global rebase.autoSquash true

이후 git rebase -i만 해도 autosquash λ™μž‘.

fixup의 3κ°€μ§€ λͺ¨λ“œ

1. κΈ°λ³Έ fixup β€” λ‚΄μš©λ§Œ μˆ˜μ •

git commit --fixup=<commit>
  • λŒ€μƒ μ»€λ°‹μ˜ **λ‚΄μš©(μ½”λ“œ)**만 λ³€κ²½
  • 컀밋 λ©”μ‹œμ§€λŠ” 원본 κ·ΈλŒ€λ‘œ μœ μ§€
  • "fixup! <원본 컀밋 λ©”μ‹œμ§€>" ν˜•μ‹μ˜ 컀밋 생성
# μ˜ˆμ‹œ: 3개 μ „ μ»€λ°‹μ˜ 버그λ₯Ό μˆ˜μ •
git add fixed_file.py
git commit --fixup=HEAD~2
# β†’ "fixup! Add login feature" 컀밋 생성

2. amend λͺ¨λ“œ β€” λ‚΄μš© + λ©”μ‹œμ§€ μˆ˜μ •

git commit --fixup=amend:<commit>
  • λŒ€μƒ μ»€λ°‹μ˜ λ‚΄μš©κ³Ό 컀밋 λ©”μ‹œμ§€ λͺ¨λ‘ λ³€κ²½
  • "amend! <원본 컀밋 λ©”μ‹œμ§€>" ν˜•μ‹μ˜ 컀밋 생성
  • 에디터가 μ—΄λ € λ©”μ‹œμ§€λ₯Ό μˆ˜μ •ν•  수 있음

3. reword λͺ¨λ“œ β€” λ©”μ‹œμ§€λ§Œ μˆ˜μ •

git commit --fixup=reword:<commit>
  • --fixup=amend:<commit> --only의 μΆ•μ•½ν˜•
  • λŒ€μƒ μ»€λ°‹μ˜ λ©”μ‹œμ§€λ§Œ λ³€κ²½ (staging된 μ½”λ“œ λ³€κ²½ λ¬΄μ‹œ)
  • μ½”λ“œ λ³€κ²½ 없이 컀밋 λ©”μ‹œμ§€λ§Œ 고치고 싢을 λ•Œ μ‚¬μš©

전체 μ›Œν¬ν”Œλ‘œμš°

# 1. 일반 컀밋듀 μž‘μ„±
git commit -m "feat: Add user authentication"
git commit -m "feat: Add dashboard page"
git commit -m "feat: Add profile settings"
 
# 2. authentication 컀밋에 μˆ˜μ •μ΄ ν•„μš”ν•˜λ‹€λ©΄
git add auth_fix.py
git commit --fixup=HEAD~2
 
# 3. autosquash둜 rebase
git rebase -i --autosquash main

rebase todo λ¦¬μŠ€νŠΈκ°€ μžλ™μœΌλ‘œ μ•„λž˜μ²˜λŸΌ 정리됨:

pick abc1234 feat: Add user authentication
fixup def5678 fixup! feat: Add user authentication   ← μžλ™ 배치
pick ghi9012 feat: Add dashboard page
pick jkl3456 feat: Add profile settings

λŒ€μƒ 컀밋 μ§€μ • 방법

git commit --fixup=HEAD~3        # 3개 μ „ 컀밋
git commit --fixup=abc1234       # 컀밋 ν•΄μ‹œλ‘œ μ§€μ •
git commit --fixup=:/login       # "login"이 ν¬ν•¨λœ κ°€μž₯ 졜근 컀밋

μ°Έκ³  λ¬Έμ„œ