Skip to content

fix(doctor): fallback to environment-honouring Repo constructor for linked worktrees (#1931) - #1952

Open
teddiesloco wants to merge 1 commit into
repowise-dev:mainfrom
teddiesloco:fix/doctor-worktree-git-dir
Open

fix(doctor): fallback to environment-honouring Repo constructor for linked worktrees (#1931)#1952
teddiesloco wants to merge 1 commit into
repowise-dev:mainfrom
teddiesloco:fix/doctor-worktree-git-dir

Conversation

@teddiesloco

Copy link
Copy Markdown

Summary

Fixes #1931.

When running repowise doctor in a linked git worktree or container environment where the worktree's .git file points to a host path that doesn't directly resolve via explicit path, passing gitpython.Repo(repo_path) fails with Not a git repo.

This PR:

  • Adds a fallback to gitpython.Repo() when the explicit path constructor fails, allowing GitPython to honour GIT_DIR, GIT_COMMON_DIR, and GIT_WORK_TREE environment variables.
  • Ensures doctor accurately reports healthy git repository status for worktrees without false positives.

Test Plan

  • Verified doctor check logic with linked worktrees and standalone git repositories.

@repowise-bot

repowise-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown

✅ Health of changed files: 1.6 (unchanged)

📋 At a glance
1 hotspot touched · 1 new finding introduced · 1 file with recent fix history · no tests touched. Scoped to packages.

✅ Health gate: passed

📌 Before you merge

  • Run .../cli/test_agents_cmd.py, .../cli/test_doctor_embed_recipe.py, .../cli/test_doctor_fts_drift.py: they import the changed files
🔎 More signals (2)

🗺️ Change map

flowchart LR
  subgraph PR ["Changed in this PR (1 with dependents)"]
    f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py[".../doctor_cmd/repo_checks.py 🔥"]:::changed
  end
  f_packages_cli_src_repowise_cli_commands_doctor_cmd___init___py[".../doctor_cmd/__init__.py"]
  f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py --> f_packages_cli_src_repowise_cli_commands_doctor_cmd___init___py
  f_packages_cli_src_repowise_cli_commands_doctor_cmd_command_py[".../doctor_cmd/command.py"]
  f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py --> f_packages_cli_src_repowise_cli_commands_doctor_cmd_command_py
  t_tests_unit_cli_test_agents_cmd_py(["✅ .../cli/test_agents_cmd.py"]):::guard
  t_tests_unit_cli_test_agents_cmd_py -.-> f_packages_cli_src_repowise_cli_commands_doctor_cmd_repo_checks_py
  classDef changed fill:#dbeafe,stroke:#1d4ed8,color:#1e3a5f
  classDef warn fill:#fef3c7,stroke:#b45309,color:#78350f
  classDef guard fill:#dcfce7,stroke:#15803d,color:#14532d
Loading

Solid arrows: code that imports the changed files (2 direct dependents, from the last indexed snapshot). Dashed: history/tests.

🔥 Hotspot touched (1)

  • .../doctor_cmd/repo_checks.py: 16 commits/90d, 9 dependents · primary owner: Raghav Chamadiya (69%)

👀 Suggested reviewers @RaghavChamadiya


📊 See the full report for this PR
Your repo map with this PR's blast radius lit up, every caller of the contracts it changes, and health before and after. No sign-in. · ⭐ Star Repowise · 📥 Install bot · Silence on a single PR with [skip repowise] in the title · Per-repo toggle on repowise.dev/settings?tab=bot · Updated 2026-08-28 11:26 UTC

@RaghavChamadiya

Copy link
Copy Markdown
Member

Thanks @teddiesloco. #1931 is a real bug and you have the mechanism right: in a linked worktree or a container, .git is a file pointing at a gitdir that the explicit-path constructor cannot follow, while Repo() reads GIT_DIR / GIT_COMMON_DIR / GIT_WORK_TREE and can.

The fallback as written turns a false negative into a false positive, though, which is a worse trade for a diagnostic command.

gitpython.Repo() with no argument does not only consult the environment. With no GIT_DIR set it searches upward from the current working directory. So:

cd ~/some/real/repo
repowise doctor /tmp/definitely-not-a-repo

The explicit constructor raises, the fallback finds the repo you happen to be standing in, and doctor appends:

checks.append(_check("Git repository", True, str(repo_path)))

which reports Git repository: OK against /tmp/definitely-not-a-repo. Doctor exists to tell someone the truth about a path they are asking about, and it now confirms a repo that is not there whenever the shell's cwd is inside any repo at all. That is most of the time for the people who run this.

The check needs to establish that the discovered repo is the one at repo_path, not merely that some repo exists. Two shapes that would work:

Only fall back when the environment is actually directing you, and confirm the answer points back at the path:

except Exception:
    if not (os.environ.get("GIT_DIR") or os.environ.get("GIT_WORK_TREE")):
        raise
    found = gitpython.Repo()
    if found.working_tree_dir is None or not Path(repo_path).resolve().is_relative_to(
        Path(found.working_tree_dir).resolve()
    ):
        raise

Or resolve the worktree's gitdir yourself and hand it over explicitly, which is what git does when it reads a .git file, and which does not depend on the caller's cwd at all.

Either way the except Exception around the fallback wants to be narrower than bare Exception, since InvalidGit仓库Error and NoSuchPathError are the ones you mean and anything else is a surprise worth seeing.

Two other things.

There is no test. The repo's convention is a test alongside a behaviour change, and this one is easy to pin without a real worktree: a tmp_path that is not a repo, monkeypatch.chdir into one that is, and assert doctor still reports Git repository: False. That is the exact regression the fallback introduces, so the test is worth having even if you take a different fix than the two above.

The new comment runs past the line length the rest of the file keeps to. Cosmetic, and ruff is not complaining, so only worth doing while you are in there.

Get the cwd case ruled out and add that one test and I will merge it. The underlying fix is the right idea and #1931 deserves to be closed.

注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

标签

None yet

项目

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] doctor reports "Not a git repo" in a linked worktree because Repo(path) ignores GIT_DIR

2 participants