diff --git a/devtools/commitgen/cli.py b/devtools/commitgen/cli.py index 1a7698e..267cc42 100644 --- a/devtools/commitgen/cli.py +++ b/devtools/commitgen/cli.py @@ -53,6 +53,7 @@ def cli(): default=True, help="Smartly group multiple file changes into one commit (disable to commit per-file)", ) +@click.option("--no-verify", is_flag=True, help="Bypass git hooks when committing") def generate( files: tuple, repo: str, @@ -64,6 +65,7 @@ def generate( temperature: float, emoji: bool, smart_group: bool, + no_verify: bool, ): """Generate commit messages for staged changes""" try: @@ -131,14 +133,21 @@ def generate( # Assumes files are already staged; git commit -- will include only that path for fp, msg in messages_by_file.items(): ok, out, err, code = git_service.commit_paths_verbose( - msg, [fp], sign=sign + msg, [fp], sign=sign, no_verify=no_verify ) if not ok: raise Exception( f"Failed to commit {fp}: {err or out or code}" ) else: - git_service.commit_changes(commit_message, sign=sign) + if no_verify: + ok, out, err, code = git_service.commit_verbose( + commit_message, sign=sign, no_verify=True + ) + if not ok: + raise Exception(f"Failed to commit: {err or out or code}") + else: + git_service.commit_changes(commit_message, sign=sign) progress.update(task, completed=True) if push: diff --git a/devtools/shared/git.py b/devtools/shared/git.py index 51ed707..a2ba0e6 100644 --- a/devtools/shared/git.py +++ b/devtools/shared/git.py @@ -70,17 +70,19 @@ class GitService: files = self.get_staged_files() if staged else self.get_unstaged_files() return {file: self.get_diff(file, staged) for file in files} - def commit(self, message: str, sign: bool = False) -> bool: + def commit(self, message: str, sign: bool = False, no_verify: bool = False) -> bool: """Create a commit with the given message.""" args = ["commit"] if sign: args.append("-S") + if no_verify: + args.append("--no-verify") args.extend(["-m", message]) stdout, stderr, returncode = self._run_git_command(args) return returncode == 0 def commit_verbose( - self, message: str, sign: bool = False + self, message: str, sign: bool = False, no_verify: bool = False ) -> Tuple[bool, str, str, int]: """Create a commit and return success and raw outputs. @@ -90,10 +92,35 @@ class GitService: args = ["commit"] if sign: args.append("-S") + if no_verify: + args.append("--no-verify") args.extend(["-m", message]) stdout, stderr, returncode = self._run_git_command(args) return returncode == 0, stdout, stderr, returncode + def commit_paths_verbose( + self, + message: str, + files: List[str], + sign: bool = False, + no_verify: bool = False, + ) -> Tuple[bool, str, str, int]: + """Create a commit including only the specified files. + + Returns: + (ok, stdout, stderr, returncode) + """ + if not files: + return False, "", "no files specified", 1 + args = ["commit"] + if sign: + args.append("-S") + if no_verify: + args.append("--no-verify") + args.extend(["-m", message, "--"] + list(files)) + stdout, stderr, returncode = self._run_git_command(args) + return returncode == 0, stdout, stderr, returncode + def commit_paths_verbose( self, message: str, files: List[str], sign: bool = False ) -> Tuple[bool, str, str, int]: