git worktree 삭제 후 .gitignore된 야간 배치 데이터가 사라진 경험: 삭제 전 확인 및 리포지토리 외 저장 설계
요약
작성자는 git worktree 내부에 .gitignore 처리된 배치 데이터를 저장했다가, worktree 삭제 과정에서 데이터가 함께 사라진 경험을 공유합니다. 이 글은 Git의 '무시(ignored)' 기능이 삭제로부터 보호하지 못한다는 점을 경고하며, 안전한 데이터 관리를 위한 방법을 제시합니다.
핵심 포인트
- `.gitignore`는 관리 대상 제외일 뿐, 삭제로부터 보호하지 않습니다.
- 작업 데이터를 리포지토리 외부의 고정 경로에 저장하는 것이 가장 안전합니다.
- 리포지토리에 두려면 symlink를 사용해 실제 데이터는 외부에 분리하세요.
- 삭제 전 `git status --ignored`나 `git ls-files --others --ignored --exclude-standard`로 확인해야 합니다.
- Git: 2.43.0
- OS: Ubuntu 22.04 LTS / macOS 14.5
- GUI: Fork 2.x, SourceTree 4.x, VS Code 1.90
- 배치: Python 3.11 + cron / systemd timer
- 저장 형식: Parquet / CSV / SQLite
- 데이터량: 하룻밤당 200MB, 여러 밤 동안 1GB 초과
- 원래 저장 위치:
<worktree>/data/
(.gitignore
처리됨) - 이전 방식:
/var/lib/myapp/data
또는 $MYAPP_DATA_DIR
.gitignore는 'Git 관리 대상에서 제외'하는 것일 뿐, '삭제로부터 보호'하는 것은 아닙니다. - worktree 삭제는 디렉터리 전체를 지웁니다. ignored 파일은 경고 메시지에 나타나지 않을 수 있습니다.
- 삭제하기 전에
git status --ignored와git log origin/main..HEAD를 확인합니다. - 데이터는 리포지토리 외부의 고정 경로에 두고, 환경 변수로 덮어쓸 수 있게 합니다. - 리포지토리 내부에 두고 싶다면 symlink를 사용하여 실제 데이터를 외부에 둡니다.
야간 배치로 수집한 데이터를 git worktree 내부의 data/에 두었습니다. data/는 .gitignore 처리되었습니다. GUI에서 작업 중인 worktree를 삭제하는 순간, 데이터까지 함께 사라졌습니다.
맹점은 'Git 관리 대상 외 = 삭제 대상'이라는 점입니다. 삭제 확인 시에는 '커밋되지 않은 변경 사항 없음'만 표시될 뿐, ignored 파일이 사라진다는 내용은 알려주지 않습니다. 여러 밤 동안 수집한 데이터가 한 번에 날아갔습니다.
- worktree를 생성합니다.
git worktree add ../worktrees/collector -b feature/collector
cd ../worktrees/collector
mkdir data
...
- 야간 배치가
data/에 출력합니다.
python collect.py --out data/$(date +%F).parquet
- 상태를 확인합니다.
git status만으로는 깨끗해 보입니다.
git status
# On branch feature/collector
# nothing to commit, working tree clean
...
- GUI에서 worktree를 삭제합니다.
data/도 함께 사라집니다. 다이얼로그에는 '커밋되지 않은 변경 사항 없음'만 표시됩니다.
git status는 ignored 파일을 표시하지 않습니다. git clean -ndx조차도 ignored 파일을 삭제 후보에 포함시키지 않습니다. worktree는 별도의 디렉터리이기 때문에, 삭제는 해당 디렉터리의 rm -rf와 유사한 동작을 합니다.
# ignored를 포함하는 모든 파일
git status --ignored --short
# ignored 파일만 목록화
...
특히 git ls-files --others --ignored --exclude-standard는 .gitignore로 숨겨진 데이터를 명시할 수 있습니다. data/가 보인다면 삭제 전에 백업해야 합니다.
#!/usr/bin/env bash
set -euo pipefail
MAIN_REPO="/path/to/main-repo"
...
export MYAPP_DATA_DIR="${MYAPP_DATA_DIR:-/var/lib/myapp/data}"
mkdir -p "$MYAPP_DATA_DIR/collector"
python collect.py --out "$MYAPP_DATA_DIR/collector/$(date +%F).parquet"
cron을 사용한다면 다음과 같이 합니다.
MYAPP_DATA_DIR=/var/lib/myapp/data
0 2 * * * MYAPP_DATA_DIR=$MYAPP_DATA_DIR /opt/myapp/collect.sh
systemd를 사용한다면 다음과 같이 합니다.
[Service]
Environment=MYAPP_DATA_DIR=/var/lib/myapp/data
ExecStart=/opt/myapp/collect.sh
이 설계라면 worktree를 삭제해도 데이터는 남습니다.
실체를 외부에 두고, worktree 내부에는 symlink로 만듭니다.
mkdir -p /var/lib/myapp/data
ln -s /var/lib/myapp/data ./data
echo '/data' >> .gitignore
worktree 삭제로 사라지는 것은 symlink뿐입니다. 다만 git clean -fdx
이나 백업 툴이 symlink의 원본(실체)을 추적하는 경우가 있으니 주의해야 합니다.
| 방법 | tracked 변경 | untracked | ignored | 위험도 |
|---|---|---|---|---|
git status만 보고 GUI 삭제 | 경고 | 경고 있음 | 경고 없음 가능 | 높 |
git worktree remove | 거부 | 거부 | 버전에 따라 다름 | 중 |
git worktree remove --force | 무시 | 무시 | 삭제 | 높 |
rm -rf <worktree> | 무시 | 무시 | 삭제 | 최고 |
| 리포지토리 외 저장 + 삭제 전 체크 | 영향 없음 | 영향 없음 | 영향 없음 | 낮 |
.gitignore에 넣었으니 안전하다는 것은 오류입니다. 관리 범위를 벗어난 파일은 삭제 대상입니다. -
git status가 깨끗하더라도 ignored(무시된 파일)가 존재할 수 있습니다. - GUI 확인 다이얼로그에서 ignored를 표시하지 않는 제품도 있습니다.
git clean -fdx는 ignored까지 삭제합니다.-n으로 반드시 사전 연습을 하세요. - worktree의 삭제는 main repo 측에서 실행해야 합니다. worktree 내부에서git worktree remove .은 할 수 없습니다. -origin/main..HEAD는 main에 병합되지 않은 것을 확인하는 것입니다. 원격 이름이upstream이라면 이를 읽어내야 합니다.
Q. .gitignore에 넣으면 삭제되지 않나요?
A. 그렇게 말할 수는 없습니다. Git 관리 범위를 벗어나기 때문에, worktree 삭제나 rm -rf로는 평범하게 사라집니다. Q. git status가 깨끗한데도요?
A. ignored는 기본적으로 숨겨져 있습니다. git status --ignored를 사용하세요. Q. 지운 데이터는 Git에서 복구할 수 있나요?
A. 할 수 없습니다. Git 관리 범위를 벗어났기 때문입니다. OS의 휴지통, Time Machine, 클라우드 백업, 디스크 복원 툴을 확인해야 합니다. 다만 확실성은 낮습니다.
Q. 데이터를 리포지토리 내에 두고 싶어요.
A. symlink나 bind mount로 실체를 외부에 두세요. CI에서는 artifact나 object storage로 옮기세요.
Q. 삭제 전 체크를 자동화하려면요?
A. 위와 같은 래퍼(wrapper)를 git wt-safe-remove로 alias화하여, GUI 삭제 대신 그것을 사용하세요. CI에서는 git status --ignored --porcelain을 검사합니다.
작업 디렉토리를 지우기 전에 Git이 무시하고 있는 파일의 내용을 확인해야 합니다. 삭제 전 체크 시에는 먼저 git status --ignored, 다음으로 git ls-files --others --ignored --exclude-standard, 마지막으로 origin/main..HEAD를 확인합니다. 데이터는 리포지토리 외의 고정 경로에 두고, 환경 변수로 덮어쓸 수 있게 합니다. 이렇게 하면 몇 밤치 가져온 데이터가 순식간에 날아가는 사고를 막을 수 있습니다.
BENTEN Web Works — 업무 자동화/시스템 개발 프리랜서 엔지니어입니다.
GAS / Python / RPA를 사용한 업무 자동화나, 웹 제작・시스템 개발 상담을 받고 있습니다.
“이런 것도 자동화할 수 있을까요?”라는 질문만으로도 편하게 문의주세요.
👉 업무 자동화 서비스 — 상세/문의는 여기
🐦 X (구 Twitter) — 일일 지식을 발신 중
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기