I'm running Windows 7, and I have the latest version of git (2.7.2.windows.1). I previously used Windows PowerShell as my terminal for git operations, with no issues. Recently, I decided to switch to Git Bash, but I'm having one major issue.
My project has a directory (within which are many subdirectories) whose name is simply an underscore. Whenever I try to run git diff on a file within that directory, I get the following error:
$ git diff _/css/templates/jquery.tag-editor.css
fatal: Invalid object name '_C'.
As far as I know, an underscore is a perfectly valid character in a file/directory name, and tab completion works fine within that directory, so I know the terminal can "see" inside it. Additionally, other contributors to the project, all of them running OSX, do not have this problem. And when I run a simple git diff, without specifying any single file, it works fine, and happily includes the diff for any changed files within the underscore directory. It also works if I cd into the underscore directory and run the git diff from there, so that the path I pass to it does not include the underscore.
What exactly is happening here to prevent me from running git diff on these files? And where does the "C" come from in the error message when I try to do so?
Update
When I run git checkout -- _/css/templates/jquery.tag-editor.css to discard the changes to that file, this is the error I see:
error: pathspec '_C:/Program Files/Git/css/templates/jquery.tag-editor.css' did not match any file(s) known to git.
C:\Program Files\Git is directory of my Git installation. So apparently part of the path is being interpreted as referring to the Git installation directory? Again, what is causing this to happen?
The problems you are experiencing are based on the Posix Path conversions of MinGW/Msys2.
on git-bash try to double a slash: git diff _//css/templates/jquery.tag-editor.css or use backslashes (which need to be escaped in git-bash): git diff _\\css\\templates\\jquery.tag-editor.css or prepend MSYS_NO_PATHCONV=1: MSYS_NO_PATHCONV=1 git diff _/css/templates/jquery.tag-editor.css
on CMD you should use a backslash instead of a slash: git diff _\css\templates\jquery.tag-editor.css OR double a slash as for git-bash
in order to prevent the conversion.
Related
This command works in git 2.30.0.windows.1 through the Windows 'command' shell.
git checkout [commit hash] -- */migrations/*
It doesn't work with Mate terminal or bash (git 2.17). The problem is that they substitute the present content of the directories */migrations/* (which are empty or don't have the files that were present at the commit I want to pull them from). Mate terminal does this whether I single or double quote.
If I invoke Bash and then, at the new command line, add single or double quotes, git says that it doesn't have any files literally called */migrations/*:
error: pathspec '*/migrations/*' did not match any files known to git
I can get the content of the migrations files if I substitute directories one at a time, but there are 20+ folders of migrations and I assume I have just missed a bit of lore about how to get what I want from a Linux terminal. Can anyone suggest what I ought to be doing?
This */migrations/* syntax is referring to nowhere path. Neither root nor current working directory.
Try these with ls command before checkout with git:
*migrations/*
./*migrations/*
$PWD/migrations/*
And if you got the right output with ls then apply it to git checkout ...
Test 1
ls */tmp/*
ls: cannot access '*/tmp/*': No such file or directory
Test 2
ls /tmp/*
it has output ...
it has output ...
We are forced to work on Windows at work, and I have lets say problem, strange situation. We have github repository, inside which we have one directory with name Something (with capitalized first letter 'S'), but in my local I see this directory with name something (note lower case 's'), git status shows that working directory is clean, even if I change this directory locally to, for example SoMeThInG git says that nothing changed. I suspect that Windows is here a problem, as it is case insensitive. Is there possibility to change this directory name from Windows level? Or maybe how to force git bash to be case sensitive?
Update
I've changed that files from mine virtual fedora, but this is just a workaround, the question remains unanswered, how to do it properly on Windows?
On case-insensitive file systems, Git will not detect changes just in casing. However, when committing files, the actual casing is still being reflected in the way it was added to the index.
So a git add file and git add FILE will both work for a file that is named file in any kind of casing (e.g. FiLe or fIlE), but each command will actually stage that exact name into the repository. So git add file will make the name be case-sensitive file and git add FILE will make the name case-sensitive FILE.
That’s why you should try to always use your command line auto completion for file names, so you don’t accidentally add files with a different casing than they actually are. Or use commands that stage the files automatically, e.g. git add ., since that will also use the actual casing.
However, since Git will not detect casing changes, once a file has been added with a particular casing, that casing will be used until you explicitly change it. That’s why it’s possible to have files in a folder src/readme.md and SRC/license.txt that are both physically in the same location on your file system, but are represented using incompatible paths inside of Git. So you should be careful here.
That all being said, you can fix the casing later. But to do that, you need to make the change using Git instead of the file system, as Git is case sensitive while the file system isn’t. So commands like git mv will work. Same as a combination of git rm --cached and git add.
For example, to fix the above situation of the src/SRC directory, one could do (assuming the correct name of the folder should be Src):
git mv src/readme.md Src/readme.md
# or
git rm --cached SRC/license.txt
git add Src/license.txt
You can also fix the casing for every file by removing everything from the index, and then adding it back:
git rm --cached -r .
git add .
That should stage all renames to the correct file casing.
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?
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.
I'd try without that .. Also I've never passed a filename to git add -p. I just make my change and run that as is. I would also check to make sure any changes you're making are in fact being applied to that specific file, and the file is being touched.
Using git svn fetch to do some local work (using git personally), I got a file that will not "reset". I see that it's different from similar files in the same directory in that it has a backslash as part of the name: icon#2xios8\.png. I suppose the backslash doesn't do anything on other platforms but msysgit on Windows 10 complains that it's unable to create the file.
I can't figure out how to make git ignore this subdirectory and let me continue with unrelated work. But I really need to fix it somehow so git can be used.
You can do this with git-read-tree and sparse checkout (git-read-tree).
Therefore you call
git config core.sparsecheckout true
Then create a file .git/info/sparse-checkout (with touch .git/info/sparse-checkout in msysgit bash). Edit this file and change its content to:
/*
!icon#2xios8\\.png
This tells git to look at all files in your working directory (/*) but '!icon#2xios8.png' (!icon#2xios8\\.png). Notice the escaped backslash here (\\)!
After you run git read-tree -mu HEAD you should be able to pull your repository by ignoring that specific file.
I'm using git on windows with the git bash and every time I want to autocomplete a filename in a git command I get fatal: Not a git repository: '.git' posted between my already typed characters and the completed ones.
It looks like this:
$ git diff a
<using tab>
$ git diff afatal: Not a git repository: '.git'
pp.js
I can still make the command properly by just pressing enter as expected. But it really starts to get on my nerves.
Any suggestions?
The problem was an extra .git-folder in my src folder. The repository was initialized on the folder above (src/..) and this seemed to mess with git. After the removal of the extra .git folder the problem disappered.
I just discoverd the solution. I had an extra .git directory in my src-folder which seemed to mess with git (the repository was initialised on the folder above).
After I removed the extra .git folder the problem disappered.
It can depends on the msysgit version you are using:
I just tested a tab completion on a git diff on W7 64bits, with the latest msysgit1.8.3, and it worked just fine.
Don't forget that, in addition to the msysgit version, you will have issues with tab completion due to the old bash 3.1 included in mysysgit.
And the completion can be slow on Windows.
As the OP Zeeker mentions below, the completion git-completion.bash is based on a proper git repo path detection.
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
__gitdir () {
...
}
And in Zeeker's case, an extra .git folder was in the src folder, which means any completion was based from the wrong folder, which, for git diff, proved fatal.
git add seems to work though.
git-bash completion for git commands is controlled by the /etc/git-completion.bash. To fix run git-bash as administrator, then:
cd /etc
mv /etc/git-completion.bash /etc/git-completion.bash.orig
Then create a new one from the contents of https://github.com/git/git/blob/master/contrib/completion/git-completion.bash