TechFeedTechFeed
개발자 작업환경

깃 워크트리, 스태시, 체크아웃 | 핫픽스를 다른 폴더에서 어떻게 빼나?

핫픽스가 오면 스태시 대신 깃 워크트리로 형제 폴더를 깐다. 객체는 공유하고 체크아웃만 따로 둔다. 같은 브랜치는 두 폴더에 동시에 못 깐다. 노드 모듈과 환경 파일, 도커 포트는 워크트리마다 다시 준비한다. 개발자, 깃허브, Next.js, 백엔드, 데브옵스, 커서, API 기준으로 리무브와 프룬, 리페어 순서만 남긴다.

by

핫픽스가 오면 스태시를 쓰지 않습니다. 형제 폴더에 깃 워크트리를 하나 더 깔면, 반쯤 고친 파일은 그대로 두고 다른 브랜치를 동시에 엽니다. 객체 칸은 같은 저장소를 씁니다. 헤드와 인덱스만 폴더마다 다릅니다. 같은 브랜치는 두 폴더에 동시에 깔리지 않습니다. 노드 모듈과 환경 파일은 워크트리마다 다시 준비합니다. 저는 12개 사이트 핫픽스를 이렇게 빼고, 끝나면 리무브와 프룬으로 폴더를 지웁니다.


커서 3 에이전트 창이 만든 워크트리와 터미널 명령은 같은 칸이 아닙니다. 에이전트 창은 커서 3 분석에 두고, 여기는 깃 명령만 봅니다. 네이버 클라우드에 올리는 저장소도 명령은 같습니다. 숫자는 2026년 8월 깃 워크트리 공식 문서 기준입니다.


스태시가 깨지는 자리

파일 이름만 바뀐 작업 중이면 스태시가 편합니다. 새 파일과 삭제, 이름 변경이 섞이면 꺼낼 때 충돌이 납니다.


공식 문서 예시도 같은 장면입니다. 리팩터 도중에 급한 수정이 오면, 지저분한 작업 트리를 건드리지 말고 임시 워크트리를 만들라고 적혀 있습니다. 스태시는 한 폴더의 변경을 선반에 올립니다. 워크트리는 폴더를 하나 더 엽니다. 클론을 하나 더 받으면 객체 칸이 두 벌이 됩니다. 워크트리는 객체 칸을 공유합니다.


갈래무엇을 남기나언제 쓰나주의
스태시한 폴더의 변경을 선반에 올림파일 몇 개, 이름 변경 없음꺼낼 때 충돌, 선반을 잊기 쉬움
워크트리형제 폴더 + 별도 헤드·인덱스핫픽스, 리뷰, 두 브랜치 동시같은 브랜치 이중 체크아웃 거부
클론 한 벌 더객체 칸까지 복제권한·리모트가 완전히 다를 때디스크와 페치가 두 배
분리 헤드 워크트리브랜치 없이 커밋만 체크아웃시험 빌드, 버릴 실험-d 또는 --detach

정본은 깃 워크트리 문서입니다. 로컬 컨테이너 런타임은 오르브스택 비교에 있고, 여기는 폴더를 나누는 자리만 봅니다.


공식 예시의 장면 | 문서 예시는 git worktree add -b emergency-fix ../temp master로 임시 폴더를 만듭니다. 고치고 커밋한 뒤 git worktree remove ../temp로 지웁니다. 메인 폴더의 리팩터는 손대지 않습니다.


형제 폴더에 핫픽스 워크트리를 만든다

메인 저장소의 부모 폴더에 새 경로를 줍니다. 브랜치 이름을 경로 끝으로 두면 깃이 그 이름으로 새 브랜치를 만듭니다.


지금 있는 브랜치를 열려면 경로 뒤에 브랜치 이름을 적습니다. 새 이름을 강제로 쓰려면 -b입니다. 이미 있는 이름을 덮어쓰려면 -B입니다. 커밋만 보고 버리려면 -d입니다. 오리진에만 있는 이름이면, 리모트가 하나일 때 추적 브랜치를 만들어 줍니다. worktree.guessRemote를 켜면 경로 끝 이름과 같은 리모트 추적을 먼저 찾습니다.


