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

cz commit with prepare-commit-msg hook #249

Closed
saygox opened this issue Aug 14, 2020 · 12 comments
Closed

cz commit with prepare-commit-msg hook #249

saygox opened this issue Aug 14, 2020 · 12 comments

Comments

@saygox
Copy link

saygox commented Aug 14, 2020

Description

cz commit is very good tool.
If prepare-commit-msg hook calls cz commit, become easy to commit by many user.

Possible Solution

like cz check, writing pre-commit config

---
repos:
- hooks:
  - id: commitizen-prepare-commit-msg
    stages: [prepare-commit-msg]

and user type git comit, then prepare-commit-msg hook works and invokes cz commit.

Is this feature accepted as this product policy?

Additional context

I did a basic research. And I found that there are two issues.

  • The current cz commit calls git. But in this case, git calls cz commit
  • Git hook is started without standard input, so we can't create commit message interactively

I made a test implementation to solve the problem by the following method

  • When called from git, write the commit message to the file which is set by "--commit-msg-file" argument
  • Open tty manualy and use as stdio.

but this change has sideffect.

tty is manually opened as io.FileIO.
But prompt_toolkit (which used by questionary) assumes tty is opened as io.TextIOWrapper.
As a workaround I added wrap class

class WrapStdin:
    def __init__(self):
        fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
        tty = open(fd, "wb+", buffering=0)
        self.tty = tty

    def __getattr__(self, key):
        if key == "encoding":
            return "UTF-8"
        return getattr(self.tty, key)

    def __del__(self):
        self.tty.close()

All patch code is here.
saygox@033159d

@saygox saygox added the type: feature A new enhacement proposal label Aug 14, 2020
@Lee-W
Copy link
Member

Lee-W commented Aug 14, 2020

I love this new feature! I never thought we could use git hook like this. One problem I can think of is the compatibility for windows users. We might make some more tests before we can accept it. @woile What do you think?

@woile
Copy link
Member

woile commented Aug 14, 2020

Quite interesting indeed, please open a PR so we can discuss it there!

@Lee-W
Copy link
Member

Lee-W commented Sep 25, 2021

Although we have a PR #250, I'm not able to reproduce the result. Might need some help from one with linux machine

@mrlubos
Copy link

mrlubos commented Dec 10, 2021

Hi @Lee-W, is there any update on this? Would love to automatically replace git commit with cz commit the same way I am able to in npm projects!

@Lee-W
Copy link
Member

Lee-W commented Dec 11, 2021

Hi @mrlubos , @saygox is working on that and is almost done. But we encounter this issue and might need some time to tackle it. Would love to hear your thought if you have an idea on how this could be solved

@mrlubos
Copy link

mrlubos commented Dec 13, 2021

Awesome @Lee-W! Admittedly, I am not very familiar with the Python ecosystem, but I wonder if you're able to solve this similarly to how npm packages handle it? https://github.com/commitizen/cz-cli

@Lee-W
Copy link
Member

Lee-W commented Dec 14, 2021

@mrlubos Thanks for your sharing! In fact, part of the code I contribute is inspired by theirs. Wondering would it be possible for you to point out what might be the modules that I need to take a look at in that project? I must admit I'm not super familiar with JS. With your help, I believe we can solve this issue much faster.

@mrlubos
Copy link

mrlubos commented Dec 14, 2021

@Lee-W Let's try!

It appears to me that we're not actually looking to replace git commit, but add a prepare-commit-msg hook.

The way it works in npm with husky (npm equivalent of pre-commit) is you need to create a prepare-commit-msg hook which is a shell file that looks like this

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

if [ -n "$CI" ]; then
  yarn git-cz --hook || true;
else
  exec < /dev/tty && yarn git-cz --hook || true;
fi

When I run git commit, this hook gets executed which is what actually triggers commitizen. All it does is run git-cz with the --hook flag. If we're in CI mode, we skip the interactive console as it doesn't make sense to wait for user input, otherwise we use the interactive mode. The interactive mode shows the same menu as running cz c in this project.

Based on the commitizen CLI docs, git-cz is just an alias for cz. The next step is looking at what git-cz does, which can be found in the git-cz.js file.

As it turns out, the git-cz file only decides whether to use commitizen or fallback to default Git CLI. It decides that based on whether it found any config. If not, it uses the Git strategy which is just executing the regular git commit command.

The important part of this hook can be found in the git-cz.js strategy file. I think you already have similar functionality in this repository, maybe commit.py is the equivalent in this project?


In summary, I understand that we want to add a prepare-commit-msg hook that calls our CLI in interactive mode unless in CI. The user creates a commit formatted according to the config and this string gets passed to the git commit command which gets called by our CLI.

Let me know if you want me to dig into anything else in that repository!

@Lee-W
Copy link
Member

Lee-W commented Dec 15, 2021

@mrlubos Thanks for the summary! It's super helpful. I'll take a deeper look and see how I can fix it when I have time 💪

@woile
Copy link
Member

woile commented Apr 28, 2023

Any update on this feature or is there no longer interest?

@Lee-W
Copy link
Member

Lee-W commented May 6, 2023

I've not yet had the time to get back to it. The last time I tested on my local machine. It failed.

@Lee-W
Copy link
Member

Lee-W commented Jan 30, 2025

Close as #731 was merged

@Lee-W Lee-W closed this as completed Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants