My team use git as main source control tool. The git repositories are hosted by Azure Dev Ops.
Most of the teammate are working on windows but some are on ubuntu (Ubuntu os or through WSL, or from continuous delivery pipelines).
By default, on windows, git ignore case (core.ignorecase
is true
on default on windows) and its causing troubles, because import 'Somefile.ts'
where the filename is actually SomeFile.ts
works on windows, but not on other systems.
And renaming the file, just by changing casing is not considered as a change by git unless the ignoreCase
option is set to false
.
Is there any way to enforce this attributes for all team mates, at repository level (meaning the option is set on the main repo, and applied when cloning) ?
Setting this option using git config core.ignorecase false
is local only.
Nothing in the .gitattributes documentation seems to handle this requirement.
CodePudding user response:
You cannot 100% ensure it, but you can add a simple script (.sh or .bat) to set this configuration for the repo. Each team member must run this script once after cloning the repository. Describe how to run it in your README or CONTRIBUTING files.
CodePudding user response:
about that point :
And renaming the file, just by changing casing is not considered as a change by git unless the
ignoreCase
option is set tofalse
I would invite you to test it on a case sensitive file system :
on my linux box, even with the core.ignoreCase
option on, case changes in file names are registered.
What I do get is git ignoring foo.txt
when it sits next to versioned Foo.txt
, for example.
There is a gotcha on case insensitive filesystems (e.g : Windows and MacOS) : mv myfile.txt MyFile.txt
is treated as a noop by the system itself.
A common workaround is to do the rename in two steps, using a temporary name :
mv myfile.txt tmpname
mv tmpname MyFile.txt
git add myfile.txt MyFile.txt
# or
git mv myfile.txt tmpname
git mv tmpname MyFile.txt
about your repo :
as said by @phd and @knittl : you can't enforce a setting on every local clone. You can :
- commit some form of
setup.sh
script, to set up the local configuration of each developper PC - use hooks on the central repo to reject commits that don't adhere to some rule
Additionally :
- you can add a CI builder which would test your code (if run on a case sensitive file system, it would hit the bugs you mention)
- you should look into linters that could catch this kind of bug
- in the would be
setup.sh
script, you can add hooks (pre-commit
and/orpre-push
) to run linters on the client side
CodePudding user response:
Do not lie to Git.
The core.ignorecase
(or core.ignoreCase
1) setting tells Git how your operating system behaves.2 It does not change how your OS behaves, because it can't: it just allows Git to foretell, in advance, whether creating and writing to a file named README.txt
is going to overwrite another file named readme.txt
, or create a new separate README.txt
.
If you do lie to Git, Git will behave in a file-system-incorrect manner, but in a predictable way (with the exact details depending on Git version). This is occasionally useful to work around particular issues. So you'll sometimes see StackOverflow answers that say "to work around this, fiddle with core.ignorecase, do operation X, then restore core.ignorecase". Some of these answers fail to mention that you must restore the setting afterwards, but it is important to restore the setting afterwards.
The reason core.ignorecase
exists is so that Git will behave better on systems that ignore case. Over time, as the Git software evolves, these "behave better" behaviors should improve, although it can never be perfect because there's a fundamental mismatch here: Git itself does not ignore case internally and Git can always store two different files under names like README.txt
vs readme.txt
. Anyone who uses Git on a case-sensitive file system, such as those found in most Linux installations, will be able to create and commit both files into a single commit. If you're working on a system that can't extract both files at the same time, you can't work with this single commit in a completely-sensible manner (though as always there are various tricks and workarounds).
1Ironically, while Git is case-sensitive in most parts, it's case-in sensitive when looking at the first and last components of settings like these. That is, both the words core
and ignorecase
can be spelled with arbitrary upper and lower casing, to some extent. (I say "to some extent" because you can't, for instance, replace a German eszett ß
with SS
, even though that's a case-insensitive equivalent. The uppercase ẞ did not exist until recently, but would generally work here, depending on your Unicode tables and the behavior of tolower
in your C library. Git doesn't have any of its own settings using ß
, but as the .gitconfig
file is user-extensible, you could add your own.)
Note that middle sections can be case-sensitive. In particular url.<thing>.insteadOf
must be case-sensitive in the middle since URLs themselves are generally case-sensitive (the URL is passed over the network to a different computer—the server—and it's the server that decides whether the URL is case-sensitive, and on many servers it is).
2Technically the behavior tends to be per-file-system, on modern operating systems, rather than OS-wide. For instance, you can mount an old-style DOS 8.3 floppy, if you can find an old floppy, on Linux using a DOS-FS file system, and you'll get the silly eight-dot-three style file names. Git assumes consistent behavior throughout the working tree of a repository, though, and probes the behavior at git init
or git clone
time to set core.ignorecase
—Git spells it in all-lower-case when setting it up initially—based on the observed behavior.