git am doesn't work from windows command line when asterisk (*) is used in file name

1,327 views
Skip to first unread message

newbie

unread,
Dec 5, 2011, 9:29:44 AM12/5/11
to msysGit
Regression of msysgit Git-1.7.7.1-preview20111027 comparing to
Git-1.7.4-preview20110204

With git version 1.7.7.1.msysgit.0 the following command
git am --keep-cr --whitespace=nowarn c:\test\*.patch

fails with message "C:\Program Files (x86)\Git/libexec/git-core\git-
am: line 182: c:\test\*.patch: No such file or directory"

While with git version 1.7.4 that works as expected. The error happens
when the command is ran directly from cmd.exe. Workaround for 1.7.7 is
to run command via git bash:
git am --keep-cr --whitespace=nowarn /c/test/*.patch

However we use git from cmd.exe and we need that fixed. I can try help
if somebody tell me where to start. It looks like on line 246 of file
"C:\Program Files (x86)\Git/libexec/git-core\git-am"

} < "$1" || clean_abort

$1 is not expanded to a list of files and applied like a ready to use
file name. But this is more a wild guess than real understanding.

Please help.

Johannes Sixt

unread,
Dec 5, 2011, 3:28:16 PM12/5/11
to newbie, msysGit

Sigh! Oh, the joys of Windows file name (non-)globbing.

Try reverting this commit: 45cfa3506b (MinGW: disable CRT command line
globbing). Or (if it is easier for you) patch your git binary so that
the variable _CRT_glob is initialized to 1 instead of 0.

-- Hannes

Karsten Blees

unread,
Dec 22, 2011, 5:29:07 PM12/22/11
to msysGit, snn...@gmail.com, j...@kdbg.org
Cmd.exe doesn't support wildcard expansion, and reenabling this in the
git executable breaks git's builtin globbing functionality (globbing
on branch names, repository history, recursive globbing etc.).

To emulate wildcard expansion in cmd.exe, you could use the find and
xargs utilities that come with git, i.e.

find c:/test/*.patch | xargs git am --keep-cr --whitespace=nowarn

HTH
Karsten

Joshua Jensen

unread,
Dec 22, 2011, 6:08:59 PM12/22/11
to Karsten Blees, msysGit, snn...@gmail.com, j...@kdbg.org
----- Original Message -----
From: Karsten Blees
Date: 12/22/2011 3:29 PM
> On Dec 5, 9:28 pm, Johannes Sixt<j...@kdbg.org> wrote:
>> Am 05.12.2011 15:29, schrieb newbie:
>>> Regression of msysgit Git-1.7.7.1-preview20111027 comparing to
>>> Git-1.7.4-preview20110204
>>> With git version 1.7.7.1.msysgit.0 the following command
>>> git am --keep-cr --whitespace=nowarn c:\test\*.patch
>>> fails with message "C:\Program Files (x86)\Git/libexec/git-core\git-
>>> am: line 182: c:\test\*.patch: No such file or directory"
>> Sigh! Oh, the joys of Windows file name (non-)globbing. Try reverting
>> this commit: 45cfa3506b (MinGW: disable CRT command line globbing).
>> Or (if it is easier for you) patch your git binary so that the
>> variable _CRT_glob is initialized to 1 instead of 0. -- Hannes
> Cmd.exe doesn't support wildcard expansion, and reenabling this in the
> git executable breaks git's builtin globbing functionality (globbing
> on branch names, repository history, recursive globbing etc.).
>
> To emulate wildcard expansion in cmd.exe, you could use the find and
> xargs utilities that come with git, i.e.
>
> find c:/test/*.patch | xargs git am --keep-cr --whitespace=nowarn
>
I'm not sure what was just said here. I find the broken 'git am'
wildcard thing very annoying. Are you implying that this isn't going to
work unless we're running under Git Bash?

-Josh

Pat Thoyts

unread,
Dec 22, 2011, 7:03:18 PM12/22/11
to Joshua Jensen, Karsten Blees, msysGit, snn...@gmail.com, j...@kdbg.org

Thats the bash way. It will iterate over the .patch files and call
that command with all the expanded filenames appended.
You could do something similar using no bash commands with maybe and
batchfile like:
for /f %I in (%1) do git am --keep-cr --whitespace=nowarn "%~I"

The issue is that Windows programs receive the command line
differently to unix programs. On windows no expansion is done by the
shell before the command line is passed to the application. On unix,
the shell expands glob arguments like *.patch into a list of filenames
before running the program with the expanded command line arguments.
Obviously this can be fixed - but doing so breaks other things so
someone always looses out. If you want, you could make a shell script
called git-amx and put it on your PATH that simply includes the line
above as below and it will be callable as 'git amx *.patch'

#!/bin/sh


find c:/test/*.patch | xargs git am --keep-cr --whitespace=nowarn

It's quite easy to add new commands to git like this (or as aliases too).

karste...@dcon.de

unread,
Dec 22, 2011, 10:20:43 PM12/22/11
to Joshua Jensen, Karsten Blees, j...@kdbg.org, msysGit, snn...@gmail.com
The documentation for git-am states that it takes a list of mbox files or Maildir directories, not a word about wildcards. If the shell doesn't process wildcards (i.e. cmd.exe or bash with globbing turned off), there's no reason to believe that 'git am *.patch' should work.

Many git commands already have pattern matching capabilities built in. For the few that don't, IMO 'find <pattern> | xargs ...' is a viable alternative to overcome cmd.exe's limitations. If you don't like find, you can of course also use dir /b or the glob.exe utility you published on codeproject. This is much more powerful and flexible than the dumb current-directory-only wildcard expansion that was enabled in previous msysgit versions.

karste...@dcon.de

unread,
Dec 22, 2011, 10:30:40 PM12/22/11
to Pat Thoyts, Karsten Blees, j...@kdbg.org, Joshua Jensen, msysGit, snn...@gmail.com

Pat Thoyts <patt...@gmail.com> wrote on 23.12.2011 01:03:18:
[...]

> You could do something similar using no bash commands with maybe and
> batchfile like:
>  for /f %I in (%1) do git am --keep-cr --whitespace=nowarn "%~I"
>


This would call 'git am' once per patch file, and wouldn't stop if a patch fails to apply. If you want to go pure cmd.exe syntax, you'd have to concat the file names by hand prior to calling 'git am', something like:

----
@echo off
set FILES=
for %%i in (%1) do call :addfile "%%~i"
git am --keep-cr --whitespace=nowarn %FILES%
goto :eof

:addfile
  set FILES=%FILES% %1
  goto :eof
----

[...]

> It's quite easy to add new commands to git like this (or as aliases too).

...e.g. like so in ~/.gitconfig:
[alias]
  amx=!sh -c 'find $1 | xargs git am --keep-cr --whitespace=nowarn' -
Reply all
Reply to author
Forward
0 new messages