▶Prefer to watch? This short video runs this page's main commands in a real lab, with on-screen captions and no voiceover. Click to play, or watch it on YouTube.
Git for Beginners: the commands you need, in plain English
git status
Git is a tool that remembers every version of your files. You save "snapshots" (called commits), and you can look back at any of them, undo mistakes, try
ideas on the side without breaking your work, and share your project with other people. You do NOT need to learn all of Git. About a dozen commands cover almost
everything a beginner does. This sheet teaches those, explains what each one is doing, shows what you should see, and gives you a safe way to fix the usual mistakes.
When you are comfortable, the full Git cheat sheet and the GitHub cheat sheet go much further.
The big idea: three places your changes live
Working folder The files you see and edit on your computer
Staging area A "waiting room" where you choose WHICH changes go into the next snapshot
Repository The saved history of snapshots (commits) inside a hidden .git folder
Remote A copy of the repository on another computer, usually GitHub, GitLab or a company server (so you can back it up and share it)
The everyday flow, in order:
edit files > git add (put chosen changes in the waiting room) > git commit (save a snapshot) > git push (send it to the remote)
Think of it like taking a photo: you arrange the scene (edit), decide who is in the picture (add), press the shutter (commit), and then post the photo online (push).
Install Git and check it works
sudo apt install git # Ubuntu and Debian sudo dnf install git Fedora, RHEL brew install git macOS winget install Git.Git Windows
git --version # you should see something like: git version 2.43.0
One-time setup: tell Git who you are
Git stamps your name and email on every snapshot. Do this once per computer:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main # new projects start on a branch called "main"
git config --global core.editor "nano" # the editor Git opens for messages (use "vim", or "code --wait" for VS Code)
git config --list # check your settings
If you plan to use GitHub, use the email address of your GitHub account (or the private "noreply" address GitHub gives you), so your snapshots are linked to you.
Your first project (follow along)
Try this in a practice folder. Nothing here can hurt anything.
mkdir my-first-repo # make a new folder
cd my-first-repo # go into it
git init # turn this folder into a Git project
You will see: Initialized empty Git repository in /home/you/my-first-repo/.git/
echo "Hello Git" > hello.txt # create a file
git status # ask Git what it sees
You will see: Untracked files: hello.txt (Git noticed the file but is not tracking it yet)
git add hello.txt # put the file in the waiting room (the staging area)
git status
You will see: Changes to be committed: new file: hello.txt (green: ready to be saved)
git commit -m "Add hello.txt" # save the snapshot, with a short message
You will see: [main (root-commit) a1b2c3d] Add hello.txt 1 file changed, 1 insertion(+)
git log # look at your history
You will see: commit a1b2c3d... Author: Your Name <you@example.com> Date: ... Add hello.txt
Congratulations: you made a repository and saved your first snapshot. From here on it is the same loop again and again.
The loop you will repeat all day
1. Edit or create files
2. git status What changed? (Run this constantly: it is safe and tells you what to do next)
3. git diff What exactly did I change? (shows the lines)
4. git add filename Choose what goes into the next snapshot (or git add . to choose everything in this folder)
5. git commit -m "What I did" Save the snapshot
6. git push Send your snapshots to the remote (GitHub) when you have one
Get in the habit of running git status before and after every step. It never changes anything, and it always tells you where you are.
The 12 commands to learn first
git init Start tracking a folder (once per project)
git clone URL Copy an existing project from GitHub to your computer
git status Show what changed and what is staged
git diff Show the exact line changes not yet staged
git add FILE Stage a file (put it in the waiting room) git add . stage everything here
git commit -m "message" Save a snapshot of what is staged
git log --oneline Show the history, one line per snapshot
git switch -c NAME Create a new branch and move to it
git switch NAME Move to an existing branch
git merge NAME Bring another branch's work into the current branch
git pull Download the newest changes from the remote and merge them in
git push Upload your snapshots to the remote
Everything else you can look up when you need it.
Writing a good commit message
The message is a note to your future self: what did you change, and why?
Good: "Fix login button not working on mobile" "Add contact page" "Update README with install steps"
Bad: "stuff" "fixed it" "asdf" "changes"
Rules of thumb: start with a verb (Add, Fix, Update, Remove), keep the first line short (under about 50 characters), and make one snapshot for one idea.
For a longer explanation run git commit with no -m: an editor opens. Write the short summary, a blank line, then the details.
Looking at your work
git status # the most useful command. Shows changed, staged and untracked files, and which branch you are on
git status -s # a short version: M = modified, A = added, ?? = not tracked yet
git diff # changes you have NOT staged yet (press q to leave the viewer)
git diff --staged # changes that ARE staged, i.e. exactly what the next commit will contain
git log # the full history (press q to leave)
git log --oneline # one short line per commit: easier to read
git log --oneline --graph --all # a little picture of branches and merges
git show # details of the latest commit git show a1b2c3d a specific one
git log -3 # only the last 3 commits
The viewer (called a pager) opens when there is a lot of text. Use the arrow keys or Space to scroll, and press q to quit.
Staging: choosing what goes into a snapshot
git add hello.txt # one file
git add file1.txt file2.txt # a few files
git add docs/ # a whole folder
git add . # everything new or changed in this folder (check with git status first!)
git add -p # go through your changes piece by piece and answer y/n (great for keeping commits tidy)
git restore --staged hello.txt # changed your mind? take it OUT of the waiting room (your edits stay)
Why staging exists: you may have changed five files, but only two belong to the same idea. Stage those two, commit them, then stage the rest as a separate snapshot.
Ignoring files you never want to save
Some files should not go into Git: passwords, huge downloads, temporary files, and folders like node_modules. Create a file named .gitignore in your project folder and list them:
# .gitignore
.env
*.log
node_modules/
__pycache__/
.DS_Store
Then git add .gitignore and commit it. Git will now skip anything that matches. NEVER commit passwords, API keys or private keys: once saved in history they are hard to remove completely.
Branches: safe places to try things
A branch is a separate line of work. The main branch (called "main") holds your good, working version. You make a new branch to try a change, and merge it back only when it works.
git branch # list branches (the one with a * is where you are)
git switch -c add-contact-page # create a branch and move onto it
...edit files, git add, git commit (as normal: the snapshots go on THIS branch)...
git switch main # go back to main (your files change to match main!)
git merge add-contact-page # bring the finished work into main
git branch -d add-contact-page # delete the branch when you are done with it
Tip: before you switch branches, commit your work (or stash it). Your files change to match the branch you switch to. That is normal, and it is how branches work.
Older guides use git checkout for switching. It still works, but git switch is clearer.
Working with a remote (GitHub)
Get a project from GitHub:
git clone https://github.com/someone/project.git # download a copy (creates a folder named project)
cd project
Connect your own project to a new empty GitHub repository (create the repository on the GitHub website first, and copy its address):
git remote add origin https://github.com/you/my-first-repo.git
git branch -M main # make sure the branch is called main
git push -u origin main # the first push (the -u remembers where to push next time)
Every day after that:
git pull # get the newest changes from GitHub (do this BEFORE you start working)
git push # send your commits to GitHub (do this when you have finished something)
git remote -v # show the remote address Git is using
Logging in: GitHub no longer accepts your account password on the command line. Use SSH keys, the GitHub CLI (gh auth login), or a personal access token. See the GitHub cheat sheet for the easy way.
"origin" is just the nickname for the remote address. "main" is the branch name.
Working with others: a safe routine
1. git switch main and git pull Start from the newest version
2. git switch -c my-change Make a branch for your work
3. Edit files, then git add and git commit as you go
4. git push -u origin my-change Send your branch to GitHub
5. Open a Pull Request on GitHub (the page offers a green button after you push). Teammates review it, and then it is merged into main
6. Back on your computer: git switch main and git pull then delete the old branch: git branch -d my-change
Pull often. The longer you wait, the more your work and everyone else's drift apart, and the harder merging becomes.
When Git says there is a conflict (do not panic)
A conflict means two people (or two branches) changed the same lines, and Git cannot decide which version to keep. It stops and asks YOU. It is normal, and not a disaster.
1. Run git status. Files marked "both modified" are in conflict
2. Open each file. You will see markers like this:
<<<<<<< HEAD
your version of the lines
=======
the other version
>>>>>>> other-branch
3. Decide what the final text should be. Edit the file so it contains only that text, and delete all three marker lines (<<<<<<<, =======, >>>>>>>)
4. git add filename (tell Git it is fixed)
5. git commit (finish the merge. Git offers a default message: save and close the editor)
Changed your mind halfway through? git merge --abort puts everything back the way it was before the merge.
Undoing mistakes (the "oh no" guide)
Match your situation to the fix. The safest ones are first.
"I edited a file and want the old version back" (not committed yet):
git restore hello.txt (WARNING: this throws away your edits to that file. It cannot be undone)
"I staged a file by mistake":
git restore --staged hello.txt (it goes back to unstaged, and your edits stay)
"I committed, but the message is wrong" (not pushed yet):
git commit --amend -m "Better message"
"I forgot to add a file to my last commit" (not pushed yet):
git add forgotten.txt then git commit --amend --no-edit
"I want to undo my last commit but keep the work" (not pushed yet):
git reset --soft HEAD~1 (the commit disappears, and your changes are staged again, ready to recommit)
"I want to undo a commit that is already pushed or shared":
git revert a1b2c3d (makes a NEW commit that cancels the old one. Safe for shared work)
"I want to throw away EVERYTHING I did since the last commit":
git restore . (WARNING: destroys all uncommitted edits)
"I committed on the wrong branch" (not pushed yet):
git branch new-branch (keep the work on a new branch) then git reset --hard HEAD~1 (remove it from this one. --hard discards uncommitted work, so check git status first) then git switch new-branch
"I deleted a file by accident" (before committing): git restore filename
"I think I lost work!": git reflog shows where you have been, and nearly everything can be recovered. Ask for help before trying anything scary.
Golden rules: never rewrite history that other people already have (do not amend or reset commits you have pushed), and stay away from git push --force until you fully understand it.
Commands with --hard, -f or "force" in them can destroy work. Read the warning, run git status first, and if you are unsure, ask.
Saving unfinished work for later (stash)
Need to switch branches but you are not ready to commit? Tuck your changes away:
git stash # hide your uncommitted changes (your files go back to the last commit)
git stash list # see what is stashed
git stash pop # bring the changes back (and remove them from the stash)
Tags: naming a version
git tag v1.0 # label the current commit (for example a release)
git tag # list tags
git push origin v1.0 # share the tag
Words you will hear (glossary)
Repository (repo) A project folder tracked by Git, with its full history
Commit A saved snapshot, with a message, an author and a date. Each has an ID like a1b2c3d
Stage / index The waiting room for changes that will go into the next commit
Branch A separate line of work main the default main line
HEAD Where you are right now (usually the tip of your current branch)
Merge Combine the work of two branches
Conflict Two changes to the same lines that Git cannot combine by itself
Remote A copy of the repository elsewhere (GitHub) origin the usual nickname for it
Clone Download a full copy of a remote repository
Push / Pull / Fetch Upload commits / download and merge commits / download without merging
Pull request (PR) A request on GitHub to merge your branch, with a review step
Fork Your own copy of someone else's GitHub project
Untracked A file Git sees but is not watching yet
Tracked A file Git is watching for changes
.gitignore A list of files Git should skip
Detached HEAD You checked out an old commit instead of a branch (fix: git switch main)
Common errors and what to do
"fatal: not a git repository (or any of the parent directories): .git" You are not inside a Git project. cd into the folder, or run git init
"Please tell me who you are. *** Run git config --global user.email ..." Do the one-time setup above
"nothing to commit, working tree clean" Good news: nothing has changed since your last commit
"Changes not staged for commit" You edited files but did not git add them yet
"error: failed to push some refs ... Updates were rejected" The remote has newer work than you. Run git pull, fix any conflicts, then git push again
"fatal: refusing to merge unrelated histories" Two projects with no shared past. Usually a mistake: check you are in the right folder
"CONFLICT (content): Merge conflict in ..." See "When Git says there is a conflict" above
"Your local changes would be overwritten by checkout/merge" Commit them first, or use git stash, then try again
"fatal: Authentication failed" or "Permission denied (publickey)" Your login for GitHub is not set up. Use the GitHub CLI (gh auth login), SSH keys, or a token
"You are in 'detached HEAD' state" You looked at an old commit. Go back with git switch main (or, to keep changes, git switch -c new-branch)
"error: pathspec 'x' did not match any file(s) known to git" Typo in the file or branch name, or the file is not tracked. Check with git status or git branch
Git opens a strange editor (vim) and you cannot get out Press Esc, then type :wq and Enter to save and quit (or :q! to quit without saving). Or set a friendlier editor: git config --global core.editor nano
"fatal: unable to access ... Could not resolve host" No internet, or the address is mistyped
A file you meant to ignore is still tracked .gitignore only affects NEW files. Stop tracking it: git rm --cached filename then commit
I cannot see my file on GitHub You committed but did not push. Run git push. Or it is in .gitignore
Good habits (they save you from most trouble)
- Run git status all the time. It is your compass
- Commit small and often, with clear messages. Small commits are easy to understand and easy to undo
- Pull before you start working, and push when you finish something
- Use a branch for each new piece of work, and keep main working
- Look at git diff before you commit, so you know what you are saving
- Never commit passwords, keys or big files. Use .gitignore
- Do not use git push --force or git reset --hard unless you understand exactly what they will destroy
- If you are unsure, copy your project folder as a backup, and then experiment
- Practice in a throwaway folder until the loop feels natural
Practice exercise (15 minutes)
1. Make a folder, run git init, and create notes.txt with two lines of text. Add and commit it
2. Edit notes.txt, run git diff to see the change, then add and commit with a good message
3. Run git log --oneline to see both commits
4. Create a branch: git switch -c experiment. Add a third line, commit it
5. Go back: git switch main. Look at notes.txt: the third line is gone (it lives on the branch)
6. Merge it: git merge experiment. The third line is back. Delete the branch: git branch -d experiment
7. Make a mistake on purpose: add a bad line, do NOT commit, then undo it with git restore notes.txt
8. Create a free GitHub account, make an empty repository, connect it (git remote add origin ...), and push your work
9. Bonus: edit the same line on GitHub's website and on your computer, then git pull, and fix the conflict
Where to go next
- The Git cheat sheet (DevOps): more commands, rebase, stash details, worktrees, tags, bisect, and removing secrets
- The GitHub cheat sheet and GitHub Actions cheat sheet (DevOps): pull requests, the gh tool, automation
- Try a visual tool to see your history: git log --oneline --graph --all, or a program such as GitKraken, Sourcetree, or the Git features built into VS Code
- Free, excellent reading: the Pro Git book (git-scm.com/book) and the interactive lessons at learngitbranching.js.org
Tips
Run git status before and after everything. It is safe, and it always tells you what to do next.
The loop is: edit, git add, git commit, git push. Commit small and often, with a clear message.
Use branches for new work, and merge them back into main when they work.
Pull before you start, push when you finish something, and fix conflicts calmly: they are normal.
Never commit passwords or keys, and use .gitignore for files you do not want tracked.
Be careful with commands that discard work (restore, reset --hard, clean, push --force). Check git status first.
If you get stuck, copy your project folder as a backup, then ask for help. Nearly everything in Git can be recovered.
Practice in a scratch folder until the basic loop feels automatic.