파일을 부르는 방법은 두 가지입니다. 어느 폴더에 있는지로 부르거나, 내용에서 계산한 지문으로 부르거나. 코드가 바뀌어 온 기록을 저장하는 프로그램 git은 뒤쪽을 씁니다. Anthropic이 10월 13일 git 대신 쓰기 시작했다고 밝힌 자체 시스템 Scion도 같습니다.
옆(좁은 화면에서는 아래) 나무에서 파일을 하나 골라 글자를 고쳐 보세요.
상자마다 위 줄이 위치 이름, 아래 줄이 지문(앞 7자리)입니다. 주황 상자는 지문이 바뀐 곳입니다. faq.md 끝에 물음표를 하나 더한 상태로 시작합니다. 지문은 git과 같은 방식(SHA-1)으로 이 자리에서 계산합니다. 고치기 전 꼭대기 지문 9349304는 같은 파일로 만든 저장소에서 git이 낸 값과 같습니다.
해시 함수(hash function)는 어떤 내용이든 받아서 정해진 길이의 숫자 하나를 내놓는 계산 규칙입니다. 그 숫자를 해시라고 하고 이 글에서는 지문이라고 부르겠습니다.
git이 쓰는 SHA-1은 0과 1을 160개 늘어놓은 지문을 만듭니다. 0이나 1 한 자리를 비트라고 합니다. 160비트는 길어서 네 비트씩 묶어 0~9, a~f 한 글자로 적습니다(16진수). 그러면 40글자가 됩니다.
칸 하나가 비트 하나입니다. 두 지문에서 값이 다른 칸만 주황으로 칠했습니다. 두 칸의 글을 바꿔 보세요.
사람 지문처럼 내용마다 다르고 같은 내용이면 누가 언제 계산해도 같습니다. 다만 사람 지문과 달리 느낌표 하나만 붙여도 지문이 통째로 달라집니다. 비슷한 글이라고 지문이 비슷해지지 않습니다.
거꾸로 지문에서 원래 글을 되살릴 수는 없습니다. 아무리 긴 파일도 160비트로 줄이니 대부분의 정보는 남지 않습니다. 지문은 잠갔다 여는 암호가 아니라 같은지 확인하는 데 쓰는 요약입니다.
git은 파일 내용을 blob이라는 덩어리로 저장하고 blob의 이름은 내용의 지문입니다. 파일이 어느 폴더에 있는지, 파일 이름이 무엇인지는 지문 계산에 들어가지 않습니다.
저장소는 지문을 주면 내용을 돌려주는 사전처럼 동작합니다. 히어로의 프로젝트에 LICENSE를 src/와 docs/에도 복사해 넣었다고 해 보겠습니다. 같은 내용이 세 군데 있어도 저장소에는 blob 하나만 들어가고 파일 이름을 바꿔도 blob은 그대로입니다. git 공식 문서가 적어 둔 성질입니다.
위(넓은 화면에서는 왼쪽)는 폴더 속 파일, 아래(오른쪽)는 저장소에 실제로 들어간 blob입니다. 테두리 색은 blob마다 하나씩 붙였고 점 하나가 그 blob을 쓰는 파일 하나입니다.
폴더는 tree로 저장됩니다. tree의 내용은 "종류, 이름, 지문"을 한 줄씩 적은 목록입니다. 이 목록을 다시 해시 함수에 넣은 값이 폴더의 지문입니다.
파일 하나가 바뀌면 목록의 한 줄이 바뀌고 그래서 폴더 지문이 바뀝니다. 그 폴더 지문은 다시 바깥 폴더 목록의 한 줄입니다. 이렇게 지문을 묶어 지문을 만들며 쌓은 나무를 Merkle tree라고 부릅니다. 암호학자 Ralph Merkle의 이름을 땄습니다.
히어로의 나무와 같은 프로젝트입니다(LICENSE 복사본은 넣지 않은 원래 상태). 목록은 git이 보여 주는 모양(git ls-tree) 그대로이고 바뀐 줄을 칠했습니다.
커밋(commit)은 "이 시점의 프로젝트 전체"를 저장한 기록입니다. 안에는 꼭대기 tree의 지문, 바로 앞 커밋(부모)의 지문, 무엇을 했는지 적은 메시지가 들어 있고 이 묶음으로 다시 지문을 계산합니다.
부모 지문이 커밋 안에 들어가니, 옛 커밋 하나만 고쳐도 그 뒤 커밋의 지문이 줄줄이 바뀝니다. 기록을 몰래 고치면 마지막 지문만 봐도 들킵니다.
같은 프로젝트를 세 번에 나눠 커밋했습니다. 마지막 커밋의 tree가 히어로의 꼭대기 지문 9349304입니다. 설명을 위해 커밋 내용을 tree·부모·메시지로 줄여 계산했고 실제 git 커밋에는 작성자와 시각도 들어갑니다.
어제와 오늘의 프로젝트가 같은지 알고 싶으면 꼭대기 지문 두 개만 비교하면 됩니다. 다르면 한 층 내려가서 같은 이름의 폴더끼리 지문을 비교합니다. 지문이 같은 폴더는 열어 보지 않고 넘어갑니다. 그 안의 내용이 전부 같기 때문입니다.
오늘 나무의 맨 아래 점(파일)을 눌러 바뀐 파일을 늘리거나 줄여 보세요.
파일이 16개든 1,600만 개든, 하나만 바뀌었다면 내려가는 길은 나무의 층 수만큼입니다. git 공식 문서도 두 tree를 비교할 때 지문이 같은 항목은 무시할 수 있어서 차이를 빨리 찾는다고 설명합니다.
여기서 Scion 이야기로 돌아옵니다. 서버 한 대가 모든 요청을 받으면 느리니까, 가까운 곳에 데이터를 복사해 두는 캐시(cache)를 둡니다. 캐시가 늘 부딪히는 문제가 있습니다. 원본이 바뀌었는데 복사본이 옛 내용을 들고 있으면 어떻게 할까요?
원본 서버의 app.js 를 이미 고친 상태로 시작합니다. 빨간 칸은 옛 내용을 들고 있는 사본, 초록 칸은 새 내용입니다. 위의 두 요청 방식을 바꿔 가며 보세요.
지문으로 부르면 한 이름에 담긴 내용은 영원히 같습니다. 새 내용은 새 이름을 받으니 옛 복사본도 틀리지 않습니다. 옛 이름의 정확한 사본으로 남을 뿐입니다. Anthropic은 Scion의 데이터가 전부 내용 주소(지문 이름)이고 바뀌지 않아서 "어느 서버든 조율 없이 캐시할 수 있다"고 적었습니다.
Scion은 작업 컴퓨터마다 하나씩 도는 프로그램(scion-daemon), 지역 캐시, 원본 서버의 세 층으로 데이터를 나눠 둡니다. 층마다 찾는 것이 이미 캐시에 있는 비율이 99%를 넘는다고 밝혔습니다. 회사 저장소에 하루 합쳐지는 변경은 2026년 5월 약 2,500건에서 9월 3만 건 이상으로 늘었다고 합니다.
git은 처음 받을 때 서버와 "내가 가진 것"을 주고받으며 보낼 것을 맞춥니다. Scion의 작업 컴퓨터는 그 대화를 하지 않고 꼭대기 tree부터 필요한 지문을 하나씩 불러 내려갑니다. 요청마다 바뀌지 않는 데이터 하나를 가리키니 어느 캐시가 답해도 되고 보지 않을 폴더는 아예 받지 않습니다.
기록 방식도 다릅니다. git 커밋은 꼭대기 tree를 가리키지만 Scion의 changeset은 첫째 부모와 비교해 바뀐 파일만 적고 그 내용은 지문을 주소로 삼아 따로 저장합니다.
캐시 그림에서 작업 컴퓨터는 "main 이 가리키는 새 지문"을 먼저 알아냈습니다. 지문으로 부르는 데이터는 바뀌지 않으니, "지금 최신 버전"은 따로 적어 둬야 합니다. 브랜치(branch)가 그 일을 합니다. 브랜치는 커밋 하나의 지문을 가리키는 이름표이고 보통 main이 최신 커밋을 가리킵니다. 위 커밋 그림의 main 딱지입니다.
A와 B가 같은 main(c3)을 보고 각자 c3 위에 커밋을 하나씩 만들어 동시에 올리려 합니다. 점선 원은 아직 main에 붙지 못한 커밋입니다. "다음 단계"를 눌러 보세요.
이름표는 여러 사람이 동시에 옮기려 하는 곳이라, 저장소에서 유일하게 조심해서 다뤄야 합니다. Scion은 이름표를 옮길 때 "내가 처음 본 값이 아직 그대로일 때만 바꾸고 그 사이 누가 먼저 옮겼으면 실패로 돌려보내는" 방식(compare-and-swap)을 씁니다. 그래서 줄을 세워 한 명씩 기다리게 하지 않아도 남의 커밋을 덮어쓰지 않습니다.
Scion은 main과 배포용 브랜치 말고는 이름표를 거의 쓰지 않습니다. 여럿이 함께 바꾸는 값이 늘어날수록 규모를 키우기 어려워서라고 설명합니다.
겹칠 수 있습니다. 파일 내용은 끝없이 다양한데 지문의 가짓수는 정해져 있기 때문입니다. 반 친구가 13명이면 달은 12개뿐이라 생일이 같은 달인 친구가 반드시 생기는 것과 같습니다. 아래는 단어 40개의 지문을 앞 몇 글자로만 줄여 상자에 넣은 모습입니다.
점 하나가 단어 하나입니다. 지문의 앞 글자가 같으면 같은 상자에 들어갑니다. 글자가 하나 늘 때마다 상자는 16배가 됩니다. git의 40글자 지문이라면 상자가 2의 160제곱 개, 10의 48제곱 개쯤 됩니다.
40글자면 우연히 겹칠 걱정은 사실상 하지 않습니다. 문제는 누군가 일부러 같은 지문을 가진 두 파일을 만들어 내는 경우입니다. SHA-1에서는 실제로 그런 일이 일어났습니다. 그래서 git은 더 긴 지문으로 옮겨 가는 중입니다.
2017년 2월 23일, 연구자들이 SHAttered라는 방법으로 지문이 같은 서로 다른 PDF 문서 두 개를 만들어 보였습니다. git은 2.13.0 버전부터 이런 조작 파일을 알아채는 SHA-1 계산 방식을 기본으로 씁니다.
git은 256비트 지문을 쓰는 SHA-256 저장소도 지원하고 앞으로 새 저장소의 기본값을 SHA-256으로 바꾸겠다고 문서에 밝혀 두었습니다. 지문 계산법이 바뀌어도 내용으로 이름을 붙이는 원리는 같습니다.
정리하면 세 가지입니다. 이름만 비교해서 같은지 압니다. 꼭대기 지문 하나로 전체를 확인합니다. 이름이 곧 내용이니 복사본이 틀릴 일이 없습니다. git이 오래 써 온 이 성질을, Scion은 하루 3만 건이 넘는 변경을 받는 저장소의 캐시 설계까지 밀고 나갔습니다.
Anthropic은 Scion이 일반적인 git 대체품은 아니라고 밝혔습니다. 아주 큰 저장소 하나를 수만 명이나 수많은 AI 에이전트가 함께 쓰는 경우를 위한 설계이고 공개 계획도 없습니다. 대신 git 사용자가 쓸 수 있는 아이디어를 GitHub·GitLab과 함께 나누겠다고 했습니다.