Search code examples
windowsgitfilenamesgit-add

Can't use git add with --patch option


I recently updated Git to version 2.7.2.windows.1 (I am running Windows 7 64-bit). Since the update, I have been unable to run git add with the -p option on files within a certain directory (or its subdirectories) whose name is _ (an underscore).

git status correctly reports that my file has changes:

PS C:\Users\Carl\www\dl> git status
On branch develop
Your branch is up-to-date with 'origin/develop'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   _/php/class.Menu.php

And I can add the entire file with a simple git add, or by specifying the file by name. But if I try to include the -p or --patch option (both variations produce the same results), Git reports that there are no changes:

PS C:\Users\Carl\www\dl> git add -p .\_\php\class.Menu.php
No changes.

This only happens for files within the _ directory, but it doesn't matter whether I cd into that directory to run the git add command without having to explicitly specify a path with an underscore in it; it still doesn't work:

PS C:\Users\Carl\www\dl\_\php> git add -p .\class.Menu.php
No changes.

I had initially thought this problem was related to a similar one I encountered recently on files within the _ directory, which I asked about here. However, that problem appears to have been related to Posix path conversion in MinGW, whereas this problem occurs whether I use Git Bash, Windows PowerShell, or cmd.exe.

As I said in that previous question, I believe underscores to be valid in file/directory names. Additionally, I am not the owner of the project so I cannot rename the directory or move the file.

Is this a bug in Git? Are there any additional steps I can take to determine what the underlying issue is?


Solution

  • Well, I was able to reproduce this, and seems that it is the same POSIX-to-Windows path conversion. ProcessMonitor shows that git (actually, perl run by git) looks for a file C:\Program Files\Git\php\class.Menu.php.

    To work this around (at least, that worked for me), according to documentation, you can set the environment variable MSYS_NO_PATHCONV temporarily, like so (in git bash):

    MSYS_NO_PATHCONV=1 git add -p _/php/class.Menu.php
    

    (I don't know how to set env variables in windows' cmd/powershell, but that should be possible, too.)

    You shouldn't enable MSYS_NO_PATHCONV globally/permanently (e.g. using export in git bash or modifying windows' user/system environment variables in system settings), because that can lead to unwanted effects, and it'll probably break much more things than it'll fix (see this SO comment). Actually, git-windows folks warn against even temporary enabling MSYS_NO_PATHCONV.
    Having said that, I'm starting to think that OP's problem is a git-for-windows bug and should be reported as such (might have something to do with the fact that git-add is a binary, but git-add--interactive is a perl script).

    Another listed workaround is to double the first slash, like git add -p _//php/class.Menu.php (or does that mean the parameter must start with a double slash?), but that doesn't seem to work due to complex intermediate path conversions, that happen between the invocation of git add and the real file access.