Installing Git and configuring your environment
Install on any platform, set the identity and configuration that actually matter, control line endings, and put shared rules in the repository instead of in your head.
Install and verify
# macOS
brew install git
# Debian / Ubuntu
sudo apt update && sudo apt install git
# Fedora
sudo dnf install git
# Windows
winget install --id Git.Git -e
# whichever platform you are on, confirm what you got
git --version
git config --list --show-origin| Platform | Recommended install | Note |
|---|---|---|
| macOS | brew install git | Do not rely on the version bundled with the Xcode command line tools, which lags behind |
| Debian / Ubuntu | apt install git | Distro packages can be old; a newer release adds hooks and options you will want |
| Fedora / RHEL | dnf install git | The git-core package is usually enough on servers |
| Windows | winget install Git.Git | Also installs Git Bash, which gives you a usable POSIX shell |
| Any | git help config | The full reference ships offline with the binary |
Installing Git also installs its documentation: git help <command> works without a network connection and describes the version you actually have, which a search result rarely does.
The configuration that matters
git config --global user.name "Ada Lovelace"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main
git config --global core.editor "code --wait" # --wait keeps Git from returning early
git config --global pull.rebase true
git config --global rerere.enabled true
git config --global fetch.prune true
git config --global rebase.autosquash true
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate --all"
# a repository can override any of it, which is how work email happens
git config user.email "[email protected]"
git config --local core.hooksPath .githooks| Setting | Why it matters |
|---|---|
user.name / user.email | Every commit is stamped with them; a wrong address means your work is not attributed to you |
init.defaultBranch | New repositories start on main rather than the legacy default |
core.editor | Commit messages, rebase plans and --amend all open an editor; without --wait Git commits an empty message |
pull.rebase | Decides once whether every pull adds a merge commit, instead of asking per command |
rerere.enabled | Reuses a recorded conflict resolution when the same conflict reappears, which happens constantly during a long rebase |
fetch.prune | Removes local references to remote branches that were already deleted |
core.hooksPath | Lets a repository ship hooks in a tracked directory instead of .git/hooks, which is never cloned |
💡
Configuration has three levels — system, global and local — and the nearest one wins.
git config --list --show-origin prints the file each value came from, which is how you debug the classic "it works on my machine".Line endings, ignore files and attributes
# .gitignore — patterns apply to untracked files only
node_modules/
dist/
*.log
.env
.env.*
!.env.example
.DS_Store
# .gitattributes — per-path rules that travel with the repository
* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
# personal exclusions that should stay out of the repository
git config --global core.excludesFile ~/.gitignore_global- Prefer a small, deliberate ignore file over a large copied one: every line nobody can explain is a future mystery.
- A negation such as
!.env.exampleonly works when no parent directory is ignored, so ignoring.env*then excepting a file does not behave as people expect. core.autocrlf=trueon Windows converts LF to CRLF on checkout and back on commit;.gitattributeswithtext=autoachieves the same thing and is shared by the whole team.- Ignoring a path does not remove a file that is already tracked — use
git rm --cachedfor that, and remember the content stays in history.
FAQ
I already committed with the wrong email. Can I fix it?
On a local branch that has not been pushed, yes: an interactive rebase with
--reset-author, or a history filter over the whole range. If it is already published, do not rewrite it — add a .mailmap entry so the attribution displays correctly.Should hooks and ignore rules be committed?
Ignore rules and
.gitattributes always, because the whole team needs them. Hooks are better kept in a tracked directory and enabled with core.hooksPath than left in .git/hooks, which is not versioned and not cloned.Related
Hooks, aliases and automation Reading history: log, diff, blame and bisect
Last refreshed 2026-09-18.