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

sds / overcommit / 38794875984
92%
master: 91%

Build:
Build:
LAST BUILD BRANCH: main
DEFAULT BRANCH: master
Ran 15 Oct 2026 07:34PM UTC
Jobs 8
Files 223
Run time 1min
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

15 Oct 2026 07:33PM UTC coverage: 92.064% (+0.09%) from 91.971%
38794875984

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)

3318 of 3604 relevant lines covered (92.06%)

3261.04 hits per line

Jobs
ID Job ID Ran Files Coverage
1 ruby3.2-ubuntu - 38794875984.1 15 Oct 2026 07:35PM UTC 446
91.97
GitHub Action Run
2 ruby3.3-ubuntu - 38794875984.2 15 Oct 2026 07:34PM UTC 446
92.02
GitHub Action Run
3 ruby3.4-ubuntu - 38794875984.3 15 Oct 2026 07:35PM UTC 446
92.03
GitHub Action Run
4 ruby2.6-ubuntu - 38794875984.4 15 Oct 2026 07:35PM UTC 446
92.0
GitHub Action Run
5 ruby3.1-ubuntu - 38794875984.5 15 Oct 2026 07:35PM UTC 446
91.97
GitHub Action Run
6 ruby2.7-ubuntu - 38794875984.6 15 Oct 2026 07:35PM UTC 446
92.0
GitHub Action Run
7 ruby4.0-ubuntu - 38794875984.7 15 Oct 2026 07:35PM UTC 446
92.03
GitHub Action Run
8 ruby3.0-ubuntu - 38794875984.8 15 Oct 2026 07:34PM UTC 446
92.0
GitHub Action Run
Source Files on build 38794875984
  • Tree
  • List 223
  • Changed 222
  • Source Changed 2
  • Coverage Changed 222
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #38794875984
  • 55ea3fd1 on github
  • Prev Build on main (#38794808497)
  • Next Build on main (#39681836450)
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