mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-19 09:04:41 +04:00
Add guard against the hooks directory being a symbolic link
`pre-commit install` shouldn't mess with directories residing outside of the git repository.
This commit is contained in:
parent
3bdf9fb91b
commit
fd1cfc60bf
2 changed files with 28 additions and 1 deletions
|
|
@ -70,6 +70,22 @@ def _install_hook_script(
|
||||||
) -> None:
|
) -> None:
|
||||||
hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)
|
hook_path, legacy_path = _hook_paths(hook_type, git_dir=git_dir)
|
||||||
|
|
||||||
|
# If the hooks directory is a symlink we need to be careful
|
||||||
|
if os.path.islink(os.path.dirname(hook_path)):
|
||||||
|
git_dir = git_dir if git_dir is not None else git.get_git_common_dir()
|
||||||
|
# If the hooks directory links to a directory outside the
|
||||||
|
# git repo we shouldn't try to mess with it
|
||||||
|
if os.path.commonpath(
|
||||||
|
[os.path.realpath(git_dir), os.path.realpath(hook_path)]
|
||||||
|
) != os.path.realpath(git_dir):
|
||||||
|
logger.error(
|
||||||
|
'Cowardly refusing to install hook script to a directory '
|
||||||
|
'outside of the git repo.\n'
|
||||||
|
f'hint: {os.path.dirname(hook_path)} is a symbolic link '
|
||||||
|
f'to {os.path.realpath(os.path.dirname(hook_path))}.'
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(hook_path), exist_ok=True)
|
os.makedirs(os.path.dirname(hook_path), exist_ok=True)
|
||||||
|
|
||||||
# If we have an existing hook, move it to pre-commit.legacy
|
# If we have an existing hook, move it to pre-commit.legacy
|
||||||
|
|
@ -109,6 +125,7 @@ def _install_hook_script(
|
||||||
make_executable(hook_path)
|
make_executable(hook_path)
|
||||||
|
|
||||||
output.write_line(f'pre-commit installed at {hook_path}')
|
output.write_line(f'pre-commit installed at {hook_path}')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def install(
|
def install(
|
||||||
|
|
@ -128,12 +145,14 @@ def install(
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
for hook_type in _hook_types(config_file, hook_types):
|
for hook_type in _hook_types(config_file, hook_types):
|
||||||
_install_hook_script(
|
ret = _install_hook_script(
|
||||||
config_file, hook_type,
|
config_file, hook_type,
|
||||||
overwrite=overwrite,
|
overwrite=overwrite,
|
||||||
skip_on_missing_config=skip_on_missing_config,
|
skip_on_missing_config=skip_on_missing_config,
|
||||||
git_dir=git_dir,
|
git_dir=git_dir,
|
||||||
)
|
)
|
||||||
|
if ret != 0:
|
||||||
|
return ret
|
||||||
|
|
||||||
if hooks:
|
if hooks:
|
||||||
install_hooks(config_file, store)
|
install_hooks(config_file, store)
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,14 @@ def test_install_hooks_dead_symlink(in_git_dir, store):
|
||||||
assert hook.exists()
|
assert hook.exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_install_hooks_symlink_outisde_git_repo(in_git_dir, store):
|
||||||
|
hook_dir = in_git_dir.join('.git/hooks')
|
||||||
|
hook_dir.mksymlinkto(in_git_dir.join("../hooks"))
|
||||||
|
hook = hook_dir.join('pre-commit')
|
||||||
|
assert install(C.CONFIG_FILE, store, hook_types=['pre-commit']) != 0
|
||||||
|
assert not hook.exists()
|
||||||
|
|
||||||
|
|
||||||
def test_uninstall_does_not_blow_up_when_not_there(in_git_dir):
|
def test_uninstall_does_not_blow_up_when_not_there(in_git_dir):
|
||||||
assert uninstall(C.CONFIG_FILE, hook_types=['pre-commit']) == 0
|
assert uninstall(C.CONFIG_FILE, hook_types=['pre-commit']) == 0
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue