Repo instantiated from a bare-repository worktree incorrectly sets bare = True
Description
Since 3.1.58+, instantiating a git.Repo targeting a working tree folder that was created from a bare repository (via git worktree add) inherits the bare = True setting from the main repository's .git location.
This causes repo.working_tree_dir to resolve to None, which causes operations like index.add() / _entries_for_paths to fail with:
InvalidGitRepositoryError: Cannot rewrite paths without a working tree
Minimal Reproduction Example
fromgitimportRepoimportsubprocess, tempfile, oswithtempfile.TemporaryDirectory() astmpdir:
bare_path=os.path.join(tmpdir, "bare.git")
worktree_path=os.path.join(tmpdir, "wt")
# 1. Init bare repo and add a commitrepo_bare=Repo.init(bare_path, bare=True)
# 2. Add a worktreerepo_bare.git.worktree("add", "-b", "main", worktree_path)
# 3. Open worktree repowt_repo=Repo(worktree_path)
# Expected: wt_repo.bare is False, wt_repo.working_tree_dir is worktree_path# Actual: wt_repo.bare is True, wt_repo.working_tree_dir is Noneprint("Is bare:", wt_repo.bare)
print("Working tree dir:", wt_repo.working_tree_dir)
Isbare: TrueWorkingtreedir: Nonewhileusing3.1.57thesamecodeproducesthecorrectresultsIsbare: FalseWorkingtreedir: /tmp/tmpgz7gz3y6/wt
Adding a data point in case it helps prioritize a release: this regression took down the documentation build for every project in our monorepo CI starting the day our build image picked up 3.1.61.
Our CI checks each job out as a linked worktree of a shared bare repository (git --git-dir=<bare-repo> worktree add <job-dir> <sha>), then runs mkdocs with mkdocs-git-revision-date-localized-plugin, which calls Repo(docs_dir, search_parent_directories=True).git.log(...). With 3.1.61 the worktree inherits core.bare = true from the shared repo, working_dir falls back to the common dir, and git rejects the path:
[git-revision-date-localized-plugin] Unable to read git logs of '/build/repo/<project>/docs'
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
cmdline: git log --date=unix --format=%at --diff-filter=r -n 1 --no-show-signature --follow --ignore-all-space --ignore-blank-lines /build/repo/<project>/docs
stderr: 'fatal: /build/repo/<project>/docs: '/build/repo/<project>/docs' is outside repository at '/cache/repos/<hash>/.''
Minimal repro (fails on 3.1.61, passes on 3.1.60 and on current main with 180b1ff):
git init -q main && git -C main commit -q --allow-empty -m init
git clone -q --bare main bare.git
git --git-dir="$PWD/bare.git" worktree add -q --detach "$PWD/wt" HEAD
python -c "from git import Repo; r=Repo('wt'); print(r.bare, r.working_dir); r.git.log('-n','1','--','$PWD/wt')"
We have pinned GitPython!=3.1.61 for now. A 3.1.62 with #2224 would let us drop the pin. Thanks for the quick fix.
I consider this - guilting - an unnecessary escalation. Next time, start with merely asking for a release, feel free to say it would mean a lot to you, and only if that doesn't work amp up the intensity of these requests.
Probably I am talking to an agent here (markdown is very consistently used), so maybe I will put this into another place if it keeps happening.
Activity
fix: keep bare-repository worktrees non-bare (#2223)
christianvuerings commented on Sep 6, 2026
Adding a data point in case it helps prioritize a release: this regression took down the documentation build for every project in our monorepo CI starting the day our build image picked up 3.1.61.
Our CI checks each job out as a linked worktree of a shared bare repository (git --git-dir=<bare-repo> worktree add <job-dir> <sha>), then runs mkdocs with mkdocs-git-revision-date-localized-plugin, which calls Repo(docs_dir, search_parent_directories=True).git.log(...). With 3.1.61 the worktree inherits core.bare = true from the shared repo, working_dir falls back to the common dir, and git rejects the path:
[git-revision-date-localized-plugin] Unable to read git logs of '/build/repo/<project>/docs' git.exc.GitCommandError: Cmd('git') failed due to: exit code(128) cmdline: git log --date=unix --format=%at --diff-filter=r -n 1 --no-show-signature --follow --ignore-all-space --ignore-blank-lines /build/repo/<project>/docs stderr: 'fatal: /build/repo/<project>/docs: '/build/repo/<project>/docs' is outside repository at '/cache/repos/<hash>/.''Minimal repro (fails on 3.1.61, passes on 3.1.60 and on current main with 180b1ff):
We have pinned GitPython!=3.1.61 for now. A 3.1.62 with #2224 would let us drop the pin. Thanks for the quick fix.
Byron commented on Sep 7, 2026
I consider this - guilting - an unnecessary escalation. Next time, start with merely asking for a release, feel free to say it would mean a lot to you, and only if that doesn't work amp up the intensity of these requests.
Probably I am talking to an agent here (markdown is very consistently used), so maybe I will put this into another place if it keeps happening.
test: cover subdirectory discovery and pathspec commands in bare-repo…
christianvuerings commented on Sep 7, 2026
@Byron I apologize. I'll make sure this doesn't happen again.