git.cmd eats ^, introducing incompatibility #36
Comments
@kohsuke wow. You are not only "a developer" of Jenkins. You are the inventor. I use Jenkins every single day and love it. Thanks! I'll see tomorrow what I can do for you! |
It's not git.cmd that eats the caret -- this is used by Windows command prompt as an escape character. See http://msdn.microsoft.com/en-us/library/kcc7tke7.aspx (section Escape characters). Here is an example:
|
This SO post sums up quite nicely what the problem is: "The reason for this is that the shell special characters While we can fix the second issue using delayed expansion inside of the batch file (see the top voted answer on SO), that would not get us around the need to quote the arguments on the command line in the call to git.cmd. The top answer also suggests another approach that is supposed to work around the quoting need, but it is rather complex and involves writing to a temporary file. |
@patthoyts @sschuberth how about working the other angle? I.e. getting rid of git.cmd altogether? All it does is to set a couple of environment variables and make sure that the codepage is set, and that git gui is started with wish.exe. We should be able to do all that in Windows-specific startup code. The bigger problem would be to get this to users in a backwards-compatible manner, as nobody except @sschuberth reads release notes ;-) |
I was also thinking about replacing git.cmd / gitk.cmd with native executables. This would be the cleanest solution IMHO, but also the one involving the most work. |
I thought about this but I don't think its going to help much. Currently if you want to do "git log HEAD^" you have to give two carets because the command shell has taken the first to use as a quote. This will not change if we make a git exe wrapper for the cmd\ folder -- the command shell is still going to perform some command line handling and eat the caret. The only advantage I can see would be to make it simple in calling from other batch scripts where we currently have to do 'call git args...' which might be nice. I suspect a little wrapper making use of mingw_spawnve_fd could be fairly simple to do. Here's a real quick check of the command line handling:
With just one caret, it asks "More?" which is the command shell escaping the newline at the end of the line |
@patthoyts You're right, adding a native executable wrapper would only get us around the escaping in the CMD file, not around the one done by CMD. So if we can only solve the one issue anyway, I'd vote for using delayed expansion inside of the batch file instead of the native wrapper, just for simplicity. @kohsuke To work around the CMD escaping issue, would it be OK for you to quote strings containing |
@sschuberth OK, I didn't realize that surrounding an arugment with a double-quote would prevent I still do recommend that I was careful in my experiments to differentiate the command prompt that someone might be using interactively vs I am not asking to eliminate The second comment from @patthoyts seems to argue that "it's not going to help much" because the user of an interactive command prompt would still have to do one escaping. With all due respect, I think that's missing the point. I'm not raising it an issue that the user of an interactive command prompt has to do the escaping (on that matter, even Unix users often have to escape interactive invocation of |
@dscho i lold when realized that this is exactly the problem why we have fiji and msysgit builds failing on Windows ;-) ... |
I can reproduce the double quoting issue and there seems to be a simple fix for the cmd script. If we do want to try for a compiled wrapper I uploaded an attempt that seems to work ok to https://gist.github.com/3002978 Showing the problem:
If we apply the following patch:
Then it avoids the requirement for double-quoting. The
|
@patthoyts Great stuff about the git.cmd patch! So my understanding is that with your patched git.cmd also this should work:
Is that correct? |
Sigh. No. :( |
I've tried a few more versions with Enable/DisableDelayedExpansion in various forms. It seems I can have either quotes or caret quoting but not deal with both however I modify the cmd script. The However if we use the C code wrapper as a replacement (copied to cmd\git.exe) - no problem:
So unless anyone comes up with a bright idea for the script it looks like putting a wrapper exe in place as cmd\git.exe will be the way to sort this out. I think the wrapper is covering everything. 'git gui' launches detached, 'git gui citool' stays attached and the codepage handling is replicated along with the HOME environment setup. |
@patthoyts Well, now that you have the C-wrapper already done I'd say we should save our time thinking about a hack for git.cmd and simply use your git.exe! :-) |
I believe setting the code page is no longer necessary with Unicode support (git, tcl and all msys-progs (including bash and perl) use WriteConsoleW to write to the console, so the console code page has no effect). |
@patthoyts well done! Let's use your wrapper for now, how about putting it into /src/wrapper/? In the long run, we might want to think of merging this into compat/mingw.c's mingw_startup() function, no? @kblees I'd like to avoid conflating the move to a C-based wrapper with the removal of the code page setting. We could do that as a follow-up patch, but I am not sure whether our test suite would have any chance to catch any breakages that might be incurred by not setting the code page. So it'd need extensive manual testing. |
@patthoyts I merged your work into a topic branch, please see https://github.com/msysgit/msysgit/commits/git-wrapper; If you're okay with it, please merge into devel! |
heh - we collided somewhat - see pt/git-wrapper. If you copy the git.exe into your installed version (Program Files\Git\cmd) and remove/rename the .cmd script there it can get a good workout. I had some issue with 'git gui blame filename' which I've since fixed. The program does expect to be in either msysGit/cmd or the Git for Windows installed location (Git\cmd) as in each case it will look for ..\bin\git.exe and add ..\bin to the path. |
@patthoyts no sweat, it did not take me long (and your Makefile is much neater, anyway). I deleted my branch. |
This addresses github issue #36 which points out problems in handling git commit notations of the form tag^{commit} and HEAD^. The windows command shell uses caret as a quote both on the command line and in batch scripts and this results in requiring double quoting. To be able to handle both "tag^{commit}" and tag^^{commit} (either style of command prompt quoting) the script needs replacing. This also makes it simpler to call git from batch scripts as it will no longer need to be prefixed with 'call'. Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
@patthoyts do you want to leave this issue open until a new installer is released? |
git.cmd does "git.exe %@", which treats ^ in the argument as a special character. This processing breaks the command line interface compatibility with git.exe (or with git on Unix platforms.)
I'm a developer of Jenkins, a continuous integration server. At some point my program executes
git rev-parse sometag^{commit}
— if this findsgit.exe
(or other flavors of git, such as git from Cygwin), then this will work as expected. But if someone hasgit.cmd
from msysgit inPATH
beforegit.exe
, then cmd.exe will end up executinggit.exe rev-parse sometag{commit}
, which obviously doesn't work.If I change my git invocation to
git rev-parse sometag^^{commit}
then now it'll work withgit.cmd
, but it will not work whengit.exe
is found in PATH. And needless to say, this is incompatible with how I'd invoke git on Unix.I consider this to be a bug on msysgit. It shouldn't let cmd.exe process its arguments.
Unfortunately I don't have enough Windows-fu to be able to send in a patch, so I'm just filing this as an issue instead.
See JENKINS-13007 where this is biting us.
The text was updated successfully, but these errors were encountered: