Return (base_commit, head_commit, mode).
(repo: Path, override_base: str | None, override_head: str | None)
| 210 | |
| 211 | |
| 212 | def determine_diff_range(repo: Path, override_base: str | None, override_head: str | None) -> tuple[str, str, DiffMode]: |
| 213 | """Return (base_commit, head_commit, mode).""" |
| 214 | zero_sha = "0" * 40 |
| 215 | event_name = os.environ.get("GITHUB_EVENT_NAME", "") |
| 216 | event = _load_github_event() |
| 217 | |
| 218 | if override_base and override_head: |
| 219 | base = _validate_sha("base", override_base) |
| 220 | head = _validate_sha("head", override_head) |
| 221 | _ensure_commit_exists(base, repo) |
| 222 | _ensure_commit_exists(head, repo) |
| 223 | return base, head, DiffMode.MANUAL |
| 224 | |
| 225 | if event_name == "pull_request" and "pull_request" in event: |
| 226 | base_sha = _validate_sha("base", event["pull_request"]["base"]["sha"]) |
| 227 | head_sha = _validate_sha("head", event["pull_request"]["head"]["sha"]) |
| 228 | _ensure_commit_exists(base_sha, repo) |
| 229 | _ensure_commit_exists(head_sha, repo) |
| 230 | # Use merge-base to approximate the PR triple-dot diff base deterministically. |
| 231 | merge_base = _run_git(["merge-base", head_sha, base_sha], repo) |
| 232 | merge_base = _validate_sha("merge-base", merge_base) |
| 233 | _ensure_commit_exists(merge_base, repo) |
| 234 | return merge_base, head_sha, DiffMode.PR |
| 235 | |
| 236 | if event_name == "push" and "before" in event and "after" in event: |
| 237 | before = _validate_sha("before", event["before"]) |
| 238 | after = _validate_sha("after", event["after"]) |
| 239 | _ensure_commit_exists(after, repo) |
| 240 | |
| 241 | if before == zero_sha: |
| 242 | empty = _empty_tree(repo) |
| 243 | return empty, after, DiffMode.INITIAL |
| 244 | try: |
| 245 | _ensure_commit_exists(before, repo) |
| 246 | return before, after, DiffMode.PUSH |
| 247 | except Exception: |
| 248 | empty = _empty_tree(repo) |
| 249 | return empty, after, DiffMode.INITIAL |
| 250 | |
| 251 | # Fallback: try parent..HEAD; if no parent (initial commit), diff empty-tree..HEAD |
| 252 | try: |
| 253 | head = _validate_sha("HEAD", _run_git(["rev-parse", "HEAD"], repo)) |
| 254 | _ensure_commit_exists(head, repo) |
| 255 | |
| 256 | try: |
| 257 | prev = _validate_sha("HEAD^", _run_git(["rev-parse", "--verify", "HEAD^"], repo)) |
| 258 | _ensure_commit_exists(prev, repo) |
| 259 | return prev, head, DiffMode.FALLBACK |
| 260 | except Exception: |
| 261 | # Initial commit (no parent): treat as "everything added" |
| 262 | empty = _empty_tree(repo) |
| 263 | return empty, head, DiffMode.INITIAL |
| 264 | except Exception: |
| 265 | return "", "", DiffMode.FALLBACK_NO_HEAD |
| 266 | |
| 267 | |
| 268 | def changed_files(repo: Path, base: str, head: str) -> list[str]: |
no test coverage detected