git checkout from bash script and from terminal behaves differently - bash

I am trying to do a regression test of my code using git and a bash script.
So I have written a script to run a sample with the current version and with some previous version.
The source files are located in the src directory, and samples are in the samples directory.
Both the src and samples directories are tracked by git under the same project.
I want to roll back only src files and not touch files in samples.
I have tried git reset and git checkout.
Problem:
When I go to src in terminal and type:
git checkout -- *.F90
It does what is should - it changes only Fortran files in this directory.
If I do the same command in a bash script, it changes everything: files in src and in samples! Like if it is run from the main directory, as git checkout or git reset origin/master... How can it be?
Somewhere I have found suggestion to use env -i in a script, but it did not work either.
The whole script is about 500 lines, here is the git related part:
cd $dsrc # go to src directory
ls # debuging, just to see , that I am there
git stash
git checkout origin/master -- *.F90
with the ls command I do see the source files, so I know I am in the right place.
Any ideas?

From the Git glossary for "pathspec":
[...] in particular, * and ? can match directory separators.
So *.F90 matches all .F90 files everywhere. To limit to the current directory, you could use
git checkout origin/master -- "$PWD"/*.F90
Notice that (as pointed out by torek in their comment) the manual refers to what Git does. If the shell can expand the glob first, it will – for example, if there are files in the current directory that do match *.F90.
Only when there aren't any will Git get the unexpanded literal *.F90 and match the * with any prefix, including /. To prevent expansion by the shell, you could quote the glob:
git checkout origin/master -- "$PWD/*.F90"
or use . in the pathspec:
git checkout origin/master -- ./*.F90

Related

How to pass wildcard string to git from bash / gnome terminal

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 ...

Git on Windows: How do I ignore a folder that has dots in its name

I have a directory like that :'dir1/dir2/blah.blah.blah.blah/'
'blah.blah.blah.blah' is folder how do I add it to .gitignore?
I tried:
dir1/dir2/blah.blah.blah.blah/*
You need to escape the . in your .gitignore file like this:
blah\.blah\.blah\.blah
If this does not work, you probably added the directory to git earlier. In this case, you need to remove it from git (git rm <directory> and then git commit) but this will also remove it from the working directory, so backup the files if you still need them!
Use git ls-files dir1/dir2/ as suggested by torek in the question's comments to check if the directory has been added to git.
To remove a file or directory from repository, you can use this:
git rm -r --cached <file/directory>
git commit -m "removes <file/directory>"
This will not remove anything from the history though. The files can still be accessed when checking out an older commit.
It will also not remove the actual files in the directory, it will just make git not longer track them.

git-svn fetch gives me a filename that git doesn't handle

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.

On Windows git can't handle files with the same name but in different case properly

I use git on windows. In my project I changed case of filename. After that checkout of previous commits failed (commands are in Git Bash):
mkdir repofolder
cd repofolder
git init # create empty repo
git config core.ignorecase false # turn on case-dependent filenames
# create 'readme.txt'
$ echo "blahblahblah" > readme.txt
$ git add readme.txt
$ git commit -m "+readme.txt"
# rename it to 'README.txt'
$ git mv -f readme.txt README.txt
$ git commit -m "readme.txt => README.txt"
$ git status
On branch master
nothing to commit, working directory clean
$ git checkout HEAD~1
error: The following untracked working tree files would be overwritten by checkout:
readme.txt
Please move or remove them before you can switch branches.
Aborting
Why git doesn't allow to checkout previos commits?
You face with the same problem when delete one file and append another one with the same name, but different case. No matter how many commits you do: one (removing and appending in the same commit) or two commits (in first commit you remove file, in second you add another one).
On Windows git can't handle files with the same name but in different case properly
Git on Windows can't handle it because Windows itself can't handle it (emphasis mine):
As part of the requirements for POSIX compliance, the Windows NT File System (NTFS) provides a case-sensitive file and directory naming convention. Even though NTFS and the POSIX subsystem each handle case-sensitivity well, 16-bit Windows-based, MS-DOS-based, OS/2-based, and Win32-based applications do not.
In truth, Windows does have some level of support for NTFS case-sensitivity, but it's pretty flaky:
However, if you attempt to open one of these files in a Win32 application, such as Notepad, you would only have access to one of the files, regardless of the case of the filename you type in the Open File dialog box.
Other inconsistencies also exist. The Windows NT Command Prompt and File Manager correctly display the names of the files. However, normal commands, such as COPY, fail when you attempt to access one or more filenames that differ only in case.

Git-bash tab completion: "fatal: Not a git repository: '.git'" (Windows)

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

Resources