콘텐츠로 이동

한 폴더에서 여러 AI를 돌리다 — 멀티세션과 worktree 격리

1인 개발이지만, AI 세션은 여러 개를 동시에 굴립니다. 한 세션이 출퇴근을, 다른 세션이 결재를 짭니다. 혼자서도 여러 명처럼 일할 수 있으니 빠릅니다. 그런데 같은 폴더를 공유하니, 한 세션의 작업이 다른 세션의 커밋에 슬쩍 섞여 들어가는 사고가 났습니다. 이 글은 “왜 세션을 병렬로 굴리는지”, “git add -A가 멀티세션에서 왜 흉기가 되는지”, 그리고 “두 단계 방어 — 커밋 위생과 worktree 격리 — 가 무엇인지”를 풀어 쓴 기록입니다.

AI 협업의 숨은 이점 하나는 병렬입니다. 사람 혼자라도 AI 세션을 여러 개 띄우면, 각 세션이 동시에 다른 모듈을 진행할 수 있습니다. 한 세션은 출퇴근 화면을 다듬고, 다른 세션은 결재 로직을 고치고, 또 다른 세션은 문서를 정리합니다. 1인 개발의 처리량이 몇 배로 뜁니다.

그래서 세션마다 자연어로 “이 세션은 출퇴근”, “이 세션은 결재”처럼 선언하면 각자의 작업 상태(어디까지 했나, 다음 할 일)가 따로 저장되도록 격리 장치를 뒀습니다. 세션의 기억은 이렇게 분리됐습니다. 문제는 따로 있었습니다 — 코드가 놓인 폴더는 여전히 하나였습니다.

git의 작업 모델을 한 줄로 말하면 이렇습니다. 한 폴더 = 하나의 작업 트리(working tree). 그 폴더 안의 모든 변경은 한 곳에 모입니다. 누가 그 변경을 만들었는지 git은 구분하지 않습니다.

이제 사고가 어떻게 나는지 보겠습니다. 세션 A가 출퇴근 파일 몇 개를 고쳐서 아직 커밋하지 않은 채 떠 있습니다. 그때 세션 B가 자기 작업(결재)을 커밋하려고 무심코 git add -A를 칩니다. 이 명령은 “지금 폴더에서 변경된 모든 것”을 담습니다 — 그 “모든 것”에는 세션 A가 진행 중인 미커밋 파일까지 포함됩니다. 결과적으로 A의 작업이 B의 결재 커밋에 통째로 빨려 들어갑니다.

이게 왜 그렇게 나쁠까요? 단순히 파일이 잘못된 커밋에 들어간 정도가 아닙니다. 나중에 결재 커밋을 되돌려야 할 일이 생기면, 거기 섞인 출퇴근 작업까지 함께 사라집니다. 코드리뷰를 할 때는 “이 결재 커밋에 웬 출퇴근 CSS가?” 하는 혼란이 생깁니다. 이력을 추적할 때는 “이 출퇴근 변경이 대체 언제, 왜 들어왔지?”를 영영 알 수 없게 됩니다. 한번 뒤섞인 두 작업을 깨끗이 떼어내는 건 거의 불가능에 가깝습니다 — 그래서 섞이기 전에 막는 것이 유일하게 싼 해법입니다.

git add -A 가 섞는 순간 하나의 작업 폴더 세션 B 변경 — 결재.ts 세션 A 변경 — 출퇴근.ts (미커밋!) 세션 A 변경 — 출퇴근.css (미커밋!) git은 누가 만들었는지 구분 안 함 add -A B의 결재 커밋 결재.ts + 출퇴근.ts + 출퇴근.css A의 작업이 통째로 빨려 들어감 → 리뷰·롤백·이력 전부 오염
git add -A의 사고(개념도). 한 폴더의 모든 변경을 담기 때문에, 다른 세션이 진행 중인 미커밋 파일(빨강)까지 내 커밋에 섞여 들어갑니다.

이 문제를 두 겹으로 막았습니다. 하나는 행동 규칙(위생), 하나는 구조적 격리(worktree)입니다.

