Git 임시 저장소 및 Bundle을 활용한 커밋 보관·복원
- 첫 작업 지시문
원본 저장소의
.git에는 쓰기를 시도하지 마. 처음부터 쓰기 가능한 별도 로컬 클론을 만들고, 구현·테스트·단계별 커밋을 모두 그 클론에서 진행해. 완료한 커밋 전체를 원본 작업공간의 Git bundle 파일로 저장하고 검증해. bundle 경로, 기준 커밋, 단계별 커밋 해시를 보고해. 원본 저장소에는git add,git commit,fetch,cherry-pick을 실행하지 마.
- 나중에 반영할 때의 지시문
저장해 둔 Git bundle을 원본 저장소에서
git fetch하고, 보고된 단계별 커밋을 순서대로git cherry-pick해. 충돌이 나면 해결하고 각 단계의 결과를 검증해. 반영된 커밋 해시와 최종 작업트리 상태를 보고해.
1. 개요
원본 Git 저장소의 .git 디렉터리가 읽기 전용이거나 권한 문제로 커밋할 수 없는 상황에서, 별도의 임시 Git 저장소를 생성하여 변경 이력을 보관하고 이후 원본 저장소에 반영하는 방법이다.
주요 활용 사례는 Docker 컨테이너 또는 AI 코딩 에이전트(Codex 등)가 원본 작업트리의 파일은 수정할 수 있지만 .git 디렉터리에는 쓰기 권한이 없는 환경이다.
핵심적으로 사용하는 Git 기능은 다음과 같다.
git clone --local: 원본 저장소의 로컬 복제본 생성git commit: 임시 저장소에서 변경 이력 기록git bundle: 커밋 이력을 단일 파일로 보관git fetch: Bundle에 포함된 커밋을 원본 저장소로 가져오기git cherry-pick: 임시 저장소의 특정 커밋을 원본 브랜치에 적용
2. 전체 처리 구조
[원본 Git 저장소]
/workspace/project/
├── .git/ # 읽기 전용
├── src/
└── tests/
│
│ git clone --local --no-hardlinks
▼
[임시 Git 저장소]
/tmp/project-temp/
├── .git/ # 쓰기 가능
├── src/
└── tests/
│
│ 단계별 수정 및 커밋
▼
[임시 커밋 이력]
Commit A
Commit B
Commit C
│
│ git bundle create
▼
[Bundle 파일]
/tmp/project-history.bundle
│
│ 원본 .git 쓰기 권한 복구
▼
[원본 Git 저장소]
│
├── 방식 A: 원본 작업트리에서 재커밋
│
└── 방식 B: Bundle fetch + cherry-pick주의: /tmp는 영구 저장 경로가 아니다. 컨테이너 재생성이나 임시 파일 정리 시 데이터가 삭제될 수 있으므로 장기 보관이 필요하다면 영속 볼륨을 사용해야 한다.
3. Git 기능별 설명
3.1. git clone —local —no-hardlinks
git clone --local --no-hardlinks \
/workspace/project \
/tmp/project-temp원본 Git 저장소를 로컬 경로에 복제한다.
| 옵션 | 설명 |
|---|---|
--local | 로컬 파일시스템에서 저장소 복제 |
--no-hardlinks | Git 객체를 하드링크로 공유하지 않고 복사 |
/workspace/project | 원본 저장소 |
/tmp/project-temp | 임시 저장소 |
--no-hardlinks는 두 저장소의 Git 객체 저장 공간을 분리하기 위해 사용한다.
단, 일반적인 git clone은 원본 작업트리의 미커밋 변경사항을 복사하지 않는다.
따라서 미커밋 변경사항을 임시 저장소에서 커밋하려면 해당 파일을 별도로 복사하거나 패치를 적용해야 한다.
3.2. git commit
임시 저장소에서 단계별 변경사항을 커밋한다.
cd /tmp/project-temp
git add src/module_a.py
git commit -m "feat: implement module A"
git add tests/test_module_a.py
git commit -m "test: add module A tests"이 과정에서 원본 저장소의 .git에는 변경이 발생하지 않는다.
3.3. git bundle
Git Bundle은 Git 저장소의 객체와 참조 정보를 하나의 파일로 패키징하는 기능이다.
git bundle create \
/tmp/project-history.bundle \
HEAD생성 결과:
/tmp/project-history.bundleBundle에는 지정한 참조에서 도달 가능한 커밋과 필요한 Git 객체가 저장된다.
일반적인 Git 저장소와 달리 디렉터리가 아닌 단일 파일로 Git 이력을 보관하거나 전달할 수 있다.
Bundle 유효성 검사:
git bundle verify /tmp/project-history.bundleBundle에 포함된 참조 확인:
git bundle list-heads /tmp/project-history.bundle4. 원본 저장소에 반영하는 두 가지 방식
방식 A. 원본 작업트리에서 재커밋
임시 저장소의 커밋 이력을 참고하되, 실제 커밋은 원본 작업트리에서 다시 생성하는 방식이다.
cd /workspace/project
git add src/module_a.py
git commit -m "feat: implement module A"
git add tests/test_module_a.py
git commit -m "test: add module A tests"특징:
- 임시 커밋과 원본 커밋의 SHA가 달라진다.
- 원본 저장소에 새로운 커밋 객체를 생성한다.
- 임시 저장소의 변경사항이 자동으로 반영되는 것은 아니다.
- 각 단계에 해당하는 파일 변경 상태를 정확히 재현해야 한다.
특히 여러 단계에서 동일한 파일을 수정했다면 최종 작업트리만으로는 과거 단계의 변경 상태를 정확히 재현하기 어렵다.
따라서 재커밋 방식은 단계별 패치나 변경 내역을 별도로 관리해야 한다.
방식 B. Bundle fetch + cherry-pick
임시 저장소에서 생성한 커밋을 원본 저장소로 가져와 적용하는 방식이다.
먼저 Bundle을 가져온다.
cd /workspace/project
git fetch /tmp/project-history.bundle HEAD이후 가져온 커밋을 확인한다.
git log --oneline FETCH_HEAD필요한 커밋을 순서대로 적용한다.
git cherry-pick <commit-A>
git cherry-pick <commit-B>
git cherry-pick <commit-C>특징:
- 임시 저장소의 커밋 단위를 유지하며 변경사항을 적용할 수 있다.
- 원본 작업트리에서 단계별 변경사항을 수동 재구성할 필요가 없다.
- 커밋 간 의존관계를 유지하려면 올바른 순서로 적용해야 한다.
- 기존 작업트리에 미커밋 변경사항이 있다면 먼저 정리해야 한다.
- 원본 브랜치 상태에 따라 충돌이 발생할 수 있다.
주의: git cherry-pick은 기존 커밋의 변경사항을 현재 브랜치에 적용해 새 커밋을 생성한다. 따라서 일반적으로 원본과 cherry-pick된 커밋의 SHA는 다르다.
기존 SHA 자체를 보존하려면 cherry-pick 대신 원본 커밋 객체와 브랜치 이력을 직접 연결하는 방식이 필요하다.
5. 두 방식 비교
| 비교 항목 | 방식 A: 재커밋 | 방식 B: Bundle + cherry-pick |
|---|---|---|
| 임시 커밋 활용 | 참고 자료 | 실제 변경 이력 적용 |
| 변경사항 반영 | 원본에서 다시 커밋 | 기존 커밋의 변경사항 적용 |
| 단계별 변경 재현 | 별도 관리 필요 | 커밋 단위로 적용 |
| 커밋 SHA | 새로 생성 | 일반적으로 새로 생성 |
| 커밋 메시지 | 직접 지정 | 기본적으로 원본 메시지 유지 |
| 충돌 가능성 | 파일 상태에 따라 발생 | Git 충돌 감지 및 해결 |
| 자동화 적합성 | 상대적으로 낮음 | 상대적으로 높음 |
| 권장 상황 | 원본 변경사항을 재구성해야 할 때 | 임시 커밋 이력을 그대로 활용하고 싶을 때 |
일반적인 권장 방식은 B(Bundle + cherry-pick) 이다.
임시 저장소에서 작업 단위별 커밋을 생성했다면, 이를 원본에서 다시 수동으로 커밋할 이유가 적기 때문이다.
단, cherry-pick 대상 변경사항이 이미 원본 작업트리에 적용되어 있다면 중복 적용이나 충돌이 발생할 수 있으므로 먼저 작업트리 상태를 확인해야 한다.
6. Codex에 전달할 명시적 지시문
6.1. 방식 A — 임시 저장소에서 보관 후 재커밋
원본 Git 저장소의 .git 디렉터리에 쓰기 권한이 없는 경우,
원본 저장소에 직접 커밋하려고 반복 시도하지 마.
대신 다음 절차를 수행해.
1. 쓰기 가능한 경로에 임시 로컬 Git 저장소를 생성해.
2. 원본 작업트리의 미커밋 변경사항도 필요한 경우 임시 저장소에 반영해.
3. 작업을 논리적인 단위로 구분하여 임시 저장소에 단계별 커밋을 생성해.
4. git bundle을 이용해 커밋 이력을 단일 파일로 보관해.
5. 원본 Git 저장소의 쓰기 권한이 복구되면,
원본 작업트리에서 각 단계의 변경사항을 재현하여 각각 커밋해.
6. 임시 저장소와 원본 저장소의 커밋 SHA가 달라진다는 점을 보고해.
7. 원본 반영이 완료되기 전까지 임시 저장소와 Bundle을 삭제하지 마.6.2. 방식 B — 임시 저장소에서 보관 후 cherry-pick (권장)
원본 Git 저장소의 .git 디렉터리에 쓰기 권한이 없는 경우,
원본 저장소에 직접 커밋하려고 반복 시도하지 마.
대신 다음 절차를 수행해.
1. 쓰기 가능한 경로에 임시 로컬 Git 저장소를 생성해.
2. 원본 작업트리의 미커밋 변경사항도 필요한 경우 임시 저장소에 반영해.
3. 작업을 논리적인 단위로 구분하여 임시 저장소에 단계별 커밋을 생성해.
4. git bundle을 이용해 커밋 이력을 단일 파일로 보관해.
5. 원본 Git 저장소의 쓰기 권한이 복구되면,
Bundle을 git fetch로 가져와.
6. 원본 작업트리의 변경사항과 중복되지 않는지 확인한 후,
필요한 커밋들을 순서대로 git cherry-pick으로 적용해.
7. 적용 결과와 원본 저장소에 생성된 커밋 SHA를 보고해.
8. 모든 커밋의 정상 반영을 확인하기 전까지 임시 저장소와 Bundle을 삭제하지 마.6.3. 단축 지시문
반복적인 작업에서는 아래 지시문만으로도 충분하다.
원본 .git에 쓰기 권한이 없으면 임시 로컬 클론에서
단계별 커밋을 생성하고 git bundle로 보관해.
원본 Git 쓰기가 가능해지면 작업트리와의 변경 중복을 확인한 후
bundle을 fetch하고 필요한 커밋을 순서대로 cherry-pick해.
원본 반영이 검증되기 전까지 임시 이력을 보존하고,
최종 커밋 SHA와 적용 결과를 보고해.7. 운영 시 주의사항
7.1. 원본 .git 읽기 권한은 필요하다
git clone --local은 원본 저장소의 Git 객체를 읽어야 한다.
원본 .git에 읽기 권한도 없다면 해당 방식으로 복제할 수 없다.
7.2. Bundle 생성은 원본 권한을 복구하지 않는다
Bundle은 Git 이력을 별도 파일로 보관할 뿐이다.
원본 저장소에 커밋을 반영하려면 최종적으로 .git에 쓰기 권한이 필요하다.
7.3. 임시 저장소의 기준 커밋이 중요하다
임시 저장소를 생성한 이후 원본 브랜치가 변경되면 cherry-pick 과정에서 충돌이 발생할 수 있다.
따라서 다음 정보를 함께 기록하는 것이 좋다.
git rev-parse HEAD
git branch --show-current
git status --short7.4. Git Bundle은 완전한 백업 시스템이 아니다
Git Bundle에는 Git 객체와 참조 정보가 들어가지만 다음 항목이 자동으로 보존되는 것은 아니다.
- 미커밋 작업트리 변경사항
.gitignore에 의해 제외된 파일- Git 설정 전체
- Git Hooks
- 외부 Git LFS 객체
따라서 필요한 파일 변경사항은 반드시 임시 저장소에서 커밋해야 한다.
8. 결론
이번 사례에서 사용한 핵심 Git 기능은 **git clone --local과 git bundle**이다.
실제로 수행된 복원 방식은 다음과 같다.
임시 로컬 클론 생성
↓
임시 저장소에 커밋 3개 생성
↓
git bundle로 커밋 이력 보관
↓
원본 .git 쓰기 권한 복구
↓
원본 작업트리에서 단계별 재커밋
↓
원본에 새로운 커밋 3개 생성반면, 향후 권장하는 방식은 다음과 같다.
임시 로컬 클론 생성
↓
임시 저장소에 단계별 커밋 생성
↓
git bundle로 커밋 이력 보관
↓
원본 .git 쓰기 권한 복구
↓
git fetch로 Bundle 가져오기
↓
git cherry-pick으로 커밋 적용
↓
원본 커밋 검증핵심 구분
git bundle: 커밋 이력을 파일로 보관·전달git fetch: Bundle에 포함된 Git 객체와 참조를 가져오기git cherry-pick: 기존 커밋의 변경사항을 현재 브랜치에 적용git commit: 현재 인덱스 상태를 새로운 커밋으로 기록
이 방식을 사용하면 원본 Git 저장소가 일시적으로 읽기 전용인 환경에서도 AI 코딩 에이전트의 단계별 작업 이력을 별도로 유지할 수 있다.