Git for Windows works out of the box and then nags: a warning about line endings on every add, a
"Filename too long" on a deep .NET project, a "dubious ownership" the first time you open a
repository from WSL, and a commit that refuses because it does not know who you are. Each one is a
setting, and this part finds where the settings live, reproduces every warning in a scratch
repository and fixes it, without touching the real configuration of this PC: every global change ran
against a scratch file through GIT_CONFIG_GLOBAL, and the real one was hashed before
and after. Git 2.45.2, outputs quoted.
git config --list --show-origin --show-scopein any repository: three files, three scopes- A scratch repository with one LF file and one CRLF file;
git add .withcore.autocrlfunset, true and input; then a.gitattributesandgit add --renormalize . - A file path over 260 characters,
git add ., thengit config core.longpaths true git config --get credential.helperandgit-credential-manager -?- From WSL as root,
git statuson a repository under/mnt/c; add thesafe.directoryentry - Commit with no identity, then set
user.nameanduser.emaillocally; setinit.defaultBranch git var GIT_EDITORbefore and aftercore.editor
Three files, three scopes
system file:C:/Program Files/Git/etc/gitconfig core.autocrlf=false
system file:C:/Program Files/Git/etc/gitconfig core.editor=notepad
system file:C:/Program Files/Git/etc/gitconfig init.defaultbranch=master
global file:C:/Users/.../.gitconfig credential.helper=manager
global file:C:/Users/.../.gitconfig http.version=HTTP/1.1
local file:.git/config core.symlinks=false
local file:.git/config core.ignorecase=true
The system file under Program Files is written by the installer and holds its choices: on this PC
core.autocrlf=false, Notepad as the editor and master as the default branch.
The global file in your profile holds your identity and the credential helper. The local file in
.git holds what git init wrote for Windows, such as
core.ignorecase=true. Later scopes win: local over global over system, which every
experiment below relies on. When a setting surprises you, this one command tells you which file
set it.
Line endings: the warning and the two fixes
A fresh repository with one file ending in LF and one in CRLF, and git add . under each
value of core.autocrlf. With the system's false, or nothing set at all, there
was no warning and the CRLF file went into the repository as CRLF, which is the quiet way to put
Windows line endings into everyone's clone. With true:
warning: in the working copy of 'lf.txt', LF will be replaced by CRLF the next time Git touches it
With input, the other file is the one warned about:
warning: in the working copy of 'crlf.txt', CRLF will be replaced by LF the next time Git touches it
Neither warning stops the add; both say what the working copy will look like after the next checkout.
GitHub's documentation gives the Windows setting as git config --global core.autocrlf true,
and then the better answer, a .gitattributes file committed to the repository, which
"overrides the core.autocrlf setting for all repository contributors". With
* text=auto eol=lf in that file and git add --renormalize ., every file showed
attr/text=auto eol=lf in git ls-files --eol, a fresh clone had LF in the working
copy for every file although core.autocrlf was still true, and adding a new LF file printed
nothing. A new CRLF file still warns that CRLF will be replaced by LF, which is the file telling you
the truth. In the repository that had already committed CRLF, the same two commands produced a
normalising change to crlf.txt, the commit GitHub's page describes. For .NET
repositories, GitHub's own example keeps *.sln text eol=crlf, which Visual Studio prefers;
that line was not tested here. The warning has a
Fixes post.
Filename too long
A file whose full path is 297 characters, created from WSL because Windows tools refuse to, sat in
the repository and git status listed its folder as untracked without complaint.
git add . did not:
fatal: unable to stat 'src/Contoso.Clinic.Appointments.Infrastructure/Persistence/Configurations/Generated/AppointmentReminderSchedule/AppointmentReminderScheduleConfigurationNotes.txt': Filename too long
git config core.longpaths true in that repository, and the add went through. Cloning the
repository failed the same way during checkout, with "Clone succeeded, but checkout failed", and for
a clone the setting has to be global, because the local file does not exist yet. The registry's
LongPathsEnabled is 0 on this PC and was left alone; whether it would change Git's
behaviour on its own was not tested. The Fixes
post has the one-line version.
Credentials
git config --get credential.helper answered manager, from the global file:
Git Credential Manager 2.5.0, bundled with Git for Windows. No credential store is configured, so the
documented default applies, which its documentation names as the Windows Credential Manager. The
same documentation describes the first push: "a window will automatically open and walk you through
the sign-in process", and later commands reuse the stored token for as long as it is valid. No push
was made in this run. One trap on the way: git credential-manager --help prints nothing,
because Git hands --help to its HTML manual; git-credential-manager -? prints
the help in the terminal.
Dubious ownership, from WSL and from Windows
A repository created on Windows, opened from a WSL distribution as the normal user, worked: WSL mounts drive C: with that user's id, so the files look like theirs. Opened as root, the same repository refused:
fatal: detected dubious ownership in repository at '/mnt/c/Users/.../wsl-demo'
To add an exception for this directory, call:
git config --global --add safe.directory /mnt/c/Users/.../wsl-demo
The suggested command fixed it, and safe.directory '*' fixes it for every repository on
the drive. The reverse case is the one Visual Studio users meet: a repository inside the Linux file
system opened by Git for Windows through \\wsl.localhost\ gives the same error with a
different suggested path:
git config --global --add safe.directory '%(prefix)///wsl.localhost/ds-p5/home/maria/linux-demo'
Run exactly as suggested, it worked. The Fixes post explains the ownership check behind both.
Who you are, and which branch you start on
With no identity set anywhere, the first commit stops:
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got '...')
The last line shows your Windows user and machine name, which is one reason to set the identity
yourself. Set it per repository when a public repository should not carry your real address:
git config user.email maria-garcia@users.noreply.github.test in the scratch repository
made the next commit read Maria Garcia <maria-garcia@users.noreply.github.test> in
the log while the earlier commit kept the first address. GitHub shows your own noreply address in
your email settings. The default branch on this PC is master from the system file;
git config --global init.defaultBranch main in the scratch global made
git init create main, and the hint Git prints when nothing is set suggests
exactly that command.
The editor
git var GIT_EDITOR prints the editor Git would open without opening it: notepad
here, from the system file. After git config --global core.editor "code --wait" it printed
code --wait, the command Pro Git's table gives for Visual Studio Code; the
--wait is what makes Git pause until the tab is closed. A GIT_EDITOR
environment variable beat the setting in this run, which is how tools that must never open an editor
keep Git quiet.
The five lines for a new Windows PC: core.autocrlf true plus a committed
.gitattributes, core.longpaths true, init.defaultBranch main,
core.editor "code --wait", and a per-repository identity for anything public. The
credential helper is already right.
Frequently asked
- How do I stop the LF will be replaced by CRLF warning in Git on Windows?
- Commit a .gitattributes file with * text=auto eol=lf (and *.sln text eol=crlf if Visual Studio solutions must stay CRLF), then run git add --renormalize . once and commit. The attribute overrides core.autocrlf for every contributor, new LF files add without a warning, and a fresh clone has LF endings even with core.autocrlf true.
- How do I fix Filename too long in Git for Windows?
- Run git config core.longpaths true in the repository, or git config --global core.longpaths true before cloning, because a clone fails at checkout before a local setting exists. The limit is the classic 260-character Windows path; the registry's LongPathsEnabled was not changed in this test and is not needed for Git.
- Why does Git say detected dubious ownership in repository?
- The files are owned by a different user than the one running Git: root in WSL looking at a repository on /mnt/c that the mount assigns to the default user, or Git for Windows opening a repository inside the WSL file system through a wsl.localhost path. Add the repository with git config --global --add safe.directory, using the exact path Git suggests, or '*' to trust every repository.
Next: Part 6, HTTPS on localhost: what the developer certificate is, where it lives, and what trusting it means on Windows, in WSL and in a container.