핫픽스 워크트리를 형제 폴더에 깐다
# 메인 저장소: ~/work/tech cd ~/work/tech git fetch origin # 경로 끝 이름(hotfix-login)으로 새 브랜치를 만들고 체크아웃 git worktree add -b hotfix-login ../tech-hotfix-login origin/main # 이미 있는 릴리스 브랜치를 다른 폴더에서 연다 git worktree add ../tech-release-2026 release/2026-08 # 버릴 실험. 브랜치를 만들지 않는다 git worktree add --detach ../tech-try HEAD git worktree list

목록의 첫 줄은 메인 워크트리입니다. 그 아래가 연결 워크트리입니다. 잠겨 있으면 locked, 폴더가 사라져 지울 수 있으면 prunable이 붙습니다. 스크립트는 --porcelain-z를 같이 씁니다. 경로에 한글이나 공백이 있어도 줄이 안 갈립니다.


목록을 스크립트가 읽게 찍는다
git worktree list --verbose git worktree list --porcelain -z | tr '\0' '\n'
노트북 터미널에 깃 저장소와 형제 폴더가 열린 개발 책상
핫픽스는 스태시가 아니라 형제 폴더의 워크트리로 뺀다

같은 브랜치는 두 폴더에 못 깐다

이미 체크아웃된 브랜치를 다른 워크트리에 다시 열면 명령이 거절합니다. --force가 아니면 두 폴더가 같은 브랜치를 동시에 잡지 않습니다.


에러 문장은 버전마다 조금 다릅니다. 뜻은 같습니다. 그 브랜치는 이미 다른 작업 트리가 잡고 있다. 핫픽스를 메인에서 딴 새 이름으로 빼면 이 거절을 피합니다. 정말 같은 브랜치를 두 곳에서 봐야 하면 --force입니다. 인덱스가 서로 덮일 수 있어서, 리뷰용 읽기에만 씁니다.


경로가 이미 등록돼 있는데 폴더만 지워진 경우도 거절합니다. 그때는 --force 한 번입니다. 잠긴 경로를 다시 쓰려면 --force를 두 번 줍니다.


이미 깔린 브랜치를 새 이름으로 뺀다
# 거절 예: main 이 메인 폴더에 이미 깔려 있다 # git worktree add ../tech-main-copy main # 새 이름으로 같은 커밋에서 시작한다 git worktree add -b hotfix-login ../tech-hotfix-login origin/main # 누가 그 브랜치를 잡고 있는지 본다 git worktree list git branch -vv

참조는 공유, 헤드는 폴더마다 | refs/heads는 저장소가 같이 씁니다. 헤드와 인덱스, refs/bisect 같은 칸만 워크트리마다 다릅니다. 한 폴더에서 브랜치를 지우면 다른 폴더의 그 이름도 사라집니다. 커밋은 객체 칸에 남습니다.


노드 모듈과 환경 파일은 워크트리마다 따로다

워크트리는 소스만 깔립니다. node_modules.env.local은 따라오지 않습니다. 넥스트 앱이면 설치와 환경 복사를 한 번 더 합니다.


심볼릭 링크로 노드 모듈을 공유하면 락파일이 다른 브랜치에서 깨집니다. 핫픽스 폴더에서 다시 설치하는 편이 안전합니다. 환경 파일은 메인에서 복사하되, 포트와 데이터베이스 이름을 바꿉니다. 같은 포트로 두 넥스트를 띄우면 한쪽이 죽습니다. 시크릿을 커밋하지 않는 칸은 환경변수 체크리스트와 같습니다.


핫픽스 폴더에서 설치하고 포트를 나눈다
cd ../tech-hotfix-login # 락파일이 있는 패키지 매니저를 그대로 쓴다 npm ci # 또는: pnpm install --frozen-lockfile # 메인 환경은 복사만 하고, 로컬 포트는 덮어쓴다 cp ../tech/.env.local .env.local printf '\nPORT=3002\n' >> .env.local npm run dev

