cz-cli icon indicating copy to clipboard operation
cz-cli copied to clipboard

How to husky prepare-commit-msg on windows?

Open creaux opened this issue 5 years ago • 25 comments

Using husky it is very useful but script which is there is designed only for bash purpose.

"husky": {
  "hooks": {
    "prepare-commit-msg": "exec < /dev/tty && git cz --hook",
  }
}

What could be solution for Windows?

creaux avatar May 02 '19 10:05 creaux

I'm having the same issue. Can someone provide an easy workaround for this ?

silltho avatar May 17 '19 14:05 silltho

Error message on windows is The system cannot find the path specified.

What is the possible workaround for Windows?

iyeldinov avatar Jun 06 '19 08:06 iyeldinov

same issue.

a294465800 avatar Jun 08 '19 04:06 a294465800

I got the error on windows:

husky > prepare-commit-msg hook failed (cannot be bypassed with --no-verify due to Git specs)

fancyboynet avatar Aug 12 '19 05:08 fancyboynet

I developed this feature for people using bash (which works for MacOS + Linux). I'm not sure how to perform the same effect using windows.

My sense is that there needs to be an additional check in the prepare-commit-msg hook on whether exec < dev/tty works, and if not assume windows and get the same behavior using native cmd commands.

I do not use windows, and so this would be difficult for me to get working (but not impossible, added to my task list). If any of y'all figure out a workaround in the meantime, please post here and / or submit a pr to this repo.

olgn avatar Aug 22 '19 18:08 olgn

This thread here suggests using file.open('CON') or file.open('CON:') as an alternative.

olgn avatar Aug 22 '19 18:08 olgn

@olgn - Can we perhaps get more information around this. I've been using WSL for Windows as a workaround but realistically my whole team is running windows It would be nice to have a solution to this,

sadsa avatar Sep 09 '19 02:09 sadsa

@sadsa I'll give it a shot.

