|
| 1 | +# init-workflow |
| 2 | + |
| 3 | +Git worktree를 자동으로 생성하는 커맨드입니다. |
| 4 | + |
| 5 | +브랜치명을 입력받아 자동으로: |
| 6 | +1. 브랜치명에서 `#` 문자 제거 (Git 브랜치명으로 사용) |
| 7 | +2. 브랜치가 없으면 생성 (현재 브랜치에서 분기) |
| 8 | +3. 브랜치명의 특수문자를 `_`로 변환하여 폴더명 생성 |
| 9 | +4. `{프로젝트명}-Worktree` 폴더에 worktree 생성 (예: `RomRom-FE-Worktree`) |
| 10 | +5. 설정 파일 자동 복사 (Firebase, iOS, Android 키 등) |
| 11 | +6. 이미 존재하면 경로만 출력 |
| 12 | + |
| 13 | +## 사용법 |
| 14 | + |
| 15 | +``` |
| 16 | +/init-workflow |
| 17 | +
|
| 18 | +20260120_#163_Github_Projects_에_대한_템플릿_개발_필요_및_관련_Sync_워크플로우_개발_필요 |
| 19 | +``` |
| 20 | + |
| 21 | +## 실행 로직 |
| 22 | + |
| 23 | +1. 사용자 입력에서 두 번째 줄의 브랜치명 추출 |
| 24 | +2. 브랜치명에서 `#` 문자 제거 |
| 25 | +3. 임시 Python 스크립트 파일 생성 (인코딩 문제 해결) |
| 26 | +4. Python 스크립트 실행 (worktree 생성 + 설정 파일 복사) |
| 27 | +5. 임시 파일 자동 삭제 |
| 28 | +6. 결과 출력 |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +사용자 입력에서 두 번째 줄을 추출하여 브랜치명으로 사용하세요. |
| 33 | + |
| 34 | +브랜치명이 제공되지 않은 경우: |
| 35 | +- 사용법을 안내하세요. |
| 36 | + |
| 37 | +브랜치명이 제공된 경우: |
| 38 | +1. 프로젝트 루트로 이동 |
| 39 | +2. Git 긴 경로 지원 활성화: `git config --global core.longpaths true` (최초 1회만 실행) |
| 40 | +3. 브랜치명에서 `#` 문자 제거 (예: `20260116_#432_...` → `20260116_432_...`) |
| 41 | +4. 임시 Python 스크립트 파일 생성: |
| 42 | + - 파일명: `init_worktree_temp_{timestamp}.py` |
| 43 | + - 브랜치명을 코드에 직접 포함 (인코딩 문제 해결) |
| 44 | + - worktree 생성 로직 포함 |
| 45 | +5. **Python 스크립트 실행** (Windows에서는 `-X utf8` 플래그 필수): |
| 46 | + ```bash |
| 47 | + python -X utf8 init_worktree_temp_{timestamp}.py |
| 48 | + ``` |
| 49 | +6. 임시 파일 삭제 |
| 50 | +7. 결과 출력 |
| 51 | +8. 에이전트가 `.gitignore` 분석 후 민감 파일 복사 |
| 52 | + |
| 53 | +**중요**: |
| 54 | +- **브랜치명 처리**: `#` 문자는 Git 브랜치명에서 제거됩니다 (문제 방지) |
| 55 | +- **인코딩 문제 해결**: Python 스크립트 파일에 브랜치명을 직접 포함시켜 Windows PowerShell 인코딩 문제 회피 |
| 56 | +- **Windows UTF-8 모드**: Python 실행 시 `-X utf8` 플래그 사용 필수 |
| 57 | +- **설정 파일 자동 복사**: worktree 생성 후 에이전트가 동적으로 파일 복사 |
| 58 | +- **플랫폼 독립성**: Windows/macOS/Linux 모두 동일한 방식으로 처리 |
| 59 | + |
| 60 | +**실행 예시**: |
| 61 | +```powershell |
| 62 | +# Windows PowerShell |
| 63 | +cd d:\0-suh\project\RomRom-FE |
| 64 | +git config --global core.longpaths true |
| 65 | +
|
| 66 | +# Python UTF-8 모드로 실행 (Windows 한글 인코딩 문제 해결) |
| 67 | +python -X utf8 init_worktree_temp.py |
| 68 | +
|
| 69 | +# 브랜치명: 20260116_#432_UX_개선_및_페이지_디자인_수정 |
| 70 | +# → Git 브랜치: 20260116_432_UX_개선_및_페이지_디자인_수정 |
| 71 | +# → 폴더명: 20260116_432_UX_개선_및_페이지_디자인_수정 |
| 72 | +``` |
| 73 | + |
| 74 | +**Python 스크립트 구조**: |
| 75 | +```python |
| 76 | +# -*- coding: utf-8 -*- |
| 77 | +import sys |
| 78 | +import os |
| 79 | +import shutil |
| 80 | +import glob |
| 81 | + |
| 82 | +# 프로젝트 루트로 이동 |
| 83 | +os.chdir('프로젝트_루트_경로') |
| 84 | + |
| 85 | +# 브랜치명 (# 제거됨) |
| 86 | +branch_name = '20260116_432_UX_개선_및_페이지_디자인_수정' |
| 87 | + |
| 88 | +# worktree_manager 실행 |
| 89 | +sys.path.insert(0, '.cursor/scripts') |
| 90 | +import worktree_manager |
| 91 | +os.environ['GIT_BRANCH_NAME'] = branch_name |
| 92 | +os.environ['PYTHONIOENCODING'] = 'utf-8' |
| 93 | +sys.argv = ['worktree_manager.py'] |
| 94 | +exit_code = worktree_manager.main() |
| 95 | + |
| 96 | +# worktree 경로를 환경변수로 설정 (에이전트가 파일 복사에 사용) |
| 97 | +if exit_code == 0: |
| 98 | + import subprocess |
| 99 | + result = subprocess.run(['git', 'worktree', 'list', '--porcelain'], |
| 100 | + capture_output=True, text=True, encoding='utf-8') |
| 101 | + lines = result.stdout.split('\n') |
| 102 | + worktree_path = None |
| 103 | + for i, line in enumerate(lines): |
| 104 | + if line.startswith(f'branch refs/heads/{branch_name}'): |
| 105 | + worktree_path = lines[i-1].replace('worktree ', '') |
| 106 | + break |
| 107 | + |
| 108 | + if worktree_path: |
| 109 | + print(f'📍 WORKTREE_PATH={worktree_path}') |
| 110 | + |
| 111 | +sys.exit(exit_code) |
| 112 | +``` |
| 113 | + |
| 114 | +## 설정 파일 복사 (에이전트 동적 판단) |
| 115 | + |
| 116 | +Worktree 생성 성공 후, **에이전트가 `.gitignore`를 분석하여 민감 파일을 동적으로 판단**하고 복사합니다. |
| 117 | + |
| 118 | +### Step 1: .gitignore 분석 |
| 119 | + |
| 120 | +프로젝트 `.gitignore` 파일을 읽고 다음 카테고리의 민감 파일 패턴을 식별합니다: |
| 121 | + |
| 122 | +| 카테고리 | 식별 패턴 | 설명 | |
| 123 | +|---------|----------|------| |
| 124 | +| Firebase 설정 | `google-services.json`, `GoogleService-Info.plist` | Firebase 연동 설정 | |
| 125 | +| 서명 키/인증서 | `key.properties`, `*.jks`, `*.p12`, `*.p8`, `*.mobileprovision` | 앱 서명 인증서 | |
| 126 | +| 빌드 설정 | `Secrets.xcconfig`, 민감한 `*.xcconfig` | iOS 빌드 비밀 설정 | |
| 127 | +| 환경 변수 | `*.env` | 환경별 설정 파일 | |
| 128 | +| IDE 로컬 설정 | `settings.local.json` | Claude/Cursor 로컬 설정 | |
| 129 | + |
| 130 | +### Step 2: 실제 파일 확인 및 복사 |
| 131 | + |
| 132 | +1. `.gitignore`에 명시된 패턴 중 **실제 존재하는 파일** 확인 |
| 133 | +2. 존재하는 파일만 worktree 경로로 복사 |
| 134 | +3. 디렉토리 구조 유지 (예: `android/app/google-services.json` → `worktree/android/app/google-services.json`) |
| 135 | + |
| 136 | +**복사 명령 예시**: |
| 137 | +```bash |
| 138 | +# Python shutil 사용 |
| 139 | +import shutil |
| 140 | +shutil.copy2('원본경로', 'worktree경로/원본경로') |
| 141 | +``` |
| 142 | + |
| 143 | +### Step 3: 복사 제외 대상 (절대 복사 금지) |
| 144 | + |
| 145 | +다음은 민감 파일이더라도 **절대 복사하지 않습니다**: |
| 146 | + |
| 147 | +| 경로/패턴 | 이유 | |
| 148 | +|----------|------| |
| 149 | +| `build/`, `target/`, `.gradle/` | 빌드 산출물 (새로 빌드 필요) | |
| 150 | +| `node_modules/`, `Pods/`, `.dart_tool/` | 의존성 (새로 설치 필요) | |
| 151 | +| `.report/`, `.run/` | 보고서 (worktree별로 별도 생성) | |
| 152 | +| `.idea/` | IDE 캐시 전체 | |
| 153 | +| `*.log`, `*.class`, `*.pyc` | 임시/컴파일 파일 | |
| 154 | + |
| 155 | +### Step 4: 결과 출력 |
| 156 | + |
| 157 | +복사된 파일 목록을 ✅ 이모지와 함께 출력합니다: |
| 158 | +``` |
| 159 | +✅ android/app/google-services.json 복사 완료 |
| 160 | +✅ ios/Runner/GoogleService-Info.plist 복사 완료 |
| 161 | +✅ android/key.properties 복사 완료 |
| 162 | +``` |
| 163 | + |
| 164 | +**참고**: |
| 165 | +- 파일이 존재하지 않으면 해당 복사는 자동으로 건너뜁니다. |
| 166 | +- 에이전트가 `.gitignore`를 분석하여 복사 대상을 동적으로 결정합니다. |
0 commit comments