한 리포에서 AI 세션 두 개를 동시에 돌리고 있었습니다. 제 쪽 작업이 끝나서 파일 73개를 스테이징하고, 커밋 메시지를 쓰고 있었습니다.
메시지를 쓰는 사이에 다른 세션이 자기 작업을 커밋했습니다.
제 73개가 그 커밋에 통째로 들어갔습니다. 제 git commit은 "no changes added to commit"으로 끝났습니다.
같은 리포에서 두 개 이상의 에이전트를 돌리고 있다면, 지금 스테이징 영역은 누구의 것입니까?
인덱스는 하나입니다
.git/index는 워킹 트리에 하나뿐입니다. 세션마다 있는 게 아닙니다.
그래서 다른 쪽이 경로를 지정하지 않고 git commit을 하면 인덱스 전체가 나갑니다. 그 인덱스에 제 73개가 들어 있었습니다.
내용은 정확히 들어갔습니다. 코드는 멀쩡합니다. 문제는 메시지가 남의 것이라는 겁니다.
왜 이게 손실인가
나중에 그 변경을 찾을 수 없습니다.
커밋 메시지는 히스토리의 색인입니다. "언제 왜 이걸 고쳤나"를 묻는 유일한 진입점입니다. 73개 파일의 변경이 무관한 제목 아래 묻혀 있으면, git log --grep도 git bisect도 도움이 안 됩니다.
그리고 되돌릴 수도 없습니다. 히스토리를 고치려면 그 커밋을 다시 써야 하는데, 상대가 이미 그 커밋 위에서 계속 작업하고 있습니다.
당신이라면?
같은 리포에서 세션 둘이 돕니다. 어떻게 막겠습니까?
- 커밋 직전에
git status를 본다 — 제가 하던 것. 보는 순간과 커밋하는 순간 사이에 틈이 있다. 그 틈이 이번 사고다. - 세션마다 워크트리를 나눈다 — 근본적으로 맞다. 그런데 워크트리에는 그쪽 고유의 함정이 또 있다(서명 키·시크릿이 복제되지 않고, 릴리스 도구가 메인 체크아웃을 가리킨다).
- 스테이징과 커밋을 끊지 않는다 — 메시지를 미리 준비해서 한 호출로 끝낸다.
지금은 세 번째로 막고 있습니다.
# 스테이징과 커밋을 끊지 않는다. 메시지는 미리 준비해서 한 호출로.
git add <경로들> && git commit -F - -- <경로들> <<'MSG'
...
MSG--로 경로를 다시 명시하는 것이 핵심입니다. 그러면 그 사이 누가 무엇을 스테이징했든 제 경로만 커밋됩니다.
양방향으로 새는 문제입니다
반대 방향 사고도 실제로 있었습니다. git add <디렉터리>가 다른 세션의 미추적 파일까지 집어서, 스테이징에서 빼내야 했습니다.
즉 공유 인덱스는 내 것이 남에게 새고 남의 것이 내게 새는, 양방향 문제입니다. 같은 동거의 다른 얼굴은 검수자가 절반만 고쳐진 트리를 본 이야기에 있습니다. 그래서 git add .이나 경로 없는 git commit은 여러 세션이 도는 리포에서 쓸 수 없습니다.
자가진단 세 줄
- 같은 리포에서 에이전트를 둘 이상 돌립니까? 그렇다면
git add .과 경로 없는git commit은 금지입니다. 인덱스는 공유 자원입니다. - 스테이징과 커밋 사이에 사람이 생각하는 시간이 있습니까? 그 시간이 창입니다. 메시지를 먼저 쓰고 한 호출로 끝내십시오.
git add <디렉터리>를 씁니까? 남의 미추적 파일이 함께 들어옵니다. 파일 경로를 나열하십시오.
솔직한 부분
되돌릴 방법이 없었습니다. 그래서 고치지 않고 기록만 남겼습니다. 그 73개 파일의 변경은 지금도 남의 제목 아래 있습니다.
근본적으로는 세션마다 워크트리를 나누는 게 맞습니다. 그런데 워크트리로 옮기면 다른 함정이 기다립니다 — 무시된 파일이 복제되지 않아 서명 키가 없고, 릴리스 매니페스트가 메인 체크아웃을 가리켜서 내 변경이 없는 바이너리가 올라갑니다.
그래서 지금은 규칙으로 막고 있습니다. 규칙은 깨집니다. 이 글은 그 규칙이 깨졌을 때 무슨 일이 나는지에 대한 기록입니다.