Git’s global configuration doesn’t just set your name and email; it dictates how Git behaves across your entire system, influencing everything from how it displays diffs to how it handles line endings, and these global settings can be surprisingly overridden by repository-specific configurations, creating subtle but significant differences in how your projects behave.

Let’s see Git in action with configuration. Imagine you’re working on two projects: project-a and project-b.

In project-a, you want to ensure line endings are handled strictly for a Windows-heavy environment. You’d navigate to that directory and run:

cd ~/projects/project-a
git config --local core.autocrlf true
git config --local core.eol lf

Now, in project-b, which is a more standard Unix-like project, you want to let Git handle line endings automatically but prefer LF endings.

cd ~/projects/project-b
git config --local core.autocrlf input
git config --local core.eol lf

Meanwhile, globally, you’ve set your name and email, and perhaps a default editor:

git config --global user.name "Alice Wonderland"
git config --global user.email "alice@example.com"
git config --global core.editor "vim"

Notice how core.autocrlf and core.eol are set locally for each project, while user.name, user.email, and core.editor are set globally. This demonstrates the hierarchy: local settings override global ones when they conflict.

The primary problem Git configuration solves is providing a consistent and personalized experience across different projects and machines. Without it, you’d be manually specifying your identity and preferences for every single Git operation or every new repository. It allows you to tailor Git’s behavior to your workflow and the specific needs of a project.

Internally, Git stores these configurations in three main places:

  1. System-wide (/etc/gitconfig): Affects all users on the system. Rarely modified.
  2. Global (~/.gitconfig or ~/.config/git/config): Affects all repositories for the current user. This is where you typically set your name, email, and editor.
  3. Local (.git/config within a repository): Affects only the current repository. This is where project-specific settings reside, such as branch configurations, remote URLs, and behavior overrides.

When Git needs a configuration value, it consults these files in order of precedence: local, then global, then system. If a setting exists in a higher-precedence file, it’s used, and lower-precedence files are ignored for that specific setting.

The exact levers you control are numerous, but some of the most impactful include:

  • user.name and user.email: Essential for identifying who made commits.
  • core.editor: Which text editor Git launches for commit messages, rebasing, etc.
  • core.autocrlf: How Git handles line endings (CRLF vs. LF) when checking out and committing files. true (Windows), input (Unix-like), or false (no conversion).
  • core.eol: Which line ending character Git should use when checking out files. lf or crlf.
  • alias.<alias-name>: Create custom shortcuts for frequently used Git commands. For example, git config --global alias.co checkout.
  • branch.<name>.remote and branch.<name>.merge: Define upstream tracking relationships for branches.

A common point of confusion arises with core.autocrlf and core.eol. Setting core.autocrlf to true on Windows means Git will convert LF line endings in the repository to CRLF when you check out files, and convert CRLF back to LF when you commit. Setting it to input on Unix-like systems means Git will convert CRLF to LF on commit but won’t touch LF on checkout. Setting core.eol to lf or crlf explicitly tells Git which line ending to use when checking out files, overriding core.autocrlf’s conversion behavior for checkout. The most robust cross-platform setup often involves setting core.autocrlf to input globally and core.eol to lf globally, and then ensuring no local overrides exist unless absolutely necessary for a specific project.

The next concept you’ll likely grapple with is managing different sets of global configurations for different types of work, perhaps using Git’s include.path directive.

Want structured learning?

Take the full Git course →