I am using zsh shell and prezto with cygwin. When I type this git command:
git reset HEAD5
zsh returns:
zsh: no matches found: HEAD^
But when I switch to use bash shell, it works.
Why does zsh throw an error when I try to use HEAD^
?
I am using zsh shell and prezto with cygwin. When I type this git command:
git reset HEAD5
zsh returns:
zsh: no matches found: HEAD^
But when I switch to use bash shell, it works.
Why does zsh throw an error when I try to use HEAD^
?
The ^
character is treated as special in filename expansions in zsh, but only if the EXTENDED_GLOB
option is set:
zsh% setopt noEXTENDED_GLOB
zsh% echo HEAD^
HEAD^
zsh% setopt EXTENDED_GLOB
zsh% echo HEAD^
zsh: no matches found: HEAD^
zsh%
Bash doesn't have this feature. (To be precise, bash does have an extended glob feature, enabled by shopt -s extglob
, but bash's extended glob syntax doesn't treat the ^
character as special.)
With this feature enabled, ^
is a special character similar to *
but with a different meaning. Like *
, you can inhibit its special meaning by escaping it, either by enclosing it in single or double quotes or by preceding it with a backslash. Quoting is the simplest solution.
Rather than
git reset HEAD^
try this:
git reset 'HEAD^'
The meaning of the ^
wildcard is not relevant, since all you need to do is avoid using it, but I'll mention it anyway. According to the zsh manual, ^X
matches anything except the pattern X
. For the case of HEAD^
, nothing follows the ^
-- which means that HEAD^
matches HEAD
followed by anything other than nothing. That's a roundabout way of saying that HEAD^
matches file names starting with HEAD
and followed by some non-empty string. Given files HEAD
, HEAD1
, and HEAD2
, the pattern HEAD^
matches HEAD1
and HEAD2
.
A quick workaround to avoid the ^
character is to use git reset head~1
instead of git reset head^
.
issue 449 of oh-my-zsh describes this exact behaviour and provides the solution.
The culprit is the option extended_glob
on zsh. Presto must be setting it. So when you type HEAD^
zsh tries to create a glob negation expression and fails with an error.
In other words, setopt extended_glob
allows us to use ^
to negate globs.
To fix it, you can write this line on your .zshrc
:
unsetopt nomatch
With the above line, we are saying to zsh we want that when pattern matching fails, simply use the command "as is".
nomatch
just to avoid this error. This will have knock-on behaviour for all other shell code that the user might not want or expect. It's probably better to quote the string git reset "HEAD^"
, escape the character git reset HEAD\^
or use a tilde if it's appropriate git reset HEAD~1
–
Tepper #!/usr/bin/env zsh -f
and I'm not sure that using #!/usr/bin/env zsh
makes the script pick up configuration from ~/.zshrc
. If it does that could be a problem. And even then the script should set it's own options just to be sure. It should not be dependent on users specific configurations. –
Stoddart var=(*.fooext)
with nomatch
unset will not produce an error if the glob match fails, it will instead create a string called "*.fooext" in the var
array. And that might not be what you expect. Then again, these might just be edge cases, and I guess it's up to the user to decide for themselves the system they want... –
Tepper sh
and ksh
don't default to abort on glob mismatch from the zsh docs, so I think most script tend to target sh
compatibility maybe? –
Womb On Mac escape the ^ in your command:
git reset --soft HEAD\^
© 2022 - 2024 — McMap. All rights reserved.