Git 엄격함 피로 극복하기: Jujutsu

많은 개발자에게 이상적인 풀 리퀘스트는 선별된 서사이다: 구현을 검토자에게 안내하는 논리적이고 원자적인 커밋들의 연속—타입 정의부터 시작해 데이터베이스 함수로 이동하고 UI로 끝난다. 하지만 실제로는 개발이 급박할 때 이 "엄격함"을 유지하는 것이 매우 힘들다.

우리 대부분은 "혼란 커밋"이라는 패턴에 빠진다: 기능 작업, 버그 수정, 리팩터링이 뒤섞여 몇 개의 지저분한 체인지셋에 모여 있다. git rebase -ijj absorb 같은 도구가 이를 정리해 주긴 하지만, 병합 충돌이나 부정확한 변경 할당 같은 새로운 마찰을 일으키는 경우가 많다. 이를 "git 엄격함 피로"라고 부른다—깨끗한 히스토리를 유지하려 애쓰는 동시에 복잡한 기술 문제를 해결하려는 정신적 부담이다.

"빨래 더미" 워크플로우

이 피로를 극복하기 위해, 작업 복사본을 일급 커밋으로 취급하는 버전 관리 시스템인 Jujutsu (jj)를 사용해 보다 여유로운 접근 방식을 채택할 수 있다. 개발 에 완벽한 히스토리를 유지하려 애쓰는 대신, 이 워크플로우는 혼란을 받아들이고 마지막에 한 번에 정리할 것을 제안한다.

프로세스

  1. 혼란을 받아들여라: 기능을 일반적으로 개발한다. 즉석 커밋을 만들고, 임시 디버깅 상태를 포함하며, 특정 변경이 어디에 들어가는지 걱정하지 않는다. 아마도 지저분하고 겹치는 커밋들의 연속이 될 것이다.
  2. 이상적인 상태 정의: 기능이 완성되면, 이상적인 히스토리의 "뼈대"를 만든다. jj new를 사용해 원하는 설명적 제목을 가진 빈 커밋을 만든다(예: "define types", "add DB functions", "server CRUD").
  3. 혼란 정리: 실제 개발 커밋들을 모두 하나의 "everything commit"으로 스쿼시한다.
  4. 변경 사항 배분: jj squash -i를 사용해 인터랙티브하게 "everything commit"의 변경을 이상적인 뼈대 커밋으로 옮긴다. "red" 변경(타입)을 타입 커밋으로, "blue" 변경(UI)을 UI 커밋으로 옮기는 식이다.

프로세스가 끝나면 "everything commit"은 비어 있게 되고, 히스토리는 검토자를 위해 완벽히 구조화된다.

왜 이것이 전통적인 방법보다 우수한가

jj split이나 일반적인 인터랙티브 리베이스와 비교했을 때, 이 "laundry" 방법은 여러 장점을 제공한다:

  • 충돌 위험 감소: 최종적이고 안정된 상태에서 새로운 히스토리로 변경을 옮기기 때문에, 개발 중에 반복적으로 사용되는 jj squash -i에서 흔히 발생하는 중간 병합 충돌을 피할 수 있다.
  • 인지 부하 감소: 코딩 흐름 중에 변경이 어느 커밋에 속하는지 결정할 필요가 없다. 마지막에 한 번만 "정렬" 작업을 수행한다.
  • 유연성: 가장 단순한 청크를 먼저 정렬하는 것이 쉬워지며, 이것이 히스토리 나머지 순서에 어떤 영향을 미칠지 고민할 필요가 없다.

트레이드오프와 반론

모든 워크플로우와 마찬가지로, 이 접근법에도 단점이 있다. 주요 우려는 중간 커밋이 컴파일되지 않을 수 있다는 점이다. 팀이 PR의 모든 커밋이 CI를 통과하고 빌드 가능해야 한다면, 이 방법은 논리적 카테고리별로 정렬하고 시간 순 의존성을 무시하기 때문에 큰 장애가 될 수 있다.

이 주제에 대한 커뮤니티 토론은 "좋은 커밋"의 가치에 대한 더 넓은 논쟁을 강조한다.

"깨끗한 히스토리"에 대한 주장

"Jujutsu가 작업 복사본을 커밋으로 취급하는 접근 방식은 Git rebase 워크플로우에서 흔히 발생하는 많은 마찰점을 해결한다." — @danborn26

이러한 사용자들에게 VCS를 스토리텔링 도구로 활용할 수 있다는 점은 리뷰 과정을 크게 효율화한다.

"Squash and Merge"에 대한 주장

반대로, 팀이 머지 시 전체 PR을 하나의 커밋으로 스쿼시한다면, 완벽한 히스토리를 만들기 위해 들인 노력이 헛된 것이라고 주장하는 사람도 있다.

"나는 마침내 PR을 스쿼시하는 것을 받아들였고, 좋은 커밋을 쓰려고 청춘을 낭비했다는 것을 깨달았다." — @drdrey

다른 사람들은 완벽히 깨끗한 히스토리가 실제로 디버깅에 유용할 수 있다고 지적한다. 이는 설계가 어떻게 도출되었는지에 대한 진화적 맥락을 없애버리기 때문이다.

최종 생각

Git이든 Jujutsu이든, 목표는 코드를 작성하고 그 히스토리를 기록하는 사이의 마찰을 줄이는 것이다. 일부는 처음부터 원자 커밋의 규율을 선호하고, 다른 일부는 스쿼시를 통해 히스토리를 완전히 지우는 것을 선호하지만, "빨래 더미" 접근법은 중간 지점을 제공한다: 생성 과정에서 자유롭게 지저분하게 작업하고, 이후에 서사를 정교하게 다듬을 수 있는 힘을 제공한다.

SUMMARY: Jujutsu를 사용해 복잡한 기능 개발을 관리하는 새로운 워크플로우를 탐구하여, 활발한 개발 중에 깨끗한 커밋 히스토리를 유지하는 정신적 부담을 피한다.

TITLE: Git 엄격함 피로 극복하기: Jujutsu

Sources