도커 컴포즈를 쓰는 저장소는 프로젝트 이름과 볼륨이 폴더 이름을 따릅니다. 형제 폴더면 컨테이너 이름이 갈립니다. 고정 컨테이너 이름을 컴포즈에 박아 두면 두 워크트리가 한 컨테이너를 뺏습니다. 컴포즈 파일의 container_name을 빼거나, 워크트리마다 오버라이드 파일을 둡니다. 이미지 줄이기는 멀티스테이지 빌드에 있습니다.


두 개의 터미널 창에서 서로 다른 포트로 로컬 서버를 띄운 화면
워크트리마다 설치와 포트를 나눈다. 노드 모듈을 심볼릭으로 묶지 않는다

폴더를 옮기면 리페어부터 한다

파인더나 mv로 폴더만 옮기면 연결이 끊깁니다. git worktree move가 정석이고, 이미 옮겼으면 repair입니다.


연결 워크트리의 맨 위 .git은 디렉터리가 아닙니다. 메인 저장소의 .git/worktrees/이름을 가리키는 파일입니다. 메인을 옮기면 연결 쪽이 메인을 못 찾습니다. 연결만 옮기면 메인이 연결을 못 찾습니다. 서브모듈이 있는 워크트리는 move가 거절합니다. 문서도 슈퍼프로젝트의 다중 체크아웃을 권하지 않습니다.


옮긴 뒤 연결을 다시 붙인다
# 정석: 깃이 양쪽 경로를 같이 고친다 git worktree move ../tech-hotfix-login ../hotfix/login # 이미 mv 로 옮긴 뒤. 새 폴더 안에서 고친다 cd ../hotfix/login git worktree repair # 메인까지 같이 옮겼으면 메인에서 연결 경로를 넘긴다 cd ~/work/tech git worktree repair ../hotfix/login ../hotfix/pay git worktree list

잠금과 프룬으로 죽은 칸을 지운다

외장 디스크나 네트워크 공유에 둔 워크트리는 잠급니다. 폴더가 안 보일 때 깃이 관리 칸을 지우지 못하게 막습니다. 다 쓴 폴더는 리무브입니다. 폴더만 휴지통에 넣었으면 프룬입니다.


리무브는 깨끗한 워크트리만 받습니다. 추적 파일 변경이나 추적 안 된 파일이 있으면 --force입니다. 잠긴 워크트리를 지우려면 --force를 두 번 줍니다. 메인 워크트리는 리무브로 지울 수 없습니다. 프룬의 -n은 지울 목록만 보여 줍니다. 오래된 것만 지우려면 --expire입니다. 자동 정리는 gc.worktreePruneExpire가 맡습니다.


잠그고, 지우고, 죽은 칸만 프룬한다
# 외장 디스크. 이유 문자열은 잠금 파일에 남는다 git worktree lock --reason 'SSD not always mounted' ../tech-usb git worktree unlock ../tech-usb # 핫픽스가 머지된 뒤 cd ~/work/tech git worktree remove ../tech-hotfix-login # 폴더만 지운 뒤 관리 칸을 청소 git worktree prune -n -v git worktree prune --expire 2.weeks.ago

매주 한 번 목록을 보고 프룬하는 습관이 디스크보다 머리를 아낍니다. 의존성 봇이 연 피알은 디펜더봇 체크에 두고, 여기는 로컬 폴더만 비웁니다.


외장 디스크와 노트북이 케이블로 연결된 작업 공간
항상 안 붙는 디스크의 워크트리는 잠근다. 다 쓰면 리무브, 폴더만 지웠으면 프룬

커서 창과 깃 명령을 한 칸에 두지 않는다

커서 3 에이전트 창도 워크트리라는 단어를 씁니다. 그건 아이디이 창이 에이전트마다 폴더를 나누는 기능입니다. 터미널의 git worktree와 설정 칸이 다릅니다.


에이전트가 만든 폴더를 깃 리무브로 지우려다 창이 빈 경로를 가리키는 경우가 있습니다. 반대로 터미널에서 깐 워크트리를 커서 창이 모릅니다. 아이디이를 쓰기 전에 git worktree list로 실제 경로를 봅니다. 액션에서 체크아웃 한 줄만 쓰는 파이프라인은 재사용 워크플로액션 오아이디씨에 있습니다. 러너는 보통 워크트리 하나가 맞습니다.


