Capture a git ref representing the current working tree state. Uses `git stash create` which creates a commit object for the current state (HEAD + uncommitted changes) without modifying the stash list or working tree. Falls back to HEAD if the working tree is clean. Returns the
(cwd)
| 161 | |
| 162 | |
| 163 | def capture_git_baseline(cwd): |
| 164 | """ |
| 165 | Capture a git ref representing the current working tree state. |
| 166 | Uses `git stash create` which creates a commit object for the current state |
| 167 | (HEAD + uncommitted changes) without modifying the stash list or working tree. |
| 168 | Falls back to HEAD if the working tree is clean. |
| 169 | Returns the SHA string, or None if not in a git repo or if the repo has no commits. |
| 170 | |
| 171 | NOTE: `git stash create` does NOT capture untracked files. UPS pairs this |
| 172 | SHA with a `_list_untracked()` snapshot stored as `untracked_at_baseline`, |
| 173 | and `compute_v2_review_set` subtracts that set so pre-existing untracked |
| 174 | files are not reviewed as Claude-authored. |
| 175 | """ |
| 176 | try: |
| 177 | # Check if HEAD exists (i.e., repo has at least one commit) |
| 178 | head_check = subprocess.run( |
| 179 | [*GIT_CMD, "rev-parse", "HEAD"], |
| 180 | cwd=cwd, capture_output=True, text=True, timeout=5 |
| 181 | ) |
| 182 | if head_check.returncode != 0: |
| 183 | # No commits yet — skip review rather than creating commits in the user's repo |
| 184 | debug_log("No commits in repo, skipping baseline capture") |
| 185 | return None |
| 186 | |
| 187 | result = subprocess.run( |
| 188 | [*GIT_CMD, "stash", "create"], |
| 189 | cwd=cwd, capture_output=True, text=True, timeout=15 |
| 190 | ) |
| 191 | sha = result.stdout.strip() |
| 192 | if sha: |
| 193 | return sha |
| 194 | |
| 195 | # Working tree is clean — stash create returns empty. Use HEAD. |
| 196 | result = subprocess.run( |
| 197 | [*GIT_CMD, "rev-parse", "HEAD"], |
| 198 | cwd=cwd, capture_output=True, text=True, timeout=5 |
| 199 | ) |
| 200 | sha = result.stdout.strip() |
| 201 | return sha if sha else None |
| 202 | except (subprocess.TimeoutExpired, FileNotFoundError, OSError) as e: |
| 203 | debug_log(f"Failed to capture git baseline: {e}") |
| 204 | return None |
| 205 | |
| 206 | |
| 207 | # ─── push-sweep reviewed-commit tracking ──────────────────────────────────── |
no test coverage detected