“체크포인트가 Git으로 만들어진다면, 지금 작업 중인 브랜치나 스테이징 영역도 몰래 바뀌는 것 아닐까?”
에이전트에게 파일 수정을 맡길 때 꽤 자연스럽게 생기는 의문입니다. Git은 되돌리기에 익숙한 도구지만, 개발자가 쓰는 저장소를 자동화 도구까지 함께 만지기 시작하면 이야기가 달라집니다. 사용자가 스테이징해 둔 변경과 자동 체크포인트가 섞일 수 있고, 임시 커밋이 작업 이력에 남거나, 현재 브랜치의 상태가 예상과 다르게 변할 수도 있으니까요.
Hermes의 체크포인트를 이해할 때 첫 질문은 “Git을 쓰는가?”보다 “어느 Git 저장소를 쓰는가?”여야 합니다. 결론부터 말하면, 체크포인트는 Git의 객체·트리·커밋 표현을 이용하지만 프로젝트의 기존 .git을 체크포인트 저장소로 사용하지 않습니다. 별도의 그림자 저장소와 별도의 인덱스를 둬서, 되돌리기 기능과 개발자의 Git 작업을 분리합니다.[1][2]
첫 질문: 자동 저장이라면 현재 브랜치에 커밋이 쌓일까?
Hermes 문서에서 체크포인트는 파일을 바꾸는 도구가 실행되기 전에 작업 트리를 스냅샷으로 남기고, 이후 /rollback으로 이전 상태를 고르는 기능으로 설명됩니다. 체크포인트는 사용자가 명시적으로 켤 수 있으며, 보관 개수도 설정할 수 있습니다.[1]
여기까지만 읽으면 “수정 전마다 임시 커밋을 현재 브랜치에 만드는 방식”을 떠올리기 쉽습니다. 하지만 실제 구현은 프로젝트 저장소에 git commit을 실행하는 구조가 아닙니다. 체크포인트 관리자는 Hermes 홈 아래에 공유 그림자 Git 저장소를 만들고, 프로젝트마다 별도의 참조와 인덱스 파일을 사용합니다. Git 명령을 실행할 때 작업 트리는 대상 프로젝트를 가리키되, GIT_DIR과 GIT_INDEX_FILE은 그림자 저장소 쪽을 가리키도록 환경을 구성합니다.[2]
이 차이가 중요합니다. Git에서 작업 트리, 객체 저장소, 인덱스는 서로 다른 역할을 합니다.
- 작업 트리는 실제 파일이 있는 프로젝트 폴더입니다.
- 객체 저장소는 파일 내용과 트리, 커밋 객체를 보관합니다.
- 인덱스는 다음 트리를 만들기 위해 준비한 파일 상태를 담습니다.
- 참조는 특정 커밋을 가리키는 이름입니다.
Hermes는 “어떤 파일을 복원할 것인가”를 알기 위해 프로젝트의 작업 트리를 읽지만, 스냅샷 객체와 인덱스, 체크포인트 참조는 별도 공간에 둡니다. 그래서 사용자가 보고 있는 브랜치의 HEAD나 프로젝트 .git/index를 체크포인트 기록장으로 삼지 않아도 Git의 내용 주소 방식과 트리 비교 기능은 활용할 수 있습니다.[2]
질문이 바뀐다: 분리만 하면 충분할까?
저장소를 프로젝트마다 하나씩 복제하는 방식도 분리는 됩니다. 그러나 프로젝트 수가 늘면 같은 내용의 객체가 여러 저장소에 반복 저장될 수 있습니다. 구현이 공유 그림자 저장소를 두는 이유는 여기에도 있습니다. 프로젝트별 경계는 별도의 참조와 인덱스로 유지하면서, 동일한 내용의 Git 객체는 공유 객체 저장소에서 중복을 줄일 수 있습니다.[2]
즉, 설계의 핵심은 “프로젝트별 저장소를 하나 더 만든다”가 아니라 다음 두 층을 분리하는 데 있습니다.
- 내용 저장 층: 여러 프로젝트가 사용할 수 있는 그림자 객체 저장소
- 프로젝트 상태 층: 프로젝트마다 구분되는 체크포인트 참조와 인덱스
이 구조라면 프로젝트 A의 체크포인트 이름이 프로젝트 B와 섞이지 않으면서도, 동일한 파일 내용은 Git 객체의 해시 기반 저장 특성을 이용할 수 있습니다. 다만 이것을 곧바로 “디스크를 몇 퍼센트 절약한다”는 운영 효과로 해석해서는 안 됩니다. 구현상 중복 제거가 가능한 구조라는 것과 실제 여러 프로젝트에서 측정한 절감률은 다른 주장입니다. 이번 확인에서는 장기간의 저장량 비교를 하지 않았습니다.
복원할 때는 무엇이 움직이는가
체크포인트에서 복원할 때 사용자가 기대하는 것은 과거 커밋으로 브랜치를 옮기는 일이 아니라, 선택한 시점의 파일 내용을 작업 트리에 되돌리는 일입니다. 공식 문서는 전체 체크포인트 복원뿐 아니라 특정 파일만 고르는 복원 흐름도 안내합니다.[1] 구현과 회귀 테스트도 스냅샷 생성, 목록 조회, 전체 복원, 선택 파일 복원, 보관 한도 같은 동작을 나눠 확인합니다.[2][3]
여기서 안전 경계를 다시 볼 수 있습니다.
- 프로젝트의 브랜치 HEAD를 체크포인트 커밋으로 이동하지 않습니다.
- 사용자가 스테이징한 프로젝트 인덱스를 체크포인트 인덱스로 재사용하지 않습니다.
- 복원 대상은 작업 트리의 파일 내용입니다.
- 체크포인트 메타데이터는 그림자 저장소의 프로젝트별 참조에서 관리됩니다.
물론 “원래 .git을 건드리지 않는다”가 “아무 위험도 없다”는 뜻은 아닙니다. 롤백은 실제 작업 트리 파일을 바꾸는 기능입니다. 아직 다른 곳에 보존하지 않은 최신 변경이 있다면, 잘못된 체크포인트를 선택해 덮어쓸 수 있습니다. 체크포인트 분리는 Git 메타데이터 충돌을 줄이는 장치이지, 복원 선택 자체의 실수를 없애는 장치는 아닙니다.
안전한 최소 재현
실제 프로젝트 대신 임시 폴더에서 다음 순서로 확인하면 경계를 비교하기 쉽습니다.
- 임시 폴더에 작은 Git 저장소를 만들고
note.txt한 파일을 커밋합니다. - 현재
HEAD값과.git/index파일의 해시를 기록합니다. - 별도의 임시
HERMES_HOME을 지정한 상태에서 체크포인트 관리자를 켭니다. note.txt가before인 상태에서 체크포인트를 하나 만듭니다.- 파일 내용을
after로 바꾼 뒤 그 체크포인트로 복원합니다. - 파일 내용, 프로젝트 HEAD, 프로젝트 인덱스 해시, 그림자 객체 저장소 존재 여부를 각각 비교합니다.
공식 저장소의 회귀 테스트를 이용하고 싶다면, 격리된 홈을 지정한 뒤 체크포인트 테스트 파일만 실행할 수 있습니다.[3]
export HERMES_HOME="$(mktemp -d)"
python -m pytest -o 'addopts=' -q tests/tools/test_checkpoint_manager.py
이 명령은 외부 제공자를 호출하거나 실제 프로젝트를 수정하는 실험이 아닙니다. 다만 Python 의존성이 설치된 Hermes 개발 환경에서 실행해야 합니다.
기대 결과
코드와 공식 테스트가 규정하는 기대 결과는 이렇습니다.
- 체크포인트가 생성되고 목록에서 조회됩니다.
- 복원 뒤
note.txt가before로 돌아옵니다. - 프로젝트의 HEAD와
.git/index해시는 체크포인트 작업 전후로 같습니다. - 체크포인트 객체는 별도의 그림자 저장소에 존재합니다.
이번 글의 증거 경계
이 글에는 위 로컬 스모크의 명령·원출력·전후 해시를 독립적으로 확인할 수 있는 공개 영수증을 포함하지 않았습니다. 따라서 생성 성공, 목록 개수, 복원 결과, 프로젝트 HEAD·인덱스 불변을 이번 작업의 관찰 사건으로 주장하지 않습니다. 위 항목은 동결 구현과 공식 회귀 테스트가 규정하는 기대 계약이며,[2][3] 재현하려면 같은 fixture에서 명령과 전후 해시를 새 영수증으로 남겨야 합니다.
이 계약이 다루는 범위도 한정적입니다. 여러 기가바이트 저장소, 서브모듈, 희소 체크아웃, 동시 다중 프로세스, 충돌이 있는 복원까지 자동으로 검증한 것은 아닙니다.
확인 범위와 남은 질문
이번 확인에서는 문서, 체크포인트 구현, 공식 회귀 테스트를 읽었습니다. 프로젝트의 .git과 그림자 저장소가 분리된다는 핵심 경계는 이 공개 근거의 계약으로 설명하며, 별도 로컬 재현을 완료 증거로 사용하지 않습니다.
반면 다음 항목은 이번 글에서 직접 확인하지 못했습니다.
- 대형 저장소 여러 개를 오래 운영했을 때의 실제 저장 공간 절감률
- 체크포인트 생성 중 프로세스가 강제 종료됐을 때의 모든 복구 경로
- 서브모듈·Git LFS·희소 체크아웃과 조합했을 때의 동작
- 여러 Hermes 프로세스가 같은 프로젝트를 동시에 수정하는 상황
- 운영 중 잘못된 롤백 선택을 얼마나 자주 방지하는지에 대한 사용자 연구
처음의 질문은 “Git이면 내 브랜치를 건드리는가?”였습니다. 구현을 따라가면 더 정확한 질문으로 바뀝니다. “작업 트리를 되돌리되, 개발자의 Git 메타데이터와 자동화의 스냅샷 메타데이터를 얼마나 명확히 분리했는가?” Hermes의 그림자 체크포인트는 바로 그 경계를 Git의 구성 요소 수준에서 나눠 놓은 설계입니다.
Sources
[1] Checkpoints & Rollback — Hermes Agent 공식 문서
[2] 체크포인트 관리자 구현
[3] 체크포인트 관리자 회귀 테스트