| 302 | |
| 303 | |
| 304 | def list_worktrees(cwd: str | None = None) -> list[Worktree]: |
| 305 | stdout = _run_git_ok(["worktree", "list", "--porcelain"], cwd) |
| 306 | if not stdout: |
| 307 | return [] |
| 308 | |
| 309 | worktrees: list[Worktree] = [] |
| 310 | current: dict[str, str] = {} |
| 311 | |
| 312 | for line in stdout.splitlines(): |
| 313 | if not line.strip(): |
| 314 | if current: |
| 315 | worktrees.append(Worktree( |
| 316 | path=current.get("worktree", ""), |
| 317 | branch=current.get("branch", "").replace("refs/heads/", ""), |
| 318 | commit=current.get("HEAD"), |
| 319 | is_bare="bare" in current, |
| 320 | )) |
| 321 | current = {} |
| 322 | continue |
| 323 | |
| 324 | if line.startswith("worktree "): |
| 325 | current["worktree"] = line[9:] |
| 326 | elif line.startswith("HEAD "): |
| 327 | current["HEAD"] = line[5:] |
| 328 | elif line.startswith("branch "): |
| 329 | current["branch"] = line[7:] |
| 330 | elif line == "bare": |
| 331 | current["bare"] = "true" |
| 332 | |
| 333 | if current: |
| 334 | worktrees.append(Worktree( |
| 335 | path=current.get("worktree", ""), |
| 336 | branch=current.get("branch", "").replace("refs/heads/", ""), |
| 337 | commit=current.get("HEAD"), |
| 338 | is_bare="bare" in current, |
| 339 | )) |
| 340 | |
| 341 | if worktrees: |
| 342 | worktrees[0].is_main = True |
| 343 | |
| 344 | return worktrees |
| 345 | |
| 346 | |
| 347 | def create_worktree( |