From 8315b053980e82dff0fea70f56391eb80ec373a2 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Fri, 24 Apr 2026 13:34:58 +0200 Subject: [PATCH] Detect git worktrees and submodules in identify_vcs In a linked git worktree (`git worktree add ...`) or a git submodule, `.git` is a regular file containing a `gitdir: ` pointer rather than a directory. `identify_vcs` only checked `.is_dir()`, so it returned `None` inside a worktree and `flit`'s sdist builder silently fell back to a non-VCS file set via `SdistBuilder.select_files` (`flit/sdist.py`), producing an incomplete sdist that omits tracked files such as `docs/`, `tests/`, and other data files. Accept `.git` whether it is a directory or a file; downstream `git ls-files` naturally validates the pointer. --- flit/vcs/__init__.py | 6 +++++- tests/test_vcs.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/flit/vcs/__init__.py b/flit/vcs/__init__.py index a3e92b39..27dd4ec3 100644 --- a/flit/vcs/__init__.py +++ b/flit/vcs/__init__.py @@ -6,7 +6,11 @@ def identify_vcs(directory: Path): directory = directory.resolve() for p in [directory] + list(directory.parents): - if (p / '.git').is_dir(): + # In a linked git worktree (`git worktree add ...`) or inside a + # git submodule, `.git` is a regular file containing a + # `gitdir: ` pointer rather than a directory. + git_entry = p / '.git' + if git_entry.is_dir() or git_entry.is_file(): return git if (p / '.hg').is_dir(): return hg diff --git a/tests/test_vcs.py b/tests/test_vcs.py index b528d4b4..300ff01a 100644 --- a/tests/test_vcs.py +++ b/tests/test_vcs.py @@ -24,3 +24,14 @@ def test_identify_git_parent(): subdir.mkdir() with cwd(subdir): assert vcs.identify_vcs(Path('.')).name == 'git' + +def test_identify_git_worktree(): + # In a linked git worktree (or submodule) `.git` is a regular file + # containing a `gitdir:` pointer rather than a directory. + with TemporaryDirectory() as td: + td = Path(td) + (td / '.git').write_text('gitdir: /path/to/main/.git/worktrees/feature\n') + subdir = (td / 'subdir') + subdir.mkdir() + with cwd(subdir): + assert vcs.identify_vcs(Path('.')).name == 'git'