I have changed a few files name by de-capitalize the first letter, as in Name.jpg
to name.jpg
. Git does not recognize this changes and I had to delete the files and upload them again. Is there a way that Git can be case-sensitive when checking for changes in file names? I have not made any changes to the file itself.
16 Answers
Git has a configuration setting that tells it whether to expect a case-sensitive or insensitive file system: core.ignorecase
. To tell Git to be case-senstive, simply set this setting to false
. (Be careful if you have already pushed the files, then you should first move them given the other answers).
git config core.ignorecase false
Note that setting this option to false on a case-insensitive file system is generally a bad idea. Doing so will lead to weird errors. For example, renaming a file in a way that only changes letter case will cause git to report spurious conflicts or create duplicate files(from Mark Amery's comment).
Documentation
From the git config
documentation:
core.ignorecase
If true, this option enables various workarounds to enable git to work better on filesystems that are not case sensitive, like FAT. For example, if a directory listing finds
makefile
when git expectsMakefile
, git will assume it is really the same file, and continue to remember it asMakefile
.The default is false, except git-clone(1) or git-init(1) will probe and set
core.ignorecase
true if appropriate when the repository is created.
Case-insensitive file-systems
The two most popular operating systems that have case-insensitive file systems that I know of are
- Windows
- OS X
Sometimes it is useful to temporarily change Git's case sensitivity.
Method #1 - Change case sensitivity for a single command:
git -c core.ignorecase=true checkout mybranch
to turn off case-sensitivity for a single checkout
command. Or more generally: git -c core.ignorecase=
<<true or false>>
<<command>>
. (Credit to VonC for suggesting this in the comments.)
Method #2 - Change case sensitivity for multiple commands:
To change the setting for longer (e.g. if multiple commands need to be run before changing it back):
git config core.ignorecase
(this returns the current setting, e.g.false
).git config core.ignorecase
<<true or false>>
- set the desired new setting.- ...Run multiple other commands...
git config core.ignorecase
<<false or true>>
- set config value back to its previous setting.
Under OSX, to avoid this issue and avoid other problems with developing on a case-insensitive filesystem, you can use Disk Utility to create a case sensitive virtual drive / disk image.
Run disk utility, create new disk image, and use the following settings (or change as you like, but keep it case sensitive):
Make sure to tell git it is now on a case sensitive FS:
git config core.ignorecase false
Similar to @Sijmen's answer, this is what worked for me on OSX when renaming a directory (inspired by this answer from another post):
git mv CSS CSS2
git mv CSS2 css
Simply doing git mv CSS css
gave the invalid argument error: fatal: renaming '/static/CSS' failed: Invalid argument
perhaps because OSX's file system is case insensitive
p.s BTW if you are using Django, collectstatic also wouldn't recognize the case difference and you'd have to do the above, manually, in the static root directory as well
I tried the following solutions from the other answers and they didn't work:
If your repository is hosted remotely (GitHub, GitLab, BitBucket), you can rename the file on origin (GitHub.com) and force the file rename in a top-down manner.
The instructions below pertain to GitHub, however the general idea behind them should apply to any remote repository-hosting platform. Keep in mind the type of file you're attempting to rename matters, that is, whether it's a file type that GitHub deems as editable (code, text, etc) or uneditable (image, binary, etc) within the browser.
- Visit GitHub.com
- Navigate to your repository on GitHub.com and select the branch you're working in
- Using the site's file navigation tool, navigate to the file you intend to rename
- Does GitHub allow you to edit the file within the browser?
- a.) Editable
- Click the "Edit this file" icon (it looks like a pencil)
- Change the filename in the filename text input
- b.) Uneditable
- Open the "Download" button in a new tab and save the file to your computer
- Rename the downloaded file
- In the previous tab on GitHub.com, click the "Delete this file" icon (it looks like a trashcan)
- Ensure the "Commit directly to the
branchname
branch" radio button is selected and click the "Commit changes" button - Within the same directory on GitHub.com, click the "Upload files" button
- Upload the renamed file from your computer
- a.) Editable
- Ensure the "Commit directly to the
branchname
branch" radio button is selected and click the "Commit changes" button - Locally, checkout/fetch/pull the branch
- Done
Mac OSX High Sierra 10.13 fixes this somewhat. Just make a virtual APFS partition for your git projects, by default it has no size limit and takes no space.
- In Disk Utility, click the + button while the Container disk is selected
- Select APFS (Case-Sensitive) under format
- Name it
Sensitive
- Profit
- Optional: Make a folder in Sensitive called
git
andln -s /Volumes/Sensitive/git /Users/johndoe/git
Your drive will be in /Volumes/Sensitive/
How do I commit case-sensitive only filename changes in Git?
When you've done a lot of file renaming and some of it are just a change of casing, it's hard to remember which is which. manually "git moving" the file can be quite some work. So what I would do during my filename change tasks are:
- remove all non-git files and folder to a different folder/repository.
- commit current empty git folder (this will show as all files deleted.)
- add all the files back into the original git folder/repository.
- commit current non-empty git folder.
This will fix all the case issues without trying to figure out which files or folders you renamed.
I've faced this issue several times on MacOS. Git is case sensitive but Mac is only case preserving.
Someone commit a file: Foobar.java
and after a few days decides to rename it to FooBar.java
. When you pull the latest code it fails with The following untracked working tree files would be overwritten by checkout...
The only reliable way that I've seen that fixes this is:
git rm Foobar.java
- Commit it with a message that you cannot miss
git commit -m 'TEMP COMMIT!!'
- Pull
- This will pop up a conflict forcing you to merge the conflict - because your change deleted it, but the other change renamed (hence the problem) it
- Accept your change which is the 'deletion'
git rebase --continue
- Now drop your workaround
git rebase -i HEAD~2
anddrop
theTEMP COMMIT!!
- Confirm that the file is now called
FooBar.java
I took @CBarr answer and wrote a Python 3 Script to do it with a list of files:
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import os
import shlex
import subprocess
def run_command(absolute_path, command_name):
print( "Running", command_name, absolute_path )
command = shlex.split( command_name )
command_line_interface = subprocess.Popen(
command, stdout=subprocess.PIPE, cwd=absolute_path )
output = command_line_interface.communicate()[0]
print( output )
if command_line_interface.returncode != 0:
raise RuntimeError( "A process exited with the error '%s'..." % (
command_line_interface.returncode ) )
def main():
FILENAMES_MAPPING = \
[
(r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
(r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
(r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
]
for absolute_path, oldname, newname in FILENAMES_MAPPING:
run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
run_command( absolute_path, "git add '%s1'" % ( newname ) )
run_command( absolute_path,
"git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
newname ) )
run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
run_command( absolute_path, "git add '%s'" % ( newname ) )
run_command( absolute_path, "git commit --amend --no-edit" )
if __name__ == "__main__":
main()
git mv
works. – VonCgit
working copies. Spares a lot of my sanity, I must admit... – Per Lundberg