버전 관리의 미래
(bramcohen.com)- Manyana는 Bram Cohen이 개발한 CRDT 기반 버전 관리 프로토타입으로, 병합 충돌을 제거하고 히스토리를 구조적으로 보존하는 새로운 접근을 제시함
- CRDT(Conflict-Free Replicated Data Type) 을 활용해 병합이 항상 성공하며, 충돌을 단순한 정보 표시로 처리해 사용자가 변경 내용을 명확히 인식할 수 있음
- 라인 순서의 영속성, 비차단적 병합, 히스토리 내재화를 핵심으로 하며, 리베이스 과정에서도 기존 기록을 파괴하지 않음
- 약 470줄의 Python 코드로 작성된 데모 수준 구현체로, 전체 코드와 설계 문서가 공개 도메인으로 GitHub에 공개되어 있음
- Git의 한계를 넘어 병합 실패 없는 차세대 버전 관리 모델을 실험적으로 제시한 사례로 평가됨
Manyana: 버전 관리의 미래를 위한 일관된 비전
- Manyana는 Bram Cohen이 공개한 CRDT 기반 버전 관리 시스템 프로토타입으로, 기존 시스템의 병합 충돌 문제를 해결하려는 시도임
- CRDT는 병합이 항상 성공하도록 보장하며, 충돌을 정보적 표시로 처리해 사용자가 실제 변경 내용을 명확히 확인할 수 있게 함
- 이 접근은 라인 순서의 영속성, 비차단적 충돌 처리, 구조 속 히스토리 내재화라는 세 가지 핵심 특성을 가짐
- 리베이스(rebase) 과정에서도 기존 히스토리를 유지하며, 단일 공통 조상이 없는 복잡한 병합 구조도 안정적으로 처리 가능함
- Manyana는 약 470줄의 Python 코드로 작성된 데모 구현체로, 설계 문서와 코드가 공개 도메인으로 GitHub에 공개되어 있음
CRDT 기반 접근의 핵심
- CRDT는 병합이 항상 성공하고, 병합 순서에 상관없이 동일한 결과를 보장하는 eventual consistency를 제공
- 여러 사용자가 독립적으로 작업한 브랜치를 어떤 순서로 병합하더라도 결과가 동일하게 유지됨
-
라인 순서의 영속성을 통해 동일 위치에 삽입된 코드의 순서를 한 번 결정하면 이후에도 유지됨
- 이를 통해 브랜치마다 충돌 구간이 다르게 해결되는 문제를 방지함
-
충돌은 정보 제공용 표시로만 처리되어 병합을 차단하지 않음
- 병합 결과는 항상 생성되며, 충돌은 “가까운 위치에서 동시에 수정된 부분”으로 표시됨
- 각 변경의 주체와 행위를 추적해 유용한 충돌 표시를 제공함
-
히스토리가 구조 속에 내재되어 있음
- 파일의 모든 라인을 포함하는 ‘weave’ 구조로 상태를 표현하며, 각 라인에 추가·삭제 시점의 메타데이터를 포함
- 병합 시 공통 조상을 찾거나 DAG 탐색 없이 두 상태를 입력하면 항상 올바른 결과가 생성됨
향상된 충돌 표시
- 기존 버전 관리 시스템은 충돌 시 단순히 두 코드 블록을 나란히 보여주어 사용자가 직접 차이를 추론해야 함
- Manyana는 각 충돌 구간을 “삭제됨”, “추가됨” 등으로 명시하고, 누가 어떤 변경을 했는지를 표시함
- 예를 들어 한 사용자가 함수를 삭제하고 다른 사용자가 함수 내부에 한 줄을 추가한 경우, Manyana는 각 변경의 구조를 명확히 구분해 보여줌
- 이를 통해 사용자는 두 블록을 비교하는 대신, 변경의 의미와 맥락을 즉시 파악할 수 있음
리베이스의 재정의
- CRDT 기반 시스템에서는 리베이스가 히스토리를 파괴하지 않음
- 기존 리베이스는 커밋을 새 베이스 위에 다시 쌓으며 허구의 히스토리를 생성함
- Manyana에서는 동일한 효과를 얻되, 모든 원래 히스토리를 유지함
- 이를 위해 DAG에 “주요 조상(primary ancestor)” 주석만 추가하면 충분함
- 이 방식은 공통 조상이 없는 병합 구조에서도 안정적으로 작동하며, 전통적인 3-way 병합의 실패를 피할 수 있음
프로젝트의 현재 상태
- Manyana는 완전한 버전 관리 시스템이 아닌 데모 구현체로, 개별 파일 단위에서 동작함
- 약 470줄의 Python 코드로 구성되어 있음
- Cherry-pick과 로컬 undo 기능은 아직 구현되지 않았으나, README에 향후 구현 방향이 제시되어 있음
- 이 프로젝트는 CRDT 기반 버전 관리가 UX 문제를 해결할 수 있음을 입증하며, 기존 도구보다 더 나은 결과를 제공함
- 전체 코드는 공개 도메인(public domain) 으로 배포되며, 설계 문서 전체는 GitHub README에 포함되어 있음
커뮤니티 반응 요약
- 한 사용자는 Git이 10년 넘게 사용되어 왔지만, 새로운 버전 관리 패러다임이 필요하다고 평가하며 Manyana의 시도를 긍정적으로 언급함
- 병합이 항상 성공한다는 개념이 직관적이지 않다고 지적하며 추가 예시와 설명을 요청함
- 리베이스 개선 아이디어에 관심을 보이며, 개인 프로젝트에서 중간 브랜치를 통한 병합 관리 방식을 사용 중이라고 언급함
- Git의 한계로 바이너리 파일 처리, 좌우 브랜치 구분 혼란, 대규모 코드 변경 요약 부족 등을 지적함
- 향후 버전 관리가 토큰 단위 인식(token-aware) 기능이나 언어·파일 형식별 플러그인을 지원하면 좋겠다고 제안함
- 또 다른 사용자는 Manyana가 Pijul이나 Darcs와 유사한 기반을 갖는지 질문하며, Darcs의 성능 문제와 Pijul의 현재 상태 비교를 요청함
결론
- Manyana는 CRDT를 버전 관리에 적용한 실질적 데모로, 충돌 처리와 리베이스 문제를 근본적으로 재설계함
- 병합 실패가 없는 구조, 충돌의 정보화, 히스토리의 구조적 내재화 등은 기존 Git 모델의 한계를 넘어서는 설계 방향을 제시함
- 완전한 시스템은 아니지만, 차세대 버전 관리 시스템의 설계 청사진으로서 의미 있는 출발점임
Hacker News 의견들
-
머지(merge) 표시 방식은 히스토리 표현과는 별개 문제라고 생각함
나도 Git의 기본 머지 UI를 싫어해서 p4merge를 사용함. 네 개의 패널(좌, 우, 공통 베이스, 결과)을 보여주는 도구라 충돌 원인과 해결 방법을 한눈에 볼 수 있음
굳이 VCS 자체를 바꿀 필요는 없다고 봄- p4merge를 쓰지 않더라도 Git의
merge.conflictStyle설정을"diff3"나"zdiff3"로 바꾸면 베이스 버전까지 표시됨
이렇게 하면 충돌 마커만 보고도 어느 쪽이 새로운 코드를 추가했는지 추론할 수 있음 - 대부분의 사람들은 이 문제를 깊게 생각하지 않음
예전에 한 팟캐스트에서 새로운 VCS를 만든 게스트가 Git의 diff 저장 방식을 잘못 이해한 걸 듣고 놀랐음. 수년간 프로젝트를 진행하고도 기본 개념조차 안 찾아본 걸 보면, 여전히 NIH(재발명) 정신이 살아있음을 느낌 - 나도 p4merge 추천함. Git의 머지가 고통스럽다면 그건 개념적 문제보다는 UX 디자인 문제임
- JetBrains IDE(IntelliJ 등)도 훌륭한 머지 UI를 제공함
다만 SCM 레벨에서 처리하면 사용자의 머지 기록을 기억할 수 있다는 장점이 있음. Git은 이런 부분에서 엣지 케이스가 있음 - 일반 디렉터리도 머지할 수 있는지 궁금함
- p4merge를 쓰지 않더라도 Git의
-
머지가 절대 실패하지 않는 게 좋은 일인지 모르겠음
머지 실패는 단순한 위치 충돌이 아니라 의미적 충돌을 알려주는 신호일 때가 많음. 이런 경우는 수동으로 처리해야 함- 제안된 시스템도 겹치는 변경이 있으면 사용자에게 표시한다고 함. Git과의 차이는 기본값 정도의 문제로 보임
- 실제로는 머지가 성공해도 컴파일이 안 되는 코드가 생기기도 함. AI 도구로 머지 충돌을 해결하려 해봤지만, 특히 rebase에서는 잘 안 됨
- 이 시스템은 실패하지 않는 게 아니라, 충돌을 표시하면서도 머지를 계속 진행할 수 있게 하는 개념임. jj도 비슷한 접근을 함
- 단순한 텍스트 머지에 의존해 의미적 문제를 잡으려는 건 한계가 있음. 대신 포스트 머지 검사나 에이전트 기반의 의도 검증이 더 낫다고 봄
-
CRDT는 버전 관리에 적합하지 않다고 생각함
충돌은 버전 관리의 본질임. 두 개발자가 서로 다른 방향으로 코드를 바꾸면, 결국 의미적 선택이 필요함. CRDT는 이런 상황에서 엉뚱한 코드를 만들 가능성이 큼
Git 위에 더 나은 머지 UX를 제공하는 도구들이 이미 많고, cherry-pick이나 revert가 쉬운 것도 Git의 장점임- 물론 자동 머지는 문법적 충돌만 해결할 뿐, 의미적 충돌은 여전히 남음
예를 들어 한 브랜치에서 상수를 삭제하고, 다른 브랜치에서 그 상수를 사용하는 경우 코드가 깨짐
Git의 충돌은 대부분 문법적 문제라, 더 똑똑한 semantic merge나 CRDT 접근이 도움이 될 수도 있음 - CRDT를 머지 계산에만 활용하는 건 가능함
예를 들어 파일 이름, 속성, 해시 등을 추적할 때 OR-set(https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type)을 쓸 수 있음.
다만 충돌 해결은 여전히 외부 인터페이스에서 처리해야 함
- 물론 자동 머지는 문법적 충돌만 해결할 뿐, 의미적 충돌은 여전히 남음
-
CRDT에 집중하는 이유를 잘 모르겠음
충돌의 의미적 문제는 여전히 존재함. 오히려 변경이 뒤섞여(interleave) 보일 수 있어 더 혼란스러움
나는 rebase 중심주의자임. 머지 커밋은 피해야 하고, 모든 커밋은 독립적인 단위여야 함. Gitflow는 안티패턴이라고 생각함
Jujutsu나 Gerrit은 Git의 진짜 문제인 “리뷰 피드백 기반의 커밋 체인 관리”를 잘 해결함- “작업 단위(unit of work)”가 무엇인지가 중요함
Git은 스냅샷을 재적용하기 때문에 같은 작업이 두 번 존재하는 셈임. 반면 Pijul은 패치 단위로 동작해 순서에 상관없이 동일한 결과를 냄. 이게 진짜 독립적인 작업 단위라고 생각함 - CRDT는 머지와 리베이스를 동일한 개념으로 다룰 수 있음
충돌이 있는 상태에서도 특정 커밋만 되돌리기(undo) 가능함. Git보다 유연한 구조를 가질 수 있음 - 항상 rebase만 쓰면 매 커밋마다 충돌을 해결해야 해서 비효율적임
실제로는 최종 결과만 중요할 때가 많음. squash merge를 적절히 섞는 게 현실적임 - CRDT는 모든 문제를 해결한다고 착각하기 쉬움
하지만 어떤 문제는 본질적으로 충돌이 필요함. 예를 들어 동시 편집기에서 문자가 섞이는 현상처럼 오히려 더 나쁜 결과를 낼 수도 있음
- “작업 단위(unit of work)”가 무엇인지가 중요함
-
이 프로젝트는 Bram이 예전에 만든 Codeville의 아이디어를 확장한 것 같음
Codeville은 2000년대 초 DVCS 붐 시절에 등장했고, weave 기반 저장 및 머지를 사용했음. CRDT보다 10년 앞선 개념이지만 자연스럽게 이어지는 아이디어임
Bram이 여전히 이 문제를 붙잡고 새로운 시도를 하는 게 반가움- 진짜 CRDT의 장점은 이해하기 쉬운 동작 모델임. 직접 구현해보면 그 구조가 명확함
- 2007년에 Bram이 내 Causal Tree 알고리즘을 weave의 변형이라고 말했음. 이후 weave 계열 알고리즘이 많이 발전했고, 관련 논문도 있음
arxiv:2002.09511 - CRDT는 단일 기술이 아니라 개념적 프레임워크임. 결국 Git도 eventual consistency를 구현하므로 넓은 의미의 CRDT라고 볼 수 있음
-
“CRDT 기반 VCS는 아직 없다”는 말에 동의하지 않음
이미 Pijul이 존재하고, 전문가들이 수천 시간 투입한 프로젝트임- Bram이 VCS를 많이 안 다뤘다는 뜻은 아님. Codeville만 해도 20년 전부터 있었음
- 나는 매년 Pijul 매뉴얼의 이론 페이지를 확인하는 취미가 있음. 여전히 TeX 포맷팅 오류가 고쳐지지 않았음
6년째 실험 중이고, 4년 전 직접 이슈를 올렸지만 아직 반영되지 않음 - 처음엔 오래된 GitHub 저장소를 찾았는데, 실제 공식 저장소는 Nest에 있음.
Pijul은 자기 자신으로 개발되는 VCS라 GitHub를 쓰지 않음 - 가끔
pijul pull -a를 하면 충돌이 생겨서 그냥 다시 클론함. 추적 업데이트용 pull이 있는지 궁금함
-
manana.py는 473줄짜리 의존성 없는 Python 코드임
실제 구현은 약 240줄뿐이고 나머지는 테스트 코드임. 단순하지만 인상적임- 이름 자체가 농담임. “Mañana”는 스페인어로 내일이지만, “언젠가 하자”는 의미도 있음. 즉, 미루기(procrastination) 를 암시함
- 몇백 줄의 깔끔한 Python으로 이런 걸 만든 게 놀라움
JS 생태계의 left-pad 사건을 떠올리면, Python도 이런 작고 책임감 있는 패키지가 더 많아져야 한다고 생각함
-
이런 시스템은 팀 규모별로 머지 충돌의 양상을 분석해서 설계해야 함
1인, 10인, 100인, 1000인 팀이 각각 어떤 문제를 겪는지, 그리고 에이전트 기반 개발이 이를 어떻게 바꿀지도 고려해야 함
내 경험상 1~100명 규모에서는 팀별로 코드 서브트리를 나눠서 충돌이 거의 없음.
에이전트가 늘어나면 100명이 1000명처럼 될 수도 있겠지만, 아직은 실제 문제보다 솔루션이 먼저 나온 느낌임- 에이전트는 어떤 버전 관리 시스템이든 다룰 수 있음
요즘은 그냥 Codex에게 머지 충돌을 맡기면 끝이라, 굳이 새로운 VCS를 쓸 이유가 줄었음
Git은 대규모 팀을 위해 설계됐고, 에이전트 시대에는 프로세스 자동화로 충분히 대응 가능함 - 팀 규모가 커져도 자연스럽게 코드 영역별 전문화가 일어나서 충돌 빈도는 비슷함.
문제는 오히려 공유 라이브러리의 병목이나 접근 제한 정책에서 생김 - 팀 규모별 분석으로 접근하는 건 오히려 비효율적임. 그냥 개념적으로 일관된 설계가 중요함
- 에이전트는 어떤 버전 관리 시스템이든 다룰 수 있음
-
충돌보다 더 큰 문제는 Git의 확장성(scalability) 임
저장소 크기와 변경 속도가 한계에 다다르고 있음. 서버, 클라이언트, 프로토콜 전반의 재설계가 필요함- 어떤 확장성 문제가 있었는지 궁금함. 혹시 모노레포 때문인지?
- 해결책 중 하나는 코드를 모듈화하고 버전 종속성으로 참조하는 것임
-
개인적으로 이 시스템이 어떤 문제를 해결하는지 잘 모르겠음
추상적으로는 흥미롭지만, 실제로는 jj가 Git보다 훨씬 실용적임
다음 단계는 파일 단위가 아니라 AST 수준에서 버전 관리를 하는 시스템이라고 생각함.
LightTable이나 Dark 같은 시도가 있었는데, 이런 트리 기반 VCS를 실험해보면 좋겠음- 이미 그런 방향의 시도가 진행 중임. 새로운 파서 시스템을 구축하고 있음