커밋 위생 — 내 것만 명시적으로

섹션 제목: “커밋 위생 — 내 것만 명시적으로”

먼저 규칙을 박았습니다. git add -A·git add . 금지. 대신 내가 이번 세션에 만들고 고친 파일만 경로를 하나하나 명시해서 담습니다.

  1. add 금지 — “전부 담기”(-A, .)를 쓰지 않습니다.
  2. 명시적 경로 — 내가 건드린 파일만 경로를 적어 담습니다.
  3. 커밋 전 확인 — 담긴 목록을 눈으로 확인해, 전부 내 작업이 맞는지 봅니다.
  4. 남의 것은 그대로 — 내가 안 건드린 변경은 “다른 세션 것”으로 보고 손대지 않습니다. 되돌리지도, 지우지도 않습니다.

이건 “하나의 커밋은 하나의 목적”이라는 원칙의 git 버전입니다. 커밋이 깔끔하게 분리되면, 리뷰도 롤백도 이력 추적도 깨끗해집니다. 그리고 이 위생은 1인 멀티세션뿐 아니라, 여러 사람이 PR로 협업할 때도 똑같이 통하는 공통 기반입니다.

위생만으로는 부족합니다. 사람(혹은 AI)이 한 번 실수하면 또 뚫립니다. 더 강한 격리는 git worktree입니다.

같은 저장소를 공유하되 작업 폴더를 세션마다 따로 떼어주니, 세션 A의 미커밋 변경이 세션 B의 폴더에는 아예 보이지 않습니다. 섞일 물리적 경로가 없어집니다. 그래서 큰 리팩토링처럼 충돌 위험이 큰 작업은 격리된 worktree에서 진행하고, 메인이 조용할 때 깔끔히 합쳤습니다.

방어막는 방식비유한계
커밋 위생”내 것만 명시적으로 담기” 규칙주의 깊게 짐 싸기한 번 실수하면 뚫림
worktree 격리폴더 자체를 물리적으로 분리각자 다른 방에서 작업정리 안 하면 디스크·junction 사고

worktree는 공짜가 아닙니다. 격리를 얻는 대신 정리의 규율이라는 비용을 치러야 합니다.

두 방어를 언제 쓰나 — 작업에 맞춰 고르기

섹션 제목: “두 방어를 언제 쓰나 — 작업에 맞춰 고르기”

두 방어가 항상 둘 다 필요한 건 아닙니다. 작업 성격에 따라 고릅니다. 무거운 worktree 격리를 모든 작업에 쓰면 그것대로 비용입니다.

  1. 작은 단발 수정 — 한 세션이 잠깐 고치는 정도면 커밋 위생만으로 충분합니다. 내 파일만 명시적으로 담으면 됩니다.
  2. 여러 세션이 같은 시간대에 활발히 커밋 — 섞일 위험이 큽니다. 가능하면 worktree로 폴더를 분리합니다.
  3. 큰 리팩토링·전사 스윕 — 변경 파일이 많고 오래 걸립니다. 반드시 격리된 worktree에서 하고, 메인이 조용할 때 합칩니다.
  4. 작업 종료 — 어느 경우든 커밋 목록을 눈으로 확인하고, 격리 폴더는 git 명령으로 정리합니다.

요컨대 위생은 기본값, 격리는 위험이 클 때입니다. 둘은 배타적이지 않습니다 — 격리된 worktree 안에서도 커밋 위생은 그대로 지킵니다. 격리가 “방을 나누는 것”이라면, 위생은 “방 안에서 짐을 똑바로 싸는 것”입니다. 방을 나눠도 짐을 엉망으로 싸면 다른 문제가 생깁니다.


이 글은 SL.AIMS를 만들며 겪은 현장 회고 중 하나입니다. 전체 그림은 〈사례연구: SL.AIMS〉에, 세션의 기억을 어떻게 분리·보존하는지는 〈AI는 세션이 바뀌면 다 잊는다〉에 있습니다.