From 3dc95c4d941f75f0d5fffe59943ac53c752ec28e Mon Sep 17 00:00:00 2001 From: kig777 Date: Sat, 8 Aug 2026 05:41:47 +0300 Subject: [PATCH 1/2] fix(hooks): make post-edit-format actually format on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `dotnet format --include` resolves its paths against the current directory, so the absolute path the hook passes matches no file. The command still exits 0, and `2>/dev/null || true` swallows the outcome, so the hook has been a silent no-op — edited files are never formatted and nothing reports it. On Git Bash there is a second, independent cause: the script normalizes the edited path to the mixed C:/... form for its directory walk and then hands that same form to dotnet as the project argument. dotnet loads the project fine, but --include then matches nothing even when the include path is correct. The project argument has to be a native Windows path. Fix both: convert the project with `cygpath -w` when cygpath is present, and make --include relative to the current directory when the file lives under it. Paths outside the current directory keep their previous form, and on Linux and macOS the project argument is untouched. Verified against a real solution on Windows 11 / Git Bash by introducing an indentation violation and checking `git status` after the hook ran — before the change the violation survived, after it the file comes back formatted. Covered all three input paths the hook accepts: PostToolUse stdin JSON, `$1` with a backslash path, and `$1` with a relative path. --- hooks/post-edit-format.sh | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hooks/post-edit-format.sh b/hooks/post-edit-format.sh index 21b3f70..7d874d8 100644 --- a/hooks/post-edit-format.sh +++ b/hooks/post-edit-format.sh @@ -71,7 +71,22 @@ while [[ "$DIR" != "/" && "$DIR" != "." ]]; do done if [[ -n "$PROJECT" ]]; then - dotnet format "$PROJECT" --include "$FILE" --no-restore 2>/dev/null || true + # `dotnet format --include` takes paths relative to the current directory; + # an absolute path matches no file. The project argument in turn must be a + # native path — the C:/... form this script builds for the directory walk + # also makes --include match nothing. Either mistake formats nothing and + # still exits 0, which `2>/dev/null || true` then hides. + CWD=$(pwd) + if command -v cygpath >/dev/null 2>&1; then + # Git Bash: pwd is /c/..., while FILE was normalized above to C:/... + CWD=$(cygpath -m "$CWD" 2>/dev/null || echo "$CWD") + PROJECT=$(cygpath -w "$PROJECT" 2>/dev/null || echo "$PROJECT") + fi + INCLUDE="$FILE" + case "$FILE" in + "$CWD"/*) INCLUDE="${FILE#"$CWD"/}" ;; + esac + dotnet format "$PROJECT" --include "$INCLUDE" --no-restore 2>/dev/null || true else echo "No .csproj or .sln found for $FILE, skipping format" fi From 28c8cfc3ab34427de2befa3156a7e2c5e3e66624 Mon Sep 17 00:00:00 2001 From: kig777 Date: Sat, 8 Aug 2026 05:45:34 +0300 Subject: [PATCH 2/2] fix(hooks): report a failed dotnet format instead of discarding it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `2>/dev/null || true` discarded both the error stream and the exit code, so a broken invocation looked exactly like a successful one. That is what kept the --include path bug invisible: the hook had been formatting nothing, and there was no signal anywhere to say so. Capture the output and print it when dotnet format exits non-zero. Still exit 0 — files mid-edit routinely fail to compile, and a hook that failed there would interrupt an ordinary edit for something the next edit fixes. Output is printed only on failure, so a successful format stays quiet: dotnet format prints nothing on success at default verbosity, and it exits 0 for soft problems such as workspace load warnings, which would otherwise add noise to every single edit. --- hooks/post-edit-format.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hooks/post-edit-format.sh b/hooks/post-edit-format.sh index 7d874d8..34c49e8 100644 --- a/hooks/post-edit-format.sh +++ b/hooks/post-edit-format.sh @@ -86,7 +86,13 @@ if [[ -n "$PROJECT" ]]; then case "$FILE" in "$CWD"/*) INCLUDE="${FILE#"$CWD"/}" ;; esac - dotnet format "$PROJECT" --include "$INCLUDE" --no-restore 2>/dev/null || true + # Report a failed format instead of discarding it — that is what kept the + # path bug above invisible. Still exit 0: mid-edit files routinely fail to + # compile, and a hook that fails there would interrupt an ordinary edit. + if ! FORMAT_OUTPUT=$(dotnet format "$PROJECT" --include "$INCLUDE" --no-restore 2>&1); then + echo "post-edit-format: dotnet format failed for $INCLUDE (file left unformatted)" + echo "$FORMAT_OUTPUT" + fi else echo "No .csproj or .sln found for $FILE, skipping format" fi