핫픽스 한 줄을 스크립트로 고정한다
#!/bin/sh # usage: ./scripts/wt-hotfix.sh login set -eu name="$1" root="$(git rev-parse --show-toplevel)" parent="$(dirname "$root")" dest="$parent/$(basename "$root")-hotfix-$name" git fetch origin git worktree add -b "hotfix-$name" "$dest" origin/main cd "$dest" if [ -f package-lock.json ]; then npm ci elif [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile fi if [ -f "$root/.env.local" ]; then cp "$root/.env.local" .env.local fi echo "worktree: $dest" git worktree list

상대 경로를 켜는 자리 | 저장소와 워크트리를 통째로 옮길 일이 많으면 worktree.useRelativePaths=true입니다. 이 값은 extensions.relativeWorktrees를 같이 켭니다. 옛 깃은 그 확장이 있는 저장소를 거절할 수 있습니다. 팀 최저 깃 버전을 먼저 맞춥니다. 정본은 깃 설정 문서입니다.


참고 자료


서브모듈이 있는 슈퍼프로젝트의 다중 체크아웃은 문서가 아직 실험으로 남겨 두었습니다. 권하지 않습니다. 위 표와 명령은 2026년 8월 공개 문서 기준이며, 최종 확인은 팀 깃 버전의 git help worktree입니다.


자주 묻는 질문

메인 폴더에서 브랜치를 바꿔도 핫픽스 폴더는 유지되나?

유지됩니다. 헤드는 폴더마다 따로입니다. 메인에서 git switch를 해도 연결 워크트리의 브랜치는 그대로입니다. 다만 그 브랜치 이름 자체를 지우거나 강제 리셋하면 공유 참조가 움직입니다. 핫픽스 폴더에서 git status를 한 번 더 봅니다.


워크트리 폴더를 통째로 압축해 동료에게 줘도 되나?

안 됩니다. 맨 위 .git이 당신 머신 경로를 가리킵니다. 동료 머신에서는 객체를 못 찾습니다. 피알이나 번들을 보냅니다. 경로를 옮겨야 하면 받는 쪽에서 클론한 뒤 같은 브랜치로 워크트리를 다시 깝니다.


노드 모듈을 심볼릭 링크로 공유하면 안 되나?

핫픽스와 메인의 락파일이 같으면 잠깐은 됩니다. 한쪽에서 패키지를 올리면 다른 쪽이 깨집니다. 설치 시간은 워크트리마다 한 번입니다. 공유 링크보다 npm ci가 싸게 끝나는 경우가 많습니다.


윈도우에서 대소문자만 다른 경로가 충돌하나?

충돌할 수 있습니다. 관리 칸 이름은 경로 끝에서 따고, 겹치면 숫자를 붙입니다. 대소문자를 안 가리는 디스크에서는 폴더 이름을 아예 다르게 씁니다. 목록에 이상한 숫자가 붙으면 그 자리입니다.


깃허브 액션 러너에도 워크트리를 깔아야 하나?

보통은 아닙니다. 잡 하나가 체크아웃 한 줄이면 워크트리 하나가 맞습니다. 한 잡에서 두 브랜치를 동시에 빌드할 때만 검토합니다. 재사용 워크플로와 오아이디씨는 이미 있는 글에 있습니다.


커서가 만든 워크트리를 깃 리무브로 지워도 되나?

아이디이 창이 그 경로를 아직 잡고 있으면 창이 비거나 잠깁니다. 창을 먼저 닫고, git worktree list로 실제 경로를 확인한 뒤에 리무브합니다. 폴더만 지웠으면 프룬입니다. 두 제품의 워크트리라는 단어는 같은 명령이 아닙니다.


깃 워크트리스태시체크아웃핫픽스깃허브개발자Next.js백엔드데브옵스커서도커API

함께 보면 좋은 문제 해결

EXPLORE / 개발자 작업환경

이어서 읽어보기

전체 토픽 둘러보기