Looking forward to Git 2.56 – and 3.0
Git 2.56를 기다리며, 그리고 Git 3.0
Git 2.56은 `git history drop`, `git add --resolved`, ref 관리 명령을 추가하는 안정적인 릴리스입니다. 다음 버전에서는 SHA-256 기본값, reftable 전환, Rust 빌드 의무화 같은 호환성 변경이 논의되고 있습니다.
- 주제
AI 요약
Git 2.56은 9월 말 출시가 예상되는 릴리스 후보 버전입니다. 병합 커밋을 제외하면 700개가 넘는 커밋이 들어갔지만, 대부분의 사용자 경험을 근본적으로 바꾸는 릴리스는 아닙니다. 더 큰 변화는 다음 릴리스에서 예고됩니다. Git 프로젝트는 Git 3.0을 준비하면서 저장소 형식과 빌드 환경에 영향을 주는 호환성 변경을 검토하고 있습니다.
Git 2.56에 추가되는 기능
실험 단계인 git history 도구에는 git history drop commit-id 명령이 추가됩니다. 현재 브랜치의 이력을 기준으로 지정한 커밋을 제거하고, 그 뒤에 추가된 커밋을 다시 적용합니다. 문제가 된 커밋을 없애는 절차를 단순화하지만, 이력에 병합 커밋이 있으면 동작하지 않습니다.
git status는 추적 중인 브랜치보다 현재 브랜치가 뒤처졌을 때 업데이트를 위한 git pull 명령을 제안합니다. 다만 아직 가져오지 않은 원격 추적 브랜치보다 뒤처진 경우에는 여전히 브랜치가 최신 상태라고 표시합니다. 저수준 ref 조작 명령인 git refs에는 create, delete, update, rename 하위 명령이 추가됩니다.
그 밖에도 git branch --delete-merged는 원격 추적 브랜치에 병합된 로컬 브랜치를 삭제합니다. bisect에 사용 중인 브랜치를 git branch -d로 지우려고 하면 실패 이유를 알려줍니다. 여러 Git 명령이 동시에 설정 파일을 수정할 때 발생하는 잠금 실패는 재시도합니다. git add --resolved는 병합 충돌이 해결된 파일만 스테이징합니다. 버그 수정과 리팩터링, 성능 개선도 함께 포함됩니다.
Git 3.0에서 논의되는 호환성 변경
Git 3.0에서 가장 큰 변화로 거론되는 항목은 새 저장소에서 SHA-256을 기본 해시 함수로 사용하는 일입니다. Git은 지금까지 SHA-1으로 파일, 디렉터리 트리, 커밋 같은 객체를 식별하고 커밋 이력을 검증했습니다. SHA-1의 취약성이 악용되면 감지하기 어려운 이력 변조가 가능해질 우려가 있습니다. Git에는 알려진 SHA-1 공격을 막는 방어 기능이 있지만, 더 강한 해시 함수로 옮기는 편이 합리적이라는 판단이 이어지고 있습니다.
SHA-256을 실험 기능이 아닌 형태로 지원한 시점은 Git 2.42부터입니다. 다만 기존 저장소와의 상호 운용을 위한 작업과 주요 forge 서비스의 지원이 전환을 늦췄습니다. GitLab은 2024년부터 지원했고 Forgejo도 지원합니다. GitHub의 공식 지원 시점은 아직 분명하지 않지만, SHA-256 전환을 이끄는 주요 개발자이자 GitHub 직원인 Brian M. Carlson은 관련 소식이 곧 나올 예정이며 다음 버전을 3.0으로 정하는 편이 좋을 수 있다고 밝혔습니다.
Carlson은 대문자 객체 ID를 허용하는 동작도 바꾸자고 제안했습니다. Git은 객체 ID를 소문자 16진수 문자열로 관리하면서도 대문자 ID를 받아들여 f00f00과 F00F00이 같은 값이 되는 모호성을 허용했습니다. 이 동작에서 버그와 보안 취약점이 발생한 사례가 있는 만큼, 앞으로는 소문자 ID만 받아들이자는 제안입니다.
reftable과 Rust
Git은 현재 기본 설정에서 .git/refs/ 아래에 브랜치와 태그 같은 ref를 파일로 저장합니다. 여러 ref를 packed-refs 파일에 모아 접근 속도를 높일 수도 있지만, ref 수가 많아지면 조회와 특정 커밋을 가리키는 ref 검색 비용이 커집니다. Android 저장소에는 80만 개가 넘는 ref가 있다고 reftable 문서가 설명합니다.
Git 2.45에서 추가된 reftable은 ref를 공간 효율과 빠른 접근에 맞춘 바이너리 파일로 저장합니다. 지금도 reftable 저장소를 만들 수 있지만 기본값은 아닙니다. Git 자체를 사용하는 사람에게는 성능 개선 외에 눈에 띄는 변화가 적을 전망이지만, 저장소를 직접 읽는 외부 라이브러리에는 영향이 생길 수 있습니다. 우려 대상으로 언급된 libgit2는 reftable 지원을 추가했고, 8월에는 SHA-256 지원도 기본 활성화했기 때문에 전환을 막는 요소가 되지 않을 것으로 설명됐습니다.
Rust 코드 지원도 Git 3.0에서 빌드 요구 사항으로 바뀔 가능성이 있습니다. 현재는 Rust 코드를 시험적으로 포함하지만 Rust 컴파일러가 필수가 아닙니다. 변경이 이뤄지면 작동하는 Rust 컴파일러가 없는 플랫폼은 Git을 새 버전으로 업그레이드하기 어렵습니다. Carlson은 JGit과 Gitoxide에 SHA-256 전환이 예정됐다는 사실을 최소 1년 전에 알렸고, Rust를 지원하지 않는 플랫폼을 새로 지원하려는 움직임도 알지 못한다며 두 사안이 3.0의 장애물이 되어서는 안 된다고 주장했습니다.
Git 유지 관리자 Junio Hamano는 다음 릴리스를 3.0으로 할지, 2.x 릴리스를 더 낼지 커뮤니티에 물었습니다. Hamano는 최종 결정이 인기투표나 민주주의로 정해지는 사안은 아니라고 밝혔습니다. 당시 공개된 논의에서는 3.x 시대로 넘어가는 데 강한 반대가 없었습니다. 2026년에 Git 3.0이 나오지 않더라도 그 직후 출시될 가능성이 높다고 설명합니다. 기존 SHA-1 저장소와 reftable을 사용하지 않는 저장소는 계속 지원됩니다.
Hacker News 반응
- @WCSTombs —
git add --resolved는 훌륭한 아이디어입니다. 저라면 분명 사용하기 시작하겠습니다. - @KolmogorovComp — SHA-1에서 SHA-256으로 바꿀 때 강제 푸시를 하고 전체 이력을 다시 작성해야 한다는 뜻인가요? 그렇다면 잠재적인 취약점의 거대한 원인이 되지 않나요?
- @nomel — 이 부분을 잘 모릅니다. 그 일이 어떻게 취약점을 가능하게 하는지 설명해 주실 수 있나요?
- @jayd16 — 다른 검증 없이 강제 푸시를 믿으면 악의적인 이력 변경을 끼워 넣을 수 있습니다.
- @vlovich123 — 내용 자체는 여전히 검증할 수 있습니다. 마이그레이션 뒤에도 콘텐츠 blob은 바뀌지 않습니다. 실제 공격이 가능한지는 확신하지 못하겠습니다.
- @em-bee — 아마 당분간은 새 저장소의 기본값만 바뀔 것 같습니다. SHA-1 지원이 사라지는 것은 아니므로 기존 저장소 대부분은 곧바로 전환되지 않을 겁니다. 전환하려면 강제 푸시가 필요할 수도 있지만, 기존 저장소에서 새 저장소를 만들고 이력을 가져온 뒤 모두가 새 저장소를 의도적으로 다시 클론하게 될 수도 있습니다.
- @infogulch — 모든 커밋의 내용과 메시지가 기존 트리와 바이트 단위로 같은지 검사하는 기능을 만들 수 있지 않나요? 이력을 한 번 훑어 검증하는 일은 저렴하지 않더라도 비교적 단순할 겁니다. Git에 내장해야 합니다.
- @nextaccountic — 이상합니다. 당분간 모든 Git 객체에 SHA-1과 SHA-256을 함께 계산하면 안 되나요? 그게 어렵다면 다른 객체를 감싸면서 “이 객체는 SHA-1이니 건드리지 마세요”라고 표시하는 Git 객체를 만들면 되지 않나요?
- @coliveira — 단지 Rust를 어디에나 쓰게 만들려는 이유로 Rust 사용을 강요하는 것은 유감입니다. 이제 모두에게 강제되는 말도 안 되는 일입니다.
- @tombert — 단지 이유 없이 그러는 것은 아니라고 생각합니다. Rust 코드가 더 안전하다고 믿기 때문일 겁니다.
- @nvme0n1p1 — 시간이 지나며 코드베이스를 천천히 반복해서 개선한다는 생각을 믿지 않나요? 전통과 성능, 유지보수성을 이유로 Git이 이상하게 C와 Perl, 셸 스크립트를 섞은 상태에 영원히 머물러야 하나요?
- @aw1621107 — 즉각적이고 완벽한 해결책이 아니라고 해서 조사하고 추진할 가치가 없는 것은 아닙니다. 새 코드에서 버그가 더 자주 발생하는 경향을 생각하면, 전체 코드에서 차지하는 줄 수보다 새 코드를 메모리 안전 언어로 작성하는 편이 더 큰 효과를 낼 수 있습니다.
- @jcranmer — Git에서 Rust를 쓰려는 이유를 설명하는 최근 발표 자료 링크가 댓글에 있습니다. 모든 이유에 동의하지는 않지만, 단지 이유 없이 쓰는 것은 아닙니다. 바이너리 파일 형식 파서를 C로 작성하면 CVE가 반복해서 발생하고, Rust에서는 그런 문제가 단순히 사라지는 사례가 충분히 쌓였습니다. “충분히 똑똑한 프로그래머라면 C에서 버그를 만들지 않는다”는 변명은 더 이상 통하지 않습니다.
- @eviks — 쟁점은 파서를 만들 수 있느냐가 아니라 안전하게 만들 수 있느냐입니다. 여러 곳에서 주기적으로 CVE가 발생한다는 사실은 후자가 어렵다는 점을 보여줍니다.
- @devilsdata — Rust가 C보다 안전하다고 믿는다면 왜 Git과 Linux, 그리고 C로 작성된 애플리케이션 사용을 중단해야 하나요?
- @eviks — 느린 파일을 버리고 제대로 된 데이터베이스를 사용하려는 다른 계획도 있나요? 아니면 Git의 경쟁 프로젝트에만 맡길 생각인가요?
- @112233 — “제대로 된 데이터베이스”가 관계형 데이터베이스를 뜻하나요? ACID를 뜻하나요? 기존 데이터베이스 소프트웨어를 사용하자는 뜻인가요? Git이 데이터를 저장하는 방식이 무엇 때문에 부적절한가요?
- @cesarb — 파일시스템도 제대로 된 데이터베이스입니다. 다만 관계형 데이터베이스가 아닐 뿐입니다. Linus는 Git을 작성할 때 성능을 중요하게 봤고, Linux 커널 유지 관리자였기 때문에 Linux VFS와 파일시스템이 이 용도에 충분히 빠르다는 점을 알고 있었습니다. 당시에는 하나의 저장소에 ref가 수십만 개 이상 생길 것이라고 예상하지 못했지만, 사용 사례가 달라졌습니다.
- @spankalee — 파일시스템이 없는 환경에서 Git을 사용하는 편이 유용한 곳도 많습니다.
- @globular-toast — GitHub가 SHA-256에서 계속 늦장을 부리는 것이 놀랍지 않습니다. 이제 시스템의 근본적인 부분을 바꾸지 못하는 것 같습니다. SHA-256도 IPv6도 지원하지 않고 주변부에만 기능을 덧붙일 수 있는 것처럼 보입니다.
- @masklinn — 원문은 SHA-256 개발의 주요 인물 중 한 명이 GitHub 직원이며 전환을 지지한다고 명시합니다. GitHub에서는 SHA-256이 비공개 프리뷰 상태이기도 합니다.
- @IshKebab — Git 3.0에서 잘못된 기본값을 전부 고칠 예정인가요?
- @onetoo — 어떤 기본값이 문제라고 보시는지 알려주실 수 있나요? 설정을 바꿔야 하는지 알고 싶습니다.
- @IshKebab —
git push는 기본적으로--force-with-lease --force-if-includes를 사용해야 합니다.push.autoSetupRemote도 기본 활성화해야 합니다. 기본 충돌 스타일은zdiff3여야 합니다.diff.submodule기본값은 더 보기 좋은 서브모듈 diff를 제공하는log여야 합니다. 서브모듈 업데이트와 클론도 기본적으로 재귀적이어야 합니다. - @iib — Git 코어 개발자들이 Git을 설정하는 방식을 모은 GitButler 블로그 글이 있습니다. 제 설정 대부분도 그 글을 참고했습니다.
- @moebrowne — BitBucket도 현재 SHA-256 해시를 지원하지 않는 것 같습니다.
원문: LWN.net / 번역·요약: Trawling