-
Notifications
You must be signed in to change notification settings - Fork 163
Description
Environment
- ggshield version: 1.36.0
- Operating system (Linux, macOS, Windows): Linux
- Operating system version: Ubuntu 24.04.2 LTS
- Python version: 3.11.6
Describe the bug
Global Git user configuration is ignored/overwritten when running a ggshield scan, leading to dubious ownership errors.
Steps to reproduce:
mkdir ggshield_test
cd ggshield_test
git init
ggshield secret scan repo . # Works as expected with no errors
chown <different user>:<different group> /path/to/ggshield_test/ # change ownership of the repo to another user
ggshield secret scan repo . # ggshield complains about dubious ownership in the repo
git rev-parse --git-dir # git complains about dubious onwership in the repo
git config --global --add safe.directory /path/to/ggshield_test
git rev-parse --git-dir # git no longer complains about dubious ownership
ggshield secret scan repo . # ggshield still complains about dubious ownership in the repo
Actual result:
(ggshield) oli@K57252:~/tmp/ggshield_test$ ggshield secret scan repo .
Traceback (most recent call last):
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 206, in git
result = subprocess.run(
^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/lib/python3.11/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/usr/bin/git', 'rev-parse', '--git-dir']' returned non-zero exit status 128.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/oli/.pyenv/versions/ggshield/bin/ggshield", line 8, in <module>
sys.exit(main())
^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/__main__.py", line 205, in main
return cli.main(args, prog_name="ggshield", standalone_mode=not show_crash_log)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/click/core.py", line 1078, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/click/core.py", line 1685, in invoke
super().invoke(ctx)
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/click/core.py", line 783, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/click/decorators.py", line 33, in new_func
return f(get_current_context(), *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/__main__.py", line 91, in cli
ctx_obj.config = Config(config_path)
^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/core/config/config.py", line 66, in __init__
self.user_config, self._config_path = UserConfig.load(config_path=config_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/core/config/user_config.py", line 143, in load
local_config_path = find_local_config_path()
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/core/config/utils.py", line 108, in find_local_config_path
project_root_dir = get_project_root_dir(Path())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/core/dirs.py", line 52, in get_project_root_dir
return get_git_root(wd=path).resolve()
^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 165, in get_git_root
check_git_dir(wd)
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 179, in check_git_dir
if not is_git_dir(wd):
^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 145, in is_git_dir
return _git_rev_parse("--git-dir", Path(wd)) is not None
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 96, in _git_rev_parse
return _git_rev_parse_absolute(option=option, wd_absolute=wd.resolve())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 90, in _git_rev_parse_absolute
return git(["rev-parse", option], cwd=wd_absolute, log_stderr=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/oli/.pyenv/versions/3.11.6/envs/ggshield/lib/python3.11/site-packages/ggshield/utils/git_shell.py", line 226, in git
raise GitError(
ggshield.utils.git_shell.GitError: Git command failed because of a dubious ownership in repository.
If you still want to run ggshield, make sure you mark the current repository as safe for git with:
git config --global --add safe.directory <YOUR_REPO>
Expected result:
ggshield respects the global git configuration by the user, who executes the ggshield scan.
The root cause of this error seems to be the following line in the code: https://github.com/GitGuardian/ggshield/blob/main/ggshield/utils/git_shell.py#L198 This sets the GIT_CONFIG_GLOBAL
env var even if it was not set before. As a result, the path to the global git config is now an empty string. Therefore the git command ignores the users global git configuration file. As a workaround we now have to additionally set the GG_GIT_CONFIG
env var to the path of the users global git config.
Based on the comment above the specific code it seems like this is intended? However I fail to see why ggshield would want to ignore/owerwrite the users global git configuration?
As a ggshield user I would expect ggshield to respect my global git configuration without the user having to set a specific env var that is not documented (as far as I know).