• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apiology / overcommit / 39383859468

Build:
Build:
LAST BUILD BRANCH: store-signatures-per-worktree
DEFAULT BRANCH: master
Ran 20 Oct 2026 07:03AM UTC
Jobs 0
Files 0
Run time –
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

pending completion
  cancel
39383859468

push

github

web-flow
Stop wrapping commands in cmd.exe on Windows (#898)

An attempt at Issue #847. This isn't a corner case: `pre-commit` and
`commit-msg` hooks both stash unstaged changes before running hooks, by
default, so any Windows user doing a partial commit (staging some but
not all changes) hits this — hooks fail outright with `error: unknown
switch '0'` instead of running at all.

I [commented on the
issue](https://github.com/sds/overcommit/issues/847#issuecomment-5006876753)
a couple of months ago; I've since tested this fix end to end on Windows
11 / Ruby 3.3, and while the suggestion still looks right, my
description of the cause back then was off. Here's what I think is
actually going on.


## The problem

`win32_prepare_args` escapes metacharacters per argument, then joins
everything into one string behind `cmd.exe /c`:

```ruby
%w[cmd.exe /c] + [args.join(' ')]
```

The escaping doesn't seem to be what breaks; the join is. It collapses
the command into a single argv element, and childprocess 5.x on Windows
is a thin shim over `Process.spawn`, which sees the embedded spaces,
wraps the element in quotes, and backslash-escapes the quotes already
inside it. cmd.exe strips the outer pair, and the child's C runtime then
reads the surviving `\"` as a literal quote rather than a delimiter — so
the argument re-splits on whitespace.

With the pre-commit stash message (`Overcommit: Stash of repo state
before hook run at 2024-04-10 12:34:56 -0700`), `git stash save`
receives the UTC offset as a switch of its own and aborts with `error:
unknown switch '0'`. On a throwaway repo I get exit 129 with that
message on `main`, and exit 0 with the message intact on this branch.

I couldn't find an escaping scheme that fixes this while keeping the
wrapper: inside double quotes `& | < > ( )` are already literal, `%VAR%`
still expands and can't be caret-escaped, and carets inside quotes reach
the child as literal carets.

## The change

Drop the wrapper and hand the argument vec... (continued)
Source Files on build 39383859468
Detailed source file information is not available for this build.
  • Back to Repo
  • Github Actions Build #39383859468
  • 55ea3fd1 on github
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc