Why this matters
Git is a program, and like any program it must be installed before you can use it. It also needs to know who you are, because every commit you make is signed with a name and email. Skipping this setup is the single most common reason a beginner's first commit fails. Ten careful minutes now save an hour of confusion later.
You will also learn where Git keeps its settings, which is a pattern you will meet again with other tools: settings live in plain text files at several levels, and the more specific level wins.
Where you type Git commands
Git is a command-line program: you run it by typing commands into a terminal. If the terminal is still new to you, the earlier module in this course covers it. In short, a terminal is a text window where you type a command, press Enter, and read the answer.
Which terminal you use depends on your system:
- macOS: the Terminal app (in Applications, then Utilities).
- Linux: any terminal emulator that comes with your system.
- Windows: Git for Windows includes a terminal called Git Bash. PowerShell and Windows Terminal also work once Git is installed. This course shows commands in the Bash style, so Git Bash is the simplest choice on Windows. If you use WSL (Windows Subsystem for Linux), you install Git inside Linux instead, with the Linux commands below.
Throughout the course, a line that starts with git is something you type. Lines without it, usually shown in a text block, are what the computer prints back. Do not type the $ symbol if you see it in other tutorials. It stands for the prompt, which your terminal prints itself.
Check first: is Git already installed?
Many computers already have Git. Open your terminal and run:
git --versionIf Git is installed, you see a line like this:
git version 2.53.0Your number will probably differ. Any version from the last few years is fine. A big difference between versions is rare for the commands in this course.
If Git is missing, the message depends on the system:
bash: git: command not foundor on Windows PowerShell:
git : The term 'git' is not recognized as the name of a cmdlet, function, script file, or operable program.Both mean the same thing: the terminal searched for a program called git and did not find one. Install it using the section for your system.
Install on Windows
- Go to the official Git website,
git-scm.com, and download "Git for Windows". (Type the address yourself rather than following a link from an unknown source.) - Run the installer. Most screens can stay at their defaults. Three choices deserve a moment:
- Default editor: the installer may offer Vim, which is hard for beginners to exit. Choose a friendlier one, such as Visual Studio Code or Notepad.
- Initial branch name: pick "Override the default branch name" and type
main, the standard name today. You can also set this afterwards, as shown below. - PATH environment: keep "Git from the command line and also from 3rd-party software". This is what lets VS Code and other tools find Git.
- When it finishes, open Git Bash from the Start menu and run
git --version.
If you prefer a package manager, open PowerShell and run winget install --id Git.Git -e --source winget. It installs the same program.
Install on macOS
The simplest route is to run git --version in Terminal. On a Mac without Git, macOS offers to install the Command Line Tools, a bundle of developer programs that includes Git. Click Install and wait a few minutes.
If you already use Homebrew, a package manager for macOS, you can instead run:
brew install gitHomebrew's version is usually newer than Apple's. Either one is fine.
Install on Linux
Use your distribution's package manager. You need administrator rights, which sudo gives you for one command.
# Debian, Ubuntu and relatives
sudo apt update
sudo apt install git
# Fedora and relatives
sudo dnf install git
# Arch and relatives
sudo pacman -S gitAfter installing, run git --version to confirm.
What just happened inside your computer
When you type git, the shell (the program reading your typing) looks for a file called git in a list of folders. That list is stored in an environment variable named PATH. The installer placed the Git program in one of those folders. If the installer failed to add it, you get "command not found", and the cure is usually to close and reopen the terminal (the terminal reads PATH only when it starts) or to rerun the installer.
The installation gave you a program, not an account. Git does not need a login, a network or a server. Everything in the next two lessons works without internet.
Telling Git who you are
Every commit records an author: a name and an email. This is how a log can say "Asha Rao wrote this line". Git cannot guess these, so you set them once.
git config --global user.name "Asha Rao"
git config --global user.email "asha@example.com"Replace the name and email with your own. The quotes around the name matter when it contains a space. Without quotes, the shell would treat Asha and Rao as two separate words.
Check that it worked:
git config --global user.nameAsha RaoWhich email should you use? You have two sensible choices.
- Your real email, the same one you use for GitHub. Then GitHub connects your commits to your profile.
- GitHub's private "noreply" address. In GitHub's email settings you can choose "Keep my email addresses private". GitHub then shows you an address that looks like
12345678+yourname@users.noreply.github.com. Use that inuser.emailand no stranger can read your real address in public commits.
Remember this: commit emails are public once you push to a public repository. Anyone can download the history and read them. If privacy matters to you, use the noreply address from the start. Changing it later does not erase the old commits.
What --global means
The word --global says "apply this setting to every repository on this computer, for my user account". The result lands in a plain text file in your home folder named .gitconfig. You can look at it:
cat ~/.gitconfig[user]
name = Asha Rao
email = asha@example.comA file with [section] headings and key = value lines is called an INI-style file. It is just text, and you are allowed to read it or even edit it by hand. The git config command exists only to edit that file safely.
To see the idea in action, this program reads the same format. It is a stand-in, since your sandbox does not have your .gitconfig, so it uses a short text of its own:
It prints the settings in the dotted form Git uses:
user.name = Asha Rao
user.email = asha@example.com
init.defaultbranch = mainThe dotted name user.name means "the key name inside the section user". Notice that Python lower-cased defaultBranch. Git treats key names as case-insensitive in the same way, so init.defaultbranch and init.defaultBranch mean the same setting.
Three levels of settings
Git reads settings from three places, from widest to narrowest.
| Level | Flag | Where it is stored | Applies to |
|---|---|---|---|
| System | --system | A file in Git's install folder | Every user on this computer |
| Global | --global | ~/.gitconfig in your home folder | Every repo you use |
| Local | --local (the default inside a repo) | .git/config in that repo | That one repository |
When the same key appears at several levels, the most specific level wins. This is useful. Suppose your global email is your personal one, but for a work project you need your company email. Inside that one repository, run:
git config user.email "asha@company.example"With no flag, inside a repo, this writes to the local file .git/config. That project now uses the company email, and every other repo still uses the personal one.
You can see which value Git uses and where it came from:
git config --show-scope --show-origin user.emaillocal file:.git/config work@example.comThe first column says the level (local), the second the file, the third the value. To see everything Git knows, with sources:
git config --list --show-originThat prints many lines, and it is the first command to run when a setting does not behave as you expect.
Set the default branch name
For years Git named the first branch master. The convention today, and GitHub's default, is main. If your Git is older, it may still choose master, and then your local branch name will not match GitHub's. Set it once:
git config --global init.defaultBranch mainFrom now on, every git init creates a branch called main. The name is only a label, but matching GitHub avoids a confusing mismatch in lesson 5.
Choose an editor
Sometimes Git opens a text editor, for example when you write a long commit message or resolve a merge. If you never chose, it may open Vim, a powerful editor that is famously confusing to leave. (To exit Vim, press Esc, then type :q! and press Enter.) You can pick something friendlier:
# Visual Studio Code, waiting until you close the file
git config --global core.editor "code --wait"
# Or nano, a simple terminal editor on Linux and macOS
git config --global core.editor "nano"The --wait flag matters for VS Code. Without it, Git thinks the editor has finished the moment the window opens, and carries on with an empty message.
A few useful extras
You do not need these on day one, but they save time.
Aliases are shortcuts for commands you type often:
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --decorate"Now git st means git status -sb and git lg means git log --oneline --graph --decorate. You will see what these commands do in the next lessons. In a fresh empty repository, git st prints:
## No commits yet on mainLine endings differ between systems: Windows ends a line with two invisible characters, Linux and macOS with one. A shared project can show every line as changed if people on both systems commit without care. Git for Windows sets a safe default for you. On macOS and Linux, you can add the matching setting:
git config --global core.autocrlf inputYou can ignore this unless you see whole files marked as changed when you changed one line.
Get help at any time. Every Git command accepts -h for a short usage summary, and git help <command> opens the full manual page:
git commit -h
git help commitThe first prints the usage lines (in a form such as usage: git commit [-a | --interactive | --patch] ...). The second opens a longer manual. Press q to leave the manual viewer.
Edit or remove a setting
To change a value, run git config with the new one. It overwrites the old value:
git config --global user.email "newaddress@example.com"To remove a setting, use --unset:
git config --global --unset core.editorTo read one value without changing it, give only the key:
git config --get user.emailIf the key is not set, this prints nothing and exits with a non-zero status. A script can use that to tell "not set" from "set to empty".
You can also open the whole global file in your editor with git config --global --edit. Be careful: a typo in the file format can make every Git command print an error.
Different identities for different folders
Imagine you work as a freelancer. Personal projects should use your personal email and client projects should use a client email. Setting the email by hand inside every client repo is easy to forget. Git has a feature for this: conditional includes. You tell the global file, "when a repository lives under this folder, also read these extra settings."
Put all client repositories under one folder, for example ~/clientwork/. Create a small file ~/.gitconfig-client containing:
[user]
email = asha@client.exampleThen add this to ~/.gitconfig (the trailing slash on the folder is required):
[includeIf "gitdir:~/clientwork/"]
path = ~/.gitconfig-clientTest it by creating a repo in each place and asking Git for the email. In the test that produced this lesson, the result was:
personal: asha@example.com
clientwork: asha@client.exampleThe repo under the client folder picked up the extra file, and the other repo kept the global value. The idea behind it is the same as the three levels above: the more specific setting overrides the general one, only here "specific" is decided by where the repo lives. Many professional developers use this setup, so it is worth remembering even if you do not need it yet.
Keeping Git up to date
Git changes slowly, and a version from a few years ago works for this course. Still, updating is easy and gives you bug and security fixes:
- Windows: newer Git for Windows installers replace the old one, or run
git update-git-for-windowsfrom a terminal. - macOS:
brew upgrade gitif you installed with Homebrew. Apple's own copy updates with the Command Line Tools. - Linux: update through your package manager, for example
sudo apt update && sudo apt upgrade git.
After an update, run git --version again. Settings are kept, because they live in your home folder and not in the installation.
Using Git from your editor
Most editors, including VS Code, have Git built in. VS Code shows changed files in a "Source Control" panel, lets you stage with a plus button and commit by typing a message. It finds Git through the same PATH you tested above. These buttons run the same commands you are about to learn, and nothing else. If an editor button behaves in a way you do not understand, open the terminal and run git status: it tells the truth about what the button did.
Beginners are often told to use only the terminal, or only the buttons. A balanced view: learn the terminal commands first, because they work everywhere (servers, other people's laptops, interviews), then use the buttons for speed when you know what they do.
The environment problems you may meet
These are not your fault. They are common enough that knowing them saves time.
"detected dubious ownership". If you open a repository folder that belongs to a different user account (for example a project on a shared drive or copied from another machine), Git may stop with:
fatal: detected dubious ownership in repository at '/path/to/project'and prints a suggested command that begins git config --global --add safe.directory. This is a security feature: Git refuses to run inside a folder owned by someone else, in case the folder contains hostile settings. If you trust the folder, run the command it printed. If you do not know why the owner differs, ask before trusting it.
Line-ending warnings on Windows. Messages such as warning: LF will be replaced by CRLF are harmless. They tell you Git is converting line endings as configured. Ignore them unless the project documentation says otherwise.
A corporate proxy. On a company network, git clone over HTTPS may hang. The network team will provide a proxy address, set with git config --global http.proxy <address>. At home you will not need this.
An old Git on a shared computer. Some university computers ship a very old Git. git --version tells you. If git switch is "not a git command", your Git is older than 2.23, and you can use git checkout instead or install a newer Git.
Two copies of Git. On macOS you may have both Apple's and Homebrew's. which git (or where git on Windows) shows which one runs first. It rarely matters, but it explains why git --version and a Homebrew update can disagree.
How to read what Git prints
Git talks a lot, and almost all of it is useful once you know the pattern. Messages come in four flavours, and you can tell them apart by their first word.
| Starts with | Meaning | What to do |
|---|---|---|
| nothing (plain text) | Normal information | Read it; usually it is the result you asked for |
hint: | Advice from Git | Read it, it often contains the exact command to run |
warning: | Something odd, but Git carried on | Check it, but nothing is broken |
error: or fatal: | Git stopped | Read the whole message from the top; the cause is usually in the first line |
error: means the command could not complete and Git changed nothing, or stopped at a safe point. fatal: is a stronger form: the command cannot continue at all. Neither word means your repository is damaged. Treat both as a polite refusal.
A habit that pays off for a lifetime: when a command fails, read the message from top to bottom before you search the internet. Git's authors wrote many of these messages as small instruction manuals. The "Author identity unknown" message above even prints the commands you need. Developers who skip reading and paste random commands from forums are the ones who damage repositories.
A second habit: when you are unsure what a command will do, ask for a dry run or for help first. Many commands have --dry-run (git clean --dry-run, git push --dry-run), and every command has -h. Looking costs nothing.
Your first terminal session, step by step
To bring the lesson together, here is a short session. You do not have a repository yet, so everything here is safe to type. It confirms that the install, the identity and the defaults all work.
git --version
git config --global user.name
git config --global user.email
git config --global init.defaultBranch
mkdir git-check
cd git-check
git init
git branch --show-current
cd ..What each line proves:
git --versionproves the program is installed.- The three
git config --globalreads prove your identity and your default branch are saved, and print their values. mkdir git-checkandcd git-checkmake and enter a scratch folder.git initproves Git can create a repository. It printsInitialized empty Git repository in ....git branch --show-currentprintsmain, proving the default-branch setting is active.cd ..leaves the folder. You can deletegit-checkafterwards withrm -rf git-check(be careful withrm -rf: it deletes without asking, so type the folder name exactly).
If every step printed what you expected, you are ready for lesson 3.
A setup checklist
When you are done with this lesson, every box should be ticked. Treat it as the definition of "my machine is ready".
-
git --versionprints a version number. -
git config --global user.nameprints your name, in full. -
git config --global user.emailprints the email you will use on GitHub. -
git config --global init.defaultBranchprintsmain. -
git config --global core.editorprints an editor you can use (or you accept the default). - You can find your
.gitconfigand read it. - You know the difference between global and local settings.
Common questions
Do I need a GitHub account to use Git? No. Git works fully without any account. You need GitHub only in lesson 5, when you share a repository.
Can I change my name or email later? Yes, at any time. It only affects new commits. Old commits keep the author they were made with.
Is my email safe in .gitconfig? The file is on your computer, so it is private. The email becomes visible when you push commits to a public repository, which is why the GitHub noreply address is a good choice.
What if I use two computers? Install and configure Git on each one. Settings are not shared between computers. What you share is the repositories, through GitHub.
Do I have to type --global every time? Only when you want a setting for every repository. Without it, inside a repository, the setting applies to that repository.
Worked examples
Here are six real situations, each traced to its result.
Example 1: A fresh install. You install Git on a new laptop, open a terminal and run git --version. Output: git version 2.53.0. You run git config --global user.name, which prints nothing because it is not set yet. You then set name and email. The same read now prints your name. Outcome: before the setup, git commit would refuse to run; after it, commits work.
Example 2: Checking before trusting. A classmate says Git is "all set" on her machine. You ask her to run git config --list --show-origin. She sees user.name and user.email in ~/.gitconfig. That proves both global settings exist, and tells you where they live.
Example 3: Two emails on one laptop. You have a personal laptop that you also use for a freelance client. In the client repo you run git config user.email "me@client.example" without --global. A test:
git config --global user.email -> asha@example.com
git config user.email (in client) -> me@client.example
git config user.email (elsewhere) -> asha@example.comThe local value only exists inside the one repo.
Example 4: Setting main as the default. You run git config --global init.defaultBranch main, then git init demo, then cd demo and git branch --show-current. Git prints main. The repository has no commits yet, so git branch (the list of branches) prints nothing, but the name the first commit will use is already chosen.
Example 5: Alias that fails. You define git config --global alias.lg "log --oneline --graph --decorate" and run git lg in an empty repo. Git answers fatal: your current branch 'main' does not have any commits yet. The alias is fine. The log has nothing to show until you make a commit.
Example 6: Removing an alias. After git config --global --unset-all alias.st, running git st prints:
git: 'st' is not a git command. See 'git --help'.and suggests similar commands such as status. That tells you the alias is gone.
Common mistakes
Mistake 1: "Author identity unknown". If you try a commit before setting your name and email, Git refuses:
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.Read it as instructions, because it is: it gives you the exact two commands. Run them with your details, then retry the commit. Nothing was lost.
Mistake 2: Forgetting the quotes. git config --global user.name Asha Rao prints no error, yet it stores only Asha: the shell hands Git two words and Git ignores the second as a filter. Your commits then carry a half name. Always check with git config --global user.name, and write "Asha Rao" with quotes.
Mistake 3: Using an email GitHub does not know. If the commit email does not match any email on your GitHub account, GitHub shows your commits but does not link them to your profile, and your contribution graph stays empty. Add the email in GitHub's settings, or change the Git one.
Mistake 4: Setting the wrong level. You set the company email with --global and then wonder why personal projects show it. Check with git config --show-scope --show-origin user.email and fix the level you meant.
Mistake 5: git not found after installing. The terminal you had open before the install does not know about the new program. Close it and open a new one. On Windows, use Git Bash from the Start menu.
Mistake 6: Typing git config with =. The syntax is git config user.name "Asha", with a space, not user.name="Asha".
A short debugging walkthrough
Scenario: you committed all week, but your GitHub profile shows no green squares. Work backwards.
- Run
git log -1in your repo. Read theAuthor:line. It showsAuthor: Asha Rao <asha@laptop.local>. That email looks like a placeholder, not an address. - That means Git guessed an address from your computer's name, because the email was never set.
- Fix going forward:
git config --global user.email "12345678+asha@users.noreply.github.com". - Old commits keep the wrong email, and rewriting history is an advanced topic. New commits will be correct.
The lesson here is a method. When something is wrong with a Git setting, ask three questions: what value does Git use, which level did it come from, and is that what I intended?
Interview-style questions
- What does
--globaldo ingit config? It writes the setting to your user-level file,~/.gitconfig, so it applies to all your repositories. - What happens if the same setting exists globally and locally? The local one wins, since the most specific level overrides the wider one.
- Why does Git need your name and email? Each commit stores an author, so the history can say who made each change.
- How can you find out where a setting is coming from?
git config --show-originor--list --show-originprints the file for each value.
Practice
1. (Easy) Run git --version and write down the output. If it fails, install Git using the section for your system.
Solution
You should see a line such as git version 2.53.0. Any recent version is fine. If you see "command not found" or "not recognized", follow the install steps, then close and reopen the terminal and try again.
2. (Easy) Set your global name and email, then read them back with two separate commands.
Solution
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global user.name
git config --global user.emailThe last two commands print the values you set.
3. (Easy) Set main as your default branch name and show that it is stored.
Solution
git config --global init.defaultBranch main
git config --global --get init.defaultBranchThe second command prints main.
4. (Easy) Open ~/.gitconfig in a text editor or print it. Which section headings do you see?
Solution
At least [user], and [init] if you set the default branch. Each heading groups related keys. The file is the plain text that git config --global edits.
5. (Medium) Create an empty repository called practice, give it a local email different from your global one, and prove which email applies in and out of the repo.
Solution
mkdir practice
cd practice
git init
git config user.email "local@example.com"
git config --get user.email
cd ..
git config --get user.emailInside practice the first read prints local@example.com. Outside any repo, the second read prints your global email (or nothing if you set none). The local setting is stored in practice/.git/config.
6. (Medium) Add an alias last that shows the most recent commit with git log -1. Test it in a repository that has at least one commit, and then remove it.
Solution
git config --global alias.last "log -1"
git last
git config --global --unset alias.lastgit last prints the latest commit exactly as git log -1 would. After the --unset, git last fails with "'last' is not a git command".
7. (Medium) Your commit fails with "Author identity unknown". Which two commands does Git itself tell you to run, and should you add --global?
Solution
git config --global user.email "you@example.com" and git config --global user.name "Your Name". Use --global when you want the identity everywhere on this computer. Omit it to set the identity for the current repository only. Most beginners want --global.
8. (Medium) Use a single command to list every setting Git sees along with the file each came from. What does the first column of --show-scope output tell you?
Solution
git config --list --show-origin lists every value with its file. Adding --show-scope puts the level in the first column: system, global or local. That tells you at which level each value was set.
9. (Hard) A teammate reports that their commits on a work repo show your personal email, even though the repo should use the company one. List the steps you would take to diagnose it, in order.
Solution
- Inside the repo, run
git config --show-scope --show-origin user.emailto see which value wins and from which file. - If it comes from
global, the repo has no local override. Set one withgit config user.email "name@company.example"inside the repo. - Check the last commit with
git log -1to confirm the old commits still show the old email, and the next commit shows the new one. - Remember that earlier commits keep the old email, since history is not changed by a config edit.
10. (Hard) Explain why git config --global core.editor "code --wait" includes --wait, using the idea of "when does Git think the editor is finished?".
Solution
Git starts the editor program and waits for that program to exit, then reads the file you saved. VS Code's command can return immediately after asking an existing window to open the file, so Git would see "finished" at once and read an empty file. --wait makes the command stay running until you close the file, so Git waits for you.
What you now know
- How to check whether Git is installed (
git --version) and how to install it on Windows, macOS and Linux. - Why the terminal says "command not found" and why reopening it can fix that after an install.
- How to set your name and email with
git config --global, and why the email will be public in public repositories. - That settings live in plain text files at three levels (system, global, local), and the most specific wins.
- How to set the default branch to
main, pick an editor, add aliases, and inspect a setting's origin. - How to read the "Author identity unknown" error as a set of instructions.