From 180b1ffab5fdcb52a674fb6461ca42d9788b3a07 Mon Sep 17 00:00:00 2001 From: Byron Date: Tue, 1 Sep 2026 09:33:11 +0200 Subject: [PATCH 1/2] fix: keep bare-repository worktrees non-bare (#2223) Opening a linked worktree created from a bare repository read `core.bare` from the common repository and discarded the worktree path. Keep a discovered linked worktree non-bare when its administrative directory has a `commondir` marker. The regression compares Git rev-parse behavior and verifies Repo.bare and working_tree_dir. Git baseline: 0bd5a6920d7c4238e0d90ddc0e7e08866e84a0f1; environment.c:is_bare_repository() and setup.c:check_repository_format_gently(). Git 2.50.1 reports the linked checkout as non-bare. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 --- git/repo/base.py | 4 ++++ test/test_repo.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/git/repo/base.py b/git/repo/base.py index 4ae48e17b..7039d0320 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -386,6 +386,10 @@ def __init__( # Let's not assume the option exists, although it should. pass + # A linked worktree is not bare even when its main repository is. + if self._bare and self._working_tree_dir and osp.isfile(osp.join(self.git_dir, "commondir")): + self._bare = False + # Adjust the working directory in case we are actually bare - we didn't know # that in the first place. if self._bare: diff --git a/test/test_repo.py b/test/test_repo.py index 12e572f52..ad1fa68ab 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -1459,6 +1459,23 @@ def test_git_work_tree_dotgit(self, rw_dir, use_relative_paths=False): self.assertIsInstance(repo.heads["aaaaaaaa"], Head) + @with_rw_directory + def test_git_work_tree_from_bare_repo(self, rw_dir): + if Git().version_info[:3] < (2, 5, 1): + pytest.skip("worktree feature unsupported, needs git 2.5.1 or later") + + bare_repo = self.rorepo.clone(join_path_native(rw_dir, "bare_repo"), bare=True) + worktree_path = join_path_native(rw_dir, "worktree_repo") + if Git.is_cygwin(): + worktree_path = cygpath(worktree_path) + bare_repo.git.worktree("add", "--detach", worktree_path) + + repo = Repo(worktree_path) + + assert Git(worktree_path).rev_parse("--is-bare-repository") == "false" + assert not repo.bare + assert osp.samefile(repo.working_tree_dir, worktree_path) + def test_git_work_tree_dotgit_relative(self): """Check that we find .git as a worktree file containing a relative path and find the worktree based on it.""" From 0e8c23c56c816b7fae8d2417606e9d6f7b37cc87 Mon Sep 17 00:00:00 2001 From: Byron Date: Tue, 1 Sep 2026 10:14:10 +0200 Subject: [PATCH 2/2] ci: restore Cygwin virtual environments on Python 3.9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cygwin patches ensurepip to load setuptools and pip wheels from `/usr/share/python-wheels`. The rolling python-pip-wheel package advanced to pip 26.2.1, which requires Python 3.10 or newer, so every Python 3.9 venv creation failed—including the installation test's nested virtual environment. Keep the single Cygwin lane on Python 3.9 because the regular matrix already covers Python 3.12 and newer. Install Cygwin's setuptools wheel, download pip 26.0.1 from its immutable PyPI URL into ensurepip's shared wheel directory, verify its SHA-256 digest, and avoid upgrading pip. This fixes all venv creation without relying on a version that may disappear from rolling Cygwin mirrors. Assisted-by: GPT 5.6 Co-authored-by: GPT 5.6 --- .github/workflows/cygwin-test.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cygwin-test.yml b/.github/workflows/cygwin-test.yml index b8150e93d..e14856e7e 100644 --- a/.github/workflows/cygwin-test.yml +++ b/.github/workflows/cygwin-test.yml @@ -45,7 +45,7 @@ jobs: - name: Install Cygwin uses: cygwin/cygwin-install-action@v6 with: - packages: git python39 python-pip-wheel python-setuptools-wheel python-wheel-wheel + packages: curl git python39 python-setuptools-wheel add-to-path: false # No need to change $PATH outside the Cygwin environment. - name: Arrange for verbose output @@ -73,12 +73,15 @@ jobs: - name: Set up virtual environment run: | + pip_wheel=/usr/share/python-wheels/pip-26.0.1-py3-none-any.whl + curl -fsSLo "$pip_wheel" https://files.pythonhosted.org/packages/de/f0/c81e05b613866b76d2d1066490adf1a3dbc4ee9d9c839961c3fc8a6997af/pip-26.0.1-py3-none-any.whl + python3.9 -c 'import hashlib, pathlib, sys; assert hashlib.sha256(pathlib.Path(sys.argv[1]).read_bytes()).hexdigest() == sys.argv[2]' "$pip_wheel" bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b python3.9 -m venv .venv echo 'BASH_ENV=.venv/bin/activate' >>"$GITHUB_ENV" - name: Update PyPA packages run: | - python -m pip install -U pip 'setuptools; python_version<"3.12"' wheel + python -m pip install -U 'setuptools; python_version<"3.12"' wheel - name: Install project and test dependencies run: |