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'