As you know (because you had to follow the instructions in the README), the method of enforcement for commitizen commit messages uses Husky. Husky pre-commit hooks are tied into the corresponding your-commitizen-enforced-repo/.git/hooks/<hook_name>.sh file when you run yarn / npm install. This means that husky writes the content exec < /dev/tty && git-cz --hook into the `.git/hooks/prepare-commit-msg' hook script.

The git-cz --hook command should look familiar. It's just running commitizen. The --hook option essentially takes the commit message that commitizen creates and then writes it directly to the your-commitizen-enforced-repo/.git/COMMIT_EDITMSG file. This is the file from which the commit message is read. If you run git commit -m "foo", and then open the COMMIT_EDITMSG file, the content is 'foo'.

The bit of code right before the git-cz --hook command, however, is a bit less obvious. It is necessary because we need to bind the stdin of the user to the git-cz --hook command that is being run from within the prepare-commit-msg hook script. There is a thread about how to get husky hooks to be interactive if you care to read. FWIW husky stopped supporting the interactive flag for the very reason you are experiencing - namely that it did not work on windows.

So my previous comment holds - if someone here can figure out how to replicate the behavior of exec < dev/tty on Windows, you get a gold star (and a high-five from me) and both Husky and cz-cli (in --hook mode) can support Windows. My previous comment also outlines a couple things you could try. If I had the time or the Windows machine I would totally do it because such an important + tricky contribution to Husky would be awesome.

Let me know if any of that could use clarification.

olgn avatar Sep 11 '19 23:09 olgn

Hi,

I've found something that works on my windows 10, with pure batch (bat) scripts (so it does not require bash or git bash)

precommit-msg

In my package.json:

{
  "husky": {
    "hooks": {
      "prepare-commit-msg": "prepare-commit-msg",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

I have created two bat files at the root of my repo:

  1. prepare-commit-msg.cmd
@ECHO off
SETLOCAL

CALL :find_dp0
set "_prog=%dp0%exec-git-cz.cmd"
IF NOT EXIST "%_prog%" (
    ECHO "%_prog% does not exist"
    ENDLOCAL
    EXIT /b 1
)
start /wait call "%_prog%" --hook %*)

:find_dp0
SET dp0=%~dp0
EXIT /b
  1. exec-git-cz.cmd
@ECHO off
SETLOCAL

CALL :find_dp0
set "_prog=%dp0%node_modules\.bin\git-cz.cmd"
IF NOT EXIST "%_prog%" (
    ECHO "%_prog% does not exist, please install commitizen"
    ENDLOCAL
    EXIT /b 1
)

call "%_prog%" %*

ENDLOCAL
EXIT %errorlevel%

:find_dp0
SET dp0=%~dp0
EXIT /b

neilime avatar Oct 31 '19 11:10 neilime

@neilime interesting solution. The next obvious step would be to make one command (to place in the prepare-commit-msg hook) that does the following:

  • check if the person running git commit is using windows (maybe check if /dev/tty exists?)
    • if windows, run the scripts you just posted
    • else, run the /dev/tty code that is currently implemented in the docs

that way the prepare-commit-msg command is the same for every user that installs a commitizen enforced repo, and they can all enjoy the benefits of commitizen

olgn avatar Nov 02 '19 18:11 olgn

@neilime, Although your trick works, I seem to be running into the following issue where the up and down arrow keys causes this very annoying duplication effect. I'm on Windows 7 Enterprise, Git version 2.24.0.windows.2
commitizen

shardool avatar Nov 08 '19 02:11 shardool

@shardool I'm on Windows 10 Pro (Insider Preview) - Node v13.0.1 - 2.24.0.windows.1 - and don't have any troubles

The issue you're facing, is maybe due to Inquirer.js: https://github.com/SBoudrias/Inquirer.js/issues/778

Try to upgrade your nodejs to fix it.

neilime avatar Nov 08 '19 09:11 neilime

@neilime I'm on node version v12.13.0. I tried older version too.

shardool avatar Nov 09 '19 00:11 shardool

The next obvious step would be to make one command

@olgn What about providing the feature out of the box by cz-cli?

jjangga0214 avatar Dec 10 '19 07:12 jjangga0214

i found this works on wsl

image

nico1988 avatar Dec 12 '19 03:12 nico1988

Any solutions to the duplication bug (https://github.com/commitizen/cz-cli/issues/627#issuecomment-551356945)? I am on the latest Windows 10 Update / NodeJS LTS version. Tried some older versions as well, same issue. Again, this only happens when running git-cz as a hook.

AlexanderOpran avatar Feb 23 '20 18:02 AlexanderOpran

I now have access to a windows computer to test this out and work on a solution.

First observations are that this works with both WSL (as @sadsa and @nico1988 pointed out) and also that it works with Git-Bash - presumably because they are bash shells. So one way to get commitizen to work is to commit using either of those two programs... I think Git-Bash is supported on windows 7-10, and WSL is 10 only (could be wrong there).

My next observation is that, although the output of my terminal looks very similar to @shardool, (eg duplicating with every keystroke), there is no error code - this command works (albeit it looks terrible). It has the same behavior in powershell and cmd.

Can someone who got an error running this tell me what version of windows, what shell, and more detailed error trace?

olgn avatar Feb 27 '20 17:02 olgn

I've made the fix for me runnig js script-file in prepare-commit-msg phase and in this file I check user's system and trigger exec < dev/tty.... or that two files for Windows But I think that's not a good decision. Awaiting for a fix from @olgn =)

mihanizm56 avatar Mar 01 '20 19:03 mihanizm56

@olgn I can confirm @shardool's bug on Windows 10 Pro, with Node v12.14.1, in both git bash and command prompt. If it helps, when running the hook there is no color, in contrast to running git cz.

binyamin avatar Mar 19 '20 15:03 binyamin

Same here as @b3u and @shardool.

rdgomt avatar Apr 11 '20 23:04 rdgomt

@neilime

Hi, When I try the same thing I get error.

husky > prepare-commit-msg (node v10.16.3)
sh: prepare-commit-msg: command not found
husky > prepare-commit-msg hook failed (cannot be bypassed with --no-verify due to Git specs

got it working by doing :

"prepare-commit-msg": "./prepare-commit-msg.cmd",

swapnil0545 avatar Apr 27 '20 06:04 swapnil0545

I got this "working" on windows by adding [[ "$(uname -a)" = *"MINGW64"* ]] && exit 0 to the second line:

#!/bin/sh
[[ "$(uname -a)" = *"MINGW64"* ]] && exit 0
[ -n "$CI" ] && exit 0
. "$(dirname "$0")/_/husky.sh"
exec < /dev/tty && npm run cz -- --hook || true

this will just bypass that file on windows and you can still use the "select the type of change" cli interface.

If you are using cygwin or some funky 32bit windows you might need to tweak it https://stackoverflow.com/questions/3466166/how-to-check-if-running-in-cygwin-mac-or-linux has a list of possible values

Primajin avatar Jun 17 '21 07:06 Primajin

@shardool @olgn were you able to find any solution to the duplication problem with every keystroke? I have this problem for a long time

renatoam avatar Sep 30 '21 16:09 renatoam

I'm not sure I fully understand what husky and cz must do with git hooks and whether this workaround is legit, but it works for me on windows to skip husky hook altogether, while using git cz interactive shell.

#!/usr/bin/env sh
case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*) exit 0;;
esac
. "$(dirname -- "$0")/_/husky.sh"

exec < /dev/tty && git cz --hook || true

The check is for all windows terminals (cygwin, minigw and powershell/cmd)

I guess husky hook is there for forcing git cz when doing git commit command? (in that case, it will obviously just skip)

But this removes errors at least for me, so that I can use interactive shell for commiting on windows.

armpogart avatar May 19 '22 19:05 armpogart

Here is a workaround that I am doing: In the pre-commit script, I added logic that detects if we're on windows then it just spawns new cmd & run npx cz

#!/usr/bin/env sh
#// if we hve a cmd that is rinning npx cz that means finalize and commit
FILE=commit.cmd
if test -f "$FILE"; then
    echo "$FILE exists."
    rm commit.cmd
    exit 0;
fi
#// if on Windows, spwan a cmd that will run npx cz
case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*)
        echo "npx cz && exit" > commit.cmd
        start commit.cmd
    exit 1;;
esac
. "$(dirname "$0")/_/husky.sh"
exec < /dev/tty && npx cz

umer2001 avatar Sep 02 '22 01:09 umer2001