워크트리란
git 워크트리(worktree)는 하나의 저장소에서 여러 개의 작업 디렉터리를 동시에
유지하는 기능입니다. 평소에 git checkout 으로 브랜치를 전환하면 작업 디렉터리가
한 번에 하나만 보이지만, 워크트리를 쓰면 main 과 dev 가 각자 자기 폴더에
상주한 채 동시에 실행됩니다.
# 워크트리 없이 (보통)
repo/ ← 브랜치를 전환해야만 다른 브랜치 파일을 볼 수 있다
# 워크트리 사용
repo.git/ ← bare 저장소 (객체 DB·이력만, 작업 파일 없음)
repo-main/ ← main 브랜치 작업 디렉터리 (운영 인스턴스 실행)
repo-dev/ ← dev 브랜치 작업 디렉터리 (개발 인스턴스 실행)
두 워크트리는 같은 객체 저장소를 공유하므로 Git 이력은 중복 복제하지 않습니다. 체크아웃 파일·의존성·빌드 결과는 트리마다 공간을 차지하므로 작업마다 트리를 추가하지 않습니다.
왜 이 프로젝트에서 쓰나
contextBio 백엔드(AURORA · PepDesigner)는 서버에서 프로세스가 상시 실행 중입니다. 브랜치를 전환하며 같은 폴더를 재사용하면:
- 전환 순간 파일이 바뀌어 실행 중인 프로세스가 깨질 수 있다
- 개발 테스트가 운영 요청을 방해한다
- "지금 어느 브랜치가 돌고 있나"를 확인해야 한다
워크트리를 쓰면 이 문제가 구조적으로 사라집니다.
핵심 원칙: 코드 이력은 하나로 유지하되, 실행 환경은 물리적으로 둘로 분리한다. 릴리즈 워크트리는
main만, 개발 워크트리는dev만 — 어느 폴더가 무슨 브랜치인지는 항상 자명합니다.
프로젝트별 위치
경로 기준: /mnt/S1/sdata/agents/ (c3 에서는 /data/agents/… 로 보입니다)
| 서비스 | bare 저장소 | 운영 워크트리 (main) | 개발 워크트리 (dev) |
|---|---|---|---|
| AURORA | ContextBio/AURORA.git |
ContextBio/AURORA · 포트 6081–6084 |
dev/AURORA · 6091 |
| PepDesigner | ContextBio/PepDesigner.git |
ContextBio/PepDesigner · 8081 |
dev/PepDesigner · 8082 |
폴더가 늘어나지 않게 관리하기
기존 운영 main 1개와 개발 dev 1개를 재사용합니다. 작업을 시작할 때마다 clone하거나 worktree를 추가하지 않습니다. 새 작업 트리는 사용자가 명시적으로 요청할 때만 만듭니다. 서비스가 사용 중인 작업 트리에서는 브랜치를 바꾸지 않고, 다른 작업의 미커밋 변경도 덮어쓰지 않습니다.
서버의 /data/agents와 /mnt/S1/sdata/agents는 같은 NFS 공유일 수 있습니다.
realpath와 findmnt로 확인하며 서버마다 새 클론을 만들지 않습니다. 브랜치와 복구용
참조는 폴더를 추가하지 않고 Git 내부에 보관할 수 있습니다. 완료된 임시 트리는
변경·고유 커밋·서비스 사용 여부를 확인한 뒤 git worktree remove로 정리합니다.
처음 설정하는 법
사용자가 새 서비스를 설정하도록 요청한 경우에만 사용하는 최초 구성 절차입니다. 기존 서비스의 작업마다 반복하지 않습니다.
# 1. 기존 클론을 bare 저장소로 전환 (또는 처음부터 bare 클론)
git clone --bare https://github.com/contextBio/MyService.git \
/mnt/S1/sdata/agents/ContextBio/MyService.git
# 2. 운영 워크트리 (main 브랜치)
git -C /mnt/S1/sdata/agents/ContextBio/MyService.git \
worktree add ../MyService main
# 3. 개발 워크트리 (dev 브랜치)
git -C /mnt/S1/sdata/agents/ContextBio/MyService.git \
worktree add /mnt/S1/sdata/agents/dev/MyService dev
이후 각 워크트리에서 의존성을 따로 설치합니다.
# 운영
cd /mnt/S1/sdata/agents/ContextBio/MyService
python -m venv .venv && .venv/bin/pip install -r requirements.txt
# 개발
cd /mnt/S1/sdata/agents/dev/MyService
python -m venv .venv && .venv/bin/pip install -r requirements.txt
dev 에서 설치한 패키지가 운영에 남아 "운영에서는 재현되지 않는 성공"을 만드는 사고를 구조적으로 차단합니다.
자주 쓰는 명령
# 워크트리 목록 확인
git worktree list
# 폴더를 늘리지 않고 브랜치 참조 생성
git branch feature/new-thing dev
# 워크트리 제거 (작업 폴더도 삭제)
git worktree remove ../MyService-feature
# 워크트리 정리 (폴더를 직접 지운 경우)
git worktree prune
코드 변경 흐름
앱 개발 워크트리에서 검증한 커밋을 운영 브랜치에 반영하고 백엔드를 배포한다.
화면은 회사 사이트 워크플로가 앱 소스를 가져와 별도로 빌드한다. 앱 저장소에
푸시한 것만으로 회사 사이트의 deploy.yml 또는 deploy-dev.yml이 실행되지는 않는다.
회사 사이트 브랜치 푸시나 지원되는 워크플로 실행 후 배포 결과를 확인한다.
정본 경로와 단계별 검증은 운영 소스·실행 관리를 따른다.
dev 에서 작업·푸시
cd /mnt/S1/sdata/agents/dev/AURORA
# …커밋…
git push origin dev
릴리즈 (운영 워크트리에서)
각 저장소의 release.sh 가 한 번에 처리합니다 — main 에 dev 를 머지하고
태그를 붙여 푸시한 뒤 재기동, /api/version 으로 확인합니다.
/mnt/S1/sdata/agents/ContextBio/AURORA/release.sh
무엇이 나갈지 미리 보려면:
release.sh --dry-run
릴리즈 스크립트는 운영 워크트리가 main 이 아니거나 커밋되지 않은 변경이
있으면 멈춥니다 — 잘못된 상태에서 릴리즈되는 것을 막기 위해서입니다.
긴급 수정(핫픽스)
운영 main을 기준으로 수정 브랜치를 만들고, 서비스가 사용하지 않는 기존 작업 트리에서 필요한 수정만 검증한다. 적절한 기존 트리가 없으면 경합 상황을 설명하고 새 작업 트리에 대한 명시 요청을 받는다.
검증된 커밋을 main에 반영해 배포한 뒤 dev에도 반영한다. 운영 폴더의 미커밋 변경을
덮어쓰거나 핫픽스를 위해 관련 없는 dev 변경 전체를 병합하지 않는다.
실행·데이터 격리
워크트리를 써도 의도적으로 격리하지 않으면 개발이 운영을 건드릴 수 있습니다.
| 항목 | 격리 방법 |
|---|---|
| 의존성 (venv · node_modules) | 워크트리마다 따로 설치 |
| 환경 변수 (포트·DB 이름) | 각 디렉터리의 .env — 버전 관리 제외 |
| 포트 | 운영·개발 각각 다른 번호 (표 참고) |
| AURORA 잡 디렉터리 | jobs (운영) / jobs-dev (개발) |
스키마 마이그레이션·업로드 파일·인덱스는 코드 롤백과 무관하게 남습니다. 운영 마이그레이션은 배포 전 백업을 전제로 하고, 컬럼 삭제처럼 되돌릴 수 없는 변경은 추가와 제거를 두 번의 배포로 나눕니다.
주의사항
체크아웃을 옮길 때
워크트리 경로를 바꾸면 그 안에 사는 것들이 따라가지 않습니다.
- crontab 경로 — 경로가 어긋나면 감시 cron 이 조용히 아무것도 하지 않습니다.
crontab -e로 새 경로로 갱신해야 합니다. - PepDesigner
users.db—lib/PepDesigner/dashboard/users.db가 체크아웃 안에 있습니다. 폴더를 옮기면 계정 DB 가 따라가지 않으므로 먼저 파일을 챙기십시오. - 홈 디렉터리 의존 —
~/.claude/.credentials.json,~/.local/share/notebooklm-mcp,~/GoogleDrive/…는 기계마다 다릅니다. 서버를 옮길 때 확인이 필요합니다.
AURORA 의 cron
c3 의 crontab 은 경로 절대값으로 등록돼 있습니다. 워크트리를 옮긴 뒤 반드시 cron 도 함께 갱신하십시오 — 갱신하지 않으면 워커가 죽어도 되살아나지 않습니다.
@reboot /data/agents/ContextBio/AURORA/ensure-aurora-api.sh
*/5 * * * * /data/agents/ContextBio/AURORA/ensure-aurora-api.sh >/dev/null 2>&1
@reboot /data/agents/dev/AURORA/ensure-aurora-api-dev.sh
*/5 * * * * /data/agents/dev/AURORA/ensure-aurora-api-dev.sh >/dev/null 2>&1
pkill 을 직접 치지 말 것
# 위험 — ssh 세션 자신의 cmdline 에 패턴이 들어 있어 자기 셸을 먼저 죽입니다
ssh c3 'pkill -f "serve_api.R …--workers"'
# 안전 — 스크립트 파일로 실행 (cmdline 에 패턴이 없습니다)
ssh c3 '/data/agents/ContextBio/AURORA/ensure-aurora-api.sh'