내 컴퓨터에서는 배송비 3,000원이 잘 나오는데, 저장소를 새로 받으면 파일이 없다고 멈춥니다. 코드를 더 고치기 전에 확인할 것이 있어요. 실행에 필요한 파일이 커밋에도 들어 있는지입니다.
git status가 깨끗해도 필요한 파일이 .gitignore에 가려져 있을 수 있습니다. 로컬 실행, Git 추적, 커밋 포함, 새 복제본 실행을 차례로 확인해 봅니다.AI에게 기능을 맡길 때도 이 구분이 필요합니다. 에이전트가 실행한 폴더에는 생성한 파일이 남아 있으니까요. 그 자리에서 정상 동작했다는 결과만으로, 커밋을 받은 사람도 같은 상태에서 시작한다고 볼 수는 없습니다.
2026-09-22 작성. 아래는 파일 누락을 의도적으로 만든 독립 실습입니다. 특정 AI 도구의 실제 출력이나 운영 서비스의 장애 후기가 아닙니다. macOS, Git 2.50.1(Apple Git-155), Python 3.12.4에서 실행했습니다.
코드 옆에 있던 JSON 한 개가 빠졌습니다
예제는 app.py에서 assets/shipping.json을 읽어 배송비를 계산합니다. JSON에는 무료배송 기준 50,000과 기본 배송비 3,000이 들어 있어요. 외부 패키지나 API는 사용하지 않습니다.
working/
├── .gitignore # assets/*.json
├── app.py # JSON을 읽어 계산
└── assets/
└── shipping.json # 로컬에는 있지만 Git에서 제외됨
문제는 .gitignore의 assets/*.json입니다. 이 규칙 때문에 새 JSON 파일은 추적되지 않은 채 남았고, 코드와 .gitignore만 커밋됐습니다. 그런데 같은 폴더에서는 JSON을 읽을 수 있으니 실행은 성공합니다.
shipping(10000)=3000
이때 git status --short도 아무것도 출력하지 않았습니다. 빠진 파일이 없다는 뜻이 아니라, 이 경우에는 제외 규칙에 걸린 파일을 기본 상태 출력에서 보여주지 않은 것입니다.

따라 해 볼 예제 만들기 — 새 임시 폴더에서 실행
아래 블록 전체를 macOS나 Linux 셸에 붙여 넣습니다. Git과 Python 3가 필요하며, 현재 프로젝트 대신 별도의 임시 폴더를 만듭니다. Windows에서는 WSL 등 호환 셸을 사용하세요.
# macOS / Linux 셸용. 실습 전용 임시 폴더를 만듭니다.
demo_root=$(mktemp -d "${TMPDIR:-/tmp}/devpilot-file-demo.XXXXXX")
mkdir "$demo_root/working"
cd "$demo_root/working" || exit 1
git init -q
git config user.name "DevPilot Example"
git config user.email "example@example.invalid"
mkdir assets
cat > app.py <<'PYAPP'
import json
from pathlib import Path
rules = json.loads(Path("assets/shipping.json").read_text(encoding="utf-8"))
amount = 10000
fee = 0 if amount >= rules["free_over"] else rules["standard_fee"]
print(f"shipping({amount})={fee}")
PYAPP
cat > assets/shipping.json <<'JSON'
{"free_over": 50000, "standard_fee": 3000}
JSON
cat > .gitignore <<'IGNORE'
assets/*.json
IGNORE
git add -- app.py .gitignore
git -c core.hooksPath=/dev/null -c commit.gpgsign=false commit -qm "add shipping example"
python3 app.py
같은 저장소를 새 폴더에 받으니 실패했습니다
위 예제의 working 폴더에서 다음을 실행합니다. 아직 없는 fresh-before 폴더에 로컬 저장소를 복제하므로, 원격 서비스에 접속하지 않습니다.
git clone --quiet --no-local . ../fresh-before
(cd ../fresh-before && python3 app.py)
새 폴더에는 커밋된 파일이 들어오지만, 로컬에만 남아 있던 JSON은 따라오지 않습니다. 실행은 종료 코드 1로 실패했고, 오류 출력의 마지막 줄은 다음과 같았습니다.
FileNotFoundError: [Errno 2] No such file or directory: 'assets/shipping.json'
이 실험에서는 Python 버전도 컴퓨터도 바꾸지 않았습니다. 작업 폴더에 남아 있던 파일을 기대할 수 없게 만든 것만으로 문제가 드러났어요. 로컬 성공 한 번으로는 확인되지 않았던 조건입니다.
파일 이름을 알면, 제외한 규칙까지 찾을 수 있습니다
먼저 원래 working 폴더에서 추적 여부와 제외 규칙을 확인합니다. 위 명령의 괄호 안에서만 폴더를 이동했으므로, 실행이 끝난 셸은 그대로 working에 있습니다.
git ls-files -- assets/shipping.json
git check-ignore -v -- assets/shipping.json
첫 번째 명령은 아무것도 출력하지 않았습니다. 두 번째에서는 이 파일을 제외한 규칙이 나왔습니다.
.gitignore:1:assets/*.json assets/shipping.json
.gitignore 1행의 assets/*.json이 원인이라는 뜻입니다. git check-ignore 공식 문서에 나온 -v 옵션은 이렇게 패턴이 정의된 파일과 줄까지 보여줍니다.
상태 화면에서도 제외된 파일을 확인하고 싶다면 범위를 지정해 다음처럼 볼 수 있습니다.
git status --short --untracked-files=all --ignored -- assets/shipping.json!! assets/shipping.json
!!는 제외된 파일이라는 표시입니다. 참고로 .gitignore 규칙은 이미 추적 중인 파일을 자동으로 추적 해제하지 않습니다. 이 예제처럼 아직 추적하지 않은 새 파일이 가려지는 경우와 구분해야 합니다.
일단 강제로 추가하기 전에, 어떤 파일인지 봅니다
이번 JSON은 예제의 배송비 규칙이고 비밀 값이 없습니다. 함께 배포해야 하는 파일이므로 제외 규칙을 좁히고 커밋하는 것이 맞습니다. 파일이 없다는 오류라고 해서 언제나 저장소에 넣는 것이 답은 아니에요.
- 함께 배포할 데이터·템플릿: 필요한 파일을 추적하고 커밋합니다.
- 빌드 중 생성하는 파일: 생성 명령과 입력 자료를 준비하고, 실행 순서에 그 단계를 넣습니다.
- 비밀번호·API 키가 담긴 설정: 실제 값 대신 필요한 항목과 주입 방법을 안내합니다.
파일의 역할을 보지 않고 git add -f로 밀어 넣으면, 제외한 이유도 함께 무시하게 됩니다. 이 예제에서는 “모든 JSON 제외”를 “개인별 local JSON 제외”로 바꾸겠습니다. 아래 덮어쓰기는 한 줄짜리 실습 파일에서만 사용하세요.
# 이 실습의 .gitignore는 한 줄짜리입니다.
# 실제 프로젝트에서는 다른 규칙을 보존하고 해당 줄만 수정하세요.
cat > .gitignore <<'IGNORE'
assets/*.local.json
IGNORE
git add -- .gitignore assets/shipping.json
git diff --cached
실제 프로젝트라면 .gitignore의 다른 규칙은 유지하고 필요한 부분만 편집합니다. 커밋 전에는 git diff --cached 전체를 읽어, 기존에 스테이징돼 있던 다른 변경까지 들어가는지도 확인하세요.
git add를 했다고 커밋에도 들어간 것은 아닙니다
여기서 한 번 멈춰볼게요. 이제 git ls-files에 JSON 이름이 나오는데, 새 복제본에서도 보일까요?
git ls-files -- assets/shipping.json
git ls-tree -r --name-only HEAD -- assets/shipping.json
이 시점에는 첫 번째만 assets/shipping.json을 출력하고, 두 번째는 비어 있습니다. ls-files는 기본적으로 인덱스에 있는 파일을 보여줍니다. 반면 ls-tree HEAD는 현재 커밋에 무엇이 들어 있는지 확인하는 데 쓰입니다.
실제로 커밋 전 상태에서 별도 복제본을 한 번 더 만들었지만, JSON은 여전히 없었습니다. 추적할 준비를 한 것과 전달할 버전에 담은 것은 다릅니다.

이제 예제의 변경을 커밋합니다. 아래 두 번째 명령에서 파일 이름이 나오면 현재 커밋에 포함된 것입니다.
git commit -m "track shipping data and narrow ignore rule"
git ls-tree -r --name-only HEAD -- assets/shipping.jsonassets/shipping.json
새 경로 fresh-after에 다시 복제해 실행했습니다.
git clone --quiet --no-local . ../fresh-after
(cd ../fresh-after && python3 app.py)shipping(10000)=3000
수정 전에는 새 복제본이 종료 코드 1로 실패했고, 수정 후에는 0으로 끝났습니다. 단순히 로컬 파일을 찾게 만든 것이 아니라, 그 파일이 포함된 커밋에서도 실행되는지 확인한 결과입니다.
AI의 완료 보고에 새 파일 목록을 넣습니다
“실행해 보니 됩니다”라는 보고를 받았다면, 어디에 있던 무엇으로 실행했는지를 이어서 물어볼 수 있습니다. 방향 주는 지시법에서 다룬 완료 조건에, 이번에는 전달할 파일의 범위를 더하는 겁니다.
이번 작업에서 새로 만든 파일과 실행 시 필요한 파일을 정리해줘.
각 파일이 Git에서 추적되는지, 제외 규칙에 가려졌는지 확인해줘.
커밋 전이면 아직 커밋에 포함되지 않았다고 구분해서 알려줘.
생성 파일이나 환경 설정이 필요하면 준비 명령과 실행 순서를 적어줘.
커밋은 내가 확인한 뒤 진행할게.
커밋 후 별도 폴더에서 재현할 명령과, 아직 검증하지 못한 조건도 남겨줘.
물론 새 폴더에서 성공해도 다른 운영체제, 런타임 버전, 원격 배포까지 확인한 것은 아닙니다. 이 글에서는 같은 컴퓨터에서 일반 파일이 커밋에 빠진 문제만 검증했습니다. 서브모듈이나 Git LFS, 컨테이너의 빌드 제외 규칙은 별도 확인이 필요합니다.
저라면 기능을 넘기기 직전에 새 폴더에서 한 번 실행해 보겠습니다. 내 컴퓨터에만 남은 파일이 다음 사람에게도 있을 거라는 가정을, 그때 끊을 수 있으니까요.
자주 묻는 질문
git status가 깨끗하면 필요한 파일이 모두 커밋된 건가요?
아닙니다. 제외된 미추적 파일은 기본 상태 출력에 나타나지 않을 수 있습니다. 필요한 파일의 추적 여부와 커밋 포함 여부를 각각 확인해야 합니다.
git ls-files에 나오면 바로 새 복제본에도 들어가나요?
아닙니다. 새로 git add한 파일도 목록에 나옵니다. 커밋 전이라면 그 파일은 아직 HEAD에 없으므로, HEAD 기준 복제본에 포함되지 않습니다.
실행에 필요한 파일은 무조건 Git에 추가해야 하나요?
아닙니다. 함께 배포할 파일, 생성해야 하는 파일, 비밀 값을 넣는 설정을 구분해야 합니다. 파일의 역할에 맞춰 커밋하거나 생성·설정 절차를 마련합니다.
새 폴더에서 실행하면 배포도 검증한 건가요?
아닙니다. 이 실습은 같은 컴퓨터에서 커밋된 일반 파일만으로 실행되는지 확인했습니다. 운영체제, 런타임, 네트워크, 원격 배포 환경의 차이는 별도로 검증해야 합니다.
'AI 코딩 일반' 카테고리의 다른 글
| AI 수정이 꼬였을 때, 내 코드까지 날리지 않고 되돌리는 법 (0) | 2026.09.22 |
|---|---|
| AI가 엉뚱한 곳을 고친다면? 방향 주는 지시법 (삽질 부검 2편) (0) | 2026.09.19 |
| AI 에이전트한테 시켰다가 날린 시간들: 삽질 부검 3건 (실측 후기) (0) | 2026.09.18 |
| 커서 vs 클로드코드 vs 코덱스: 작업별로 뭘 써야 하나 총정리 (디버깅·만들기·리팩토링·테스트·리뷰, 2026) (0) | 2026.09.16 |
| 같은 PR, 커서 Bugbot·클로드코드·코덱스에 리뷰시켰다: 뭘 잡고 뭘 놓치나 (2026) (0) | 2026.09.15 |