Jujutsu 실전 워크플로우: Git 고인물도 놀라는 5가지 고급 기술
지난 '첫걸음 튜토리얼'에서 우리는 Jujutsu(jj
)가 '스테이징 영역'을 없애고, jj undo
를 통해 모든 실수를 되돌릴 수 있게 하여 '두려움 없는 개발'을 가능하게 한다는 것을 배웠습니다.
하지만 Jujutsu의 진정한 힘은 단순한 실수 방지를 넘어, Git에서는 여러 단계를 거쳐야 했던 복잡한 '역사 편집' 작업을 믿을 수 없을 만큼 단순화하는 데 있습니다.
오늘은 Git 전문가들이 git rebase -i
를 열어 고군분투하던 바로 그 작업들을, Jujutsu가 어떻게 한두 개의 명령어로 우아하게 해결하는지, 5가지 실전 시나리오를 통해 알아보겠습니다.
시나리오 1: "앗, 이 커밋 너무 커요!" (커밋 쪼개기)
개발을 하다 보면, 급한 마음에 여러 가지 관련 없는 변경 사항을 하나의 커밋에 담아버리는 경우가 종종 있습니다.
나중에 이를 논리적인 단위로 쪼개는 것은 코드 리뷰와 유지보수를 위해 매우 중요합니다.
- 'Git 방식': 악명 높은
git rebase -i <commit-ish>
를 시작하여 해당 커밋을edit
으로 표시합니다.
그다음git reset HEAD^
로 커밋을 풀고,git add -p
를 사용하여 변경 사항 조각들을 하나씩 스테이징하며 여러 개의 새 커밋을 만들어야 합니다.
매우 번거롭고 실수하기 쉬운 과정입니다. - 'Jujutsu 방식': 단 하나의 명령어로 끝납니다.
# 먼저 jj log로 쪼개고 싶은 커밋의 ID를 확인합니다. (예: a1b2c3d4)
# jj split 명령어를 실행합니다.
jj split a1b2c3d4
이 명령어를 실행하면, Jujutsu는 즉시 인터랙티브한 'diff' 뷰를 열어줍니다.
여러분은 그저 각 코드 변경 사항(hunk)을 보면서, '이 조각은 기존 커밋에 남길까, 아니면 새로 만들 커밋으로 옮길까?'를 방향키나 단축키로 결정하기만 하면 됩니다.
선택이 끝나면, Jujutsu는 자동으로 두 개의 커밋으로 분리해 줍니다.
그 후 jj describe
로 각 커밋의 메시지만 수정하면 모든 작업이 끝납니다.
시나리오 2: "지저분한 WIP 커밋들, 하나로!" (커밋 합치기)
하나의 기능을 개발하며 "WIP(Work In Progress)", "fix", "oops" 같은 메시지로 여러 개의 작은 커밋을 쌓는 것은 흔한 일입니다.
Pull Request를 만들기 전, 이들을 하나의 의미 있는 커밋으로 합치는 작업이 필요합니다.
- 'Git 방식': 또다시
git rebase -i
를 사용합니다.
합치고 싶은 커밋들을squash
나fixup
으로 표시하고, 커밋 메시지를 편집하는 과정을 거쳐야 합니다. - 'Jujutsu 방식': 이 역시 훨씬 더 직관적입니다.
# 합치고 싶은 여러 커밋을 한 번에 지정합니다.
# "a1b2..f9g8"은 a1b2부터 f9g8까지의 모든 커밋을 의미합니다.
jj squash "a1b2..f9g8"
이 명령 하나로 지정된 범위의 모든 커밋이 하나의 커밋으로 합쳐집니다.
Jujutsu는 자동으로 합쳐진 커밋들의 메시지를 모아 새로운 커밋 메시지 편집기를 열어주므로, 여러분은 최종 메시지만 깔끔하게 정리하면 됩니다.
시나리오 3: "이 기능은 다음에 할래요" (커밋 재정렬)
A 기능과 B 기능을 순서대로 개발했습니다.
그런데 갑자기 B 기능을 먼저 배포해야 하는 상황이 생겼습니다.
두 커밋의 순서를 바꿔야 합니다.
- 'Git 방식':
git rebase -i
를 열고, 텍스트 에디터에서 커밋 라인의 순서를 직접 잘라내고 붙여넣어야 합니다.
충돌이라도 발생하면 머리가 아파지기 시작합니다. - 'Jujutsu 방식': 'rebase'라는 개념을 더 명확하게 사용합니다.
"어떤 변경사항을(source), 어디로(destination) 옮길까?" 라고 명령하면 됩니다.
# B 기능의 커밋 ID가 'b_commit'이고, A 기능의 커밋 ID가 'a_commit'이라고 가정
jj log
# B 커밋을 A 커밋의 부모(루트)로 재배치합니다.
jj rebase -s b_commit -d root()
# 또는, A 커밋을 B 커밋 위로 옮길 수도 있습니다.
jj rebase -s a_commit -d b_commit
Jujutsu의 jj rebase
는 Git의 리베이스보다 훨씬 더 유연하고 강력합니다.
마치 레고 블록을 빼서 원하는 위치에 다시 끼워 넣는 것처럼, 히스토리를 자유자재로 재구성할 수 있습니다.
시나리오 4: "이 코드는 그냥 버릴래요" (변경사항 폐기)
실험적으로 만들었지만 결국 필요 없어진 커밋을 히스토리에서 완전히 제거하고 싶습니다.
- 'Git 방식':
git rebase -i
에서 해당 커밋 라인을drop
으로 바꾸거나 아예 삭제해야 합니다.
한번 삭제하면reflog
없이는 되돌리기 어렵습니다. - 'Jujutsu 방식': '폐기한다'는 의도를 명확히 표현하는 명령어가 있습니다.
jj abandon <commit-id>
이 명령은 해당 커밋을 히스토리에서 제거합니다.
하지만 여기서 Jujutsu의 안전성이 빛을 발합니다.
만약 마음이 바뀌었다면? 그냥 jj undo
를 입력하세요.
폐기했던 커밋이 마법처럼 다시 돌아옵니다.
시나리오 5: 동료와 협업하기 (대화형 로그와 원격 작업)
여러 개의 커밋 스택을 동료에게 리뷰 요청하거나 원격 저장소에 푸시해야 합니다.
Jujutsu는 jj log
에 -i
또는 --interactive
플래그를 제공하여, 로그 뷰를 하나의 거대한 '컨트롤 패널'처럼 사용할 수 있게 해줍니다.
# 인터랙티브 로그를 엽니다.
jj log -i
이 뷰 안에서 여러분은 방향키로 커밋을 선택하고, 단축키를 눌러 바로 describe
(메시지 수정), split
, squash
등의 작업을 수행할 수 있습니다.
여러 개의 커밋을 원격에 푸시하는 것 또한 간단합니다.
# 현재 checkout된 커밋부터 그 조상들을 모두 푸시합니다.
jj git push --rev @-
Jujutsu는 각 커밋 스택에 해당하는 브랜치를 자동으로 관리하고 푸시해주므로, 개발자는 브랜치 이름이나 관계에 대해 크게 신경 쓸 필요가 없습니다.
결론: 당신의 Git 워크플로우를 업그레이드하세요
오늘 살펴본 시나리오들은 Jujutsu가 제공하는 강력한 기능의 일부에 불과합니다.
Jujutsu는 Git의 복잡하고 기계적인 절차들을 자동화하고, 개발자가 '무엇을 하고 싶은지'라는 본질적인 의도에만 집중할 수 있도록 도와줍니다.
더 이상 커밋 히스토리를 수정하는 것을 두려워할 필요가 없습니다.
오히려 레고 블록을 조립하듯 즐겁게 역사를 다듬고, 더 깔끔하고 논리적인 코드 히스토리를 만들 수 있게 됩니다.
Git의 rebase
에 익숙하지만 그 과정이 번거롭다고 느꼈던 모든 개발자에게, Jujutsu는 단순한 대안이 아닌 '혁신적인 업그레이드'가 될 것이라고 확신합니다.