Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No exception handling for commit-msg hook (gitlint 0.14.0) #166

Closed
BrunIF opened this issue Nov 13, 2020 · 4 comments
Closed

No exception handling for commit-msg hook (gitlint 0.14.0) #166

BrunIF opened this issue Nov 13, 2020 · 4 comments
Labels
bug User-facing bugs
Milestone

Comments

@BrunIF
Copy link

BrunIF commented Nov 13, 2020

install gitlint

pip install gitlint
....
gitlint generate-config
gitlint install-hook
git add .
git commit -m "qw"

Error:

gitlint: checking commit message...
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 46, in _git
    result = sh.git(*command_parts, **git_kwargs)  # pylint: disable=unexpected-keyword-arg
  File "/usr/local/lib/python3.9/site-packages/sh.py", line 1427, in __call__
    return RunningCommand(cmd, call_args, stdin, stdout, stderr)
  File "/usr/local/lib/python3.9/site-packages/sh.py", line 774, in __init__
    self.wait()
  File "/usr/local/lib/python3.9/site-packages/sh.py", line 792, in wait
    self.handle_command_exit_code(exit_code)
  File "/usr/local/lib/python3.9/site-packages/sh.py", line 815, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_128:

  RAN: /usr/local/Cellar/git/2.29.0/libexec/git-core/git rev-parse --abbrev-ref HEAD

  STDOUT:
HEAD


  STDERR:
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/gitlint", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/gitlint/cli.py", line 348, in run_hook
    ctx.invoke(lint)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/gitlint/cli.py", line 291, in lint
    violations = linter.lint(commit)
  File "/usr/local/lib/python3.9/site-packages/gitlint/lint.py", line 73, in lint
    LOG.debug("Commit Object\n" + ustr(commit))
  File "/usr/local/lib/python3.9/site-packages/gitlint/utils.py", line 111, in ustr
    return str(obj)
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 187, in __str__
    return sstr(self.__unicode__())  # pragma: no cover
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 184, in __unicode__
    return args[0]._try_cache(cache_decorator.cachekey, cache_func_result)
  File "/usr/local/lib/python3.9/site-packages/gitlint/cache.py", line 12, in _try_cache
    cache_populate_func()
  File "/usr/local/lib/python3.9/site-packages/gitlint/cache.py", line 43, in cache_func_result
    args[0]._cache[cache_decorator.cachekey] = func(*args)
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 334, in branches
    return [self.context.current_branch]
  File "/usr/local/lib/python3.9/site-packages/gitlint/cache.py", line 44, in wrapped
    return args[0]._try_cache(cache_decorator.cachekey, cache_func_result)
  File "/usr/local/lib/python3.9/site-packages/gitlint/cache.py", line 12, in _try_cache
    cache_populate_func()
  File "/usr/local/lib/python3.9/site-packages/gitlint/cache.py", line 43, in cache_func_result
    args[0]._cache[cache_decorator.cachekey] = func(*args)
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 359, in current_branch
    current_branch = ustr(_git("rev-parse", "--abbrev-ref", "HEAD", _cwd=self.repository_path)).strip()
  File "/usr/local/lib/python3.9/site-packages/gitlint/git.py", line 64, in _git
    raise GitContextError(u"Current branch has no commits. Gitlint requires at least one commit to function.")
gitlint.git.GitContextError: Current branch has no commits. Gitlint requires at least one commit to function.
@sigmavirus24
Copy link
Collaborator

The problem here is:

sh.ErrorReturnCode_128:

  RAN: /usr/local/Cellar/git/2.29.0/libexec/git-core/git rev-parse --abbrev-ref HEAD

  STDOUT:
HEAD


  STDERR:
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

In other words, gitlint is shelling out to git and git is erroring. Specifically it's running git rev-parse --abbrev-ref HEAD which seems to fail in your case. Can you explain why that happens? Can you replicate that?

@BrunIF
Copy link
Author

BrunIF commented Nov 17, 2020

~/Development/git-lint git:(main) ✗ git log
fatal: your current branch 'main' does not have any commits yet

My repository is empty now.

~/Development/git-lint git:(main) ✗ git rev-parse --abbrev-ref HEAD
HEAD
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

I deleted commit-msg hooks. Create the first commit. Returned this file back. The second commit worked normally.

~/Development/git-lint git:(main) ✗ git commit -am "test 2"
gitlint: checking commit message...
3: B6 Body message is missing
-----------------------------------------------
gitlint: Your commit message contains the above violations.
Continue with commit anyways (this keeps the current commit message)? [y(es)/n(no)/e(dit)]

Need fix when the repository is empty.

@jorisroovers
Copy link
Owner

Hi,

thanks for opening this issue, there's indeed a bug here related to exception handling.

If you look at the last line in your error message, you'll see that gitlint already detects the empty repository scenario:

gitlint.git.GitContextError: Current branch has no commits. Gitlint requires at least one commit to function.

It's just that the exception isn't properly handled. This is because I overlooked the exception handling in the commit-msg hook when porting it to python in the last release (0.14.0). I'm a bit surprised testing didn't catch it 🤷‍♂️

What needs to happen here, is adding exception handling in the run_hook method:

def run_hook(ctx):

Basically identical to what is done here:

gitlint/gitlint/cli.py

Lines 241 to 249 in 92c7c4a

except GitContextError as e:
click.echo(e)
ctx.exit(GIT_CONTEXT_ERROR_CODE)
except GitLintUsageError as e:
click.echo(f"Error: {e}")
ctx.exit(USAGE_ERROR_CODE)
except LintConfigError as e:
click.echo(f"Config Error: {e}")
ctx.exit(CONFIG_ERROR_CODE)

You'll notice that if you just run gitlint in an empty repo, that the exception is correctly handled and the error is displayed normally.

I'll happily accept a PR (note that it needs to include a test case for this particular scenario), or otherwise fix this myself later :-)

@jorisroovers jorisroovers added the bug User-facing bugs label Nov 17, 2020
@jorisroovers jorisroovers added this to the 0.15.0 milestone Nov 17, 2020
@jorisroovers jorisroovers changed the title Error on Mac OS (Catalina) No exception handling for commit-msg hook (gitlint 0.14.0) Nov 17, 2020
jorisroovers added a commit that referenced this issue Nov 22, 2020
- Gitlint now properly handles exceptions when using the `gitlint run-hook`
  command (#166)
- Added missing test-case for this scenario
- Also renamed some test methods in test_cli_hooks.py to better match the
  existing convention
@jorisroovers
Copy link
Owner

Fixed on the main branch. This will go out as part of 0.15.0 (#160), which is soon.

jorisroovers added a commit that referenced this issue Nov 27, 2020
This release drops support for Python 2.7 and Python 3.5 (both are EOL).
Other than a few minor fixes, there are no functional differences from the
0.14.0 release.

Other call-outs:
- Mac users: Gitlint can now be installed using both homebrew
  (upgraded to latest) and macports.
- Bugfix: Gitlint now properly handles exceptions when using its built-in
  commit-msg hook (#166)
- All dependencies have been upgraded to the latest available versions
  (Click==7.1.2, arrow==0.17.0, sh==1.14.1)
- Much under-the-hood refactoring as a result of dropping Python 2.7

Full Release details in CHANGELOG.md.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug User-facing bugs
Projects
None yet
Development

No branches or pull requests

3 participants