mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-01-14 13:00:10 -06:00
Split get_git_dir() into get_git_dir() and get_git_common_dir()
This fixes the conflicted state check when using work trees. #1972
This commit is contained in:
committed by
Anthony Sottile
parent
934afb85a4
commit
ba132f0200
@@ -36,7 +36,7 @@ def _hook_paths(
|
||||
hook_type: str,
|
||||
git_dir: str | None = None,
|
||||
) -> tuple[str, str]:
|
||||
git_dir = git_dir if git_dir is not None else git.get_git_dir()
|
||||
git_dir = git_dir if git_dir is not None else git.get_git_common_dir()
|
||||
pth = os.path.join(git_dir, 'hooks', hook_type)
|
||||
return pth, f'{pth}.legacy'
|
||||
|
||||
|
||||
@@ -57,13 +57,15 @@ def get_root() -> str:
|
||||
root = os.path.abspath(
|
||||
cmd_output('git', 'rev-parse', '--show-cdup')[1].strip(),
|
||||
)
|
||||
git_dir = os.path.abspath(get_git_dir())
|
||||
inside_git_dir = cmd_output(
|
||||
'git', 'rev-parse', '--is-inside-git-dir',
|
||||
)[1].strip()
|
||||
except CalledProcessError:
|
||||
raise FatalError(
|
||||
'git failed. Is it installed, and are you in a Git repository '
|
||||
'directory?',
|
||||
)
|
||||
if os.path.samefile(root, git_dir):
|
||||
if inside_git_dir != 'false':
|
||||
raise FatalError(
|
||||
'git toplevel unexpectedly empty! make sure you are not '
|
||||
'inside the `.git` directory of your repository.',
|
||||
@@ -72,15 +74,25 @@ def get_root() -> str:
|
||||
|
||||
|
||||
def get_git_dir(git_root: str = '.') -> str:
|
||||
opts = ('--git-common-dir', '--git-dir')
|
||||
_, out, _ = cmd_output('git', 'rev-parse', *opts, cwd=git_root)
|
||||
for line, opt in zip(out.splitlines(), opts):
|
||||
if line != opt: # pragma: no branch (git < 2.5)
|
||||
return os.path.normpath(os.path.join(git_root, line))
|
||||
opt = '--git-dir'
|
||||
_, out, _ = cmd_output('git', 'rev-parse', opt, cwd=git_root)
|
||||
git_dir = out.strip()
|
||||
if git_dir != opt:
|
||||
return os.path.normpath(os.path.join(git_root, git_dir))
|
||||
else:
|
||||
raise AssertionError('unreachable: no git dir')
|
||||
|
||||
|
||||
def get_git_common_dir(git_root: str = '.') -> str:
|
||||
opt = '--git-common-dir'
|
||||
_, out, _ = cmd_output('git', 'rev-parse', opt, cwd=git_root)
|
||||
git_common_dir = out.strip()
|
||||
if git_common_dir != opt:
|
||||
return os.path.normpath(os.path.join(git_root, git_common_dir))
|
||||
else: # pragma: no cover (git < 2.5)
|
||||
return get_git_dir(git_root)
|
||||
|
||||
|
||||
def get_remote_url(git_root: str) -> str:
|
||||
_, out, _ = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)
|
||||
return out.strip()
|
||||
|
||||
@@ -21,6 +21,20 @@ def test_get_root_deeper(in_git_dir):
|
||||
assert os.path.normcase(git.get_root()) == expected
|
||||
|
||||
|
||||
def test_get_root_in_git_sub_dir(in_git_dir):
|
||||
expected = os.path.normcase(in_git_dir.strpath)
|
||||
with pytest.raises(FatalError):
|
||||
with in_git_dir.join('.git/objects').ensure_dir().as_cwd():
|
||||
assert os.path.normcase(git.get_root()) == expected
|
||||
|
||||
|
||||
def test_get_root_not_in_working_dir(in_git_dir):
|
||||
expected = os.path.normcase(in_git_dir.strpath)
|
||||
with pytest.raises(FatalError):
|
||||
with in_git_dir.join('..').ensure_dir().as_cwd():
|
||||
assert os.path.normcase(git.get_root()) == expected
|
||||
|
||||
|
||||
def test_in_exactly_dot_git(in_git_dir):
|
||||
with in_git_dir.join('.git').as_cwd(), pytest.raises(FatalError):
|
||||
git.get_root()
|
||||
@@ -40,6 +54,22 @@ def test_get_root_bare_worktree(tmpdir):
|
||||
assert git.get_root() == os.path.abspath('.')
|
||||
|
||||
|
||||
def test_get_git_dir(tmpdir):
|
||||
"""Regression test for #1972"""
|
||||
src = tmpdir.join('src').ensure_dir()
|
||||
cmd_output('git', 'init', str(src))
|
||||
git_commit(cwd=str(src))
|
||||
|
||||
worktree = tmpdir.join('worktree').ensure_dir()
|
||||
cmd_output('git', 'worktree', 'add', '../worktree', cwd=src)
|
||||
|
||||
with worktree.as_cwd():
|
||||
assert git.get_git_dir() == src.ensure_dir(
|
||||
'.git/worktrees/worktree',
|
||||
)
|
||||
assert git.get_git_common_dir() == src.ensure_dir('.git')
|
||||
|
||||
|
||||
def test_get_root_worktree_in_git(tmpdir):
|
||||
src = tmpdir.join('src').ensure_dir()
|
||||
cmd_output('git', 'init', str(src))
|
||||
|
||||
Reference in New Issue
Block a user