These are independent study notes. They are not official documentation from the Git project, the Software Freedom Conservancy, GitHub, or Google.
git reflog
git reflog lists where HEAD has been on this computer. A checkout, a commit, a merge, and a reset each add a line. git log shows only the history still on the current branch. The reflog still shows commits that fell off that branch.
git reflog
git reflog show main
A line looks like this:
a1b2c3d HEAD@{0}: reset: moving to HEAD~1
e4f5a6b HEAD@{1}: commit: Expand the notes
HEAD@{0} is where you are now. HEAD@{1} is the position before that. The hash on the left is the commit id. That id is what you pass when you move a branch back or create a deleted branch name again.
The reflog stays on this computer. git clone and git push do not copy it. Git keeps the lines for a limited time, normally about 90 days, and git gc can drop them after that. Once the line is gone, this page's recovery steps no longer have a commit id to use.
Edits that were never committed are not in the reflog. If a command discarded those edits, git reflog cannot restore the file contents.
Undo git reset --hard
People look this up as “git reset hard undo”. The command is git reset --hard. It moves the current branch to another commit and replaces the working tree with that commit. Later commits vanish from git log. They remain in the reflog until Git expires them.
To undo a reset that just happened on this computer:
- Run
git reflogand find the line from before the reset. Right after the reset, that line is oftenHEAD@{1}. - Check it with
git show HEAD@{1} --statbefore you move anything. - Put the branch back with
git reset --hard HEAD@{1}. If other commands have run since the reset, use the hash from the reflog instead ofHEAD@{1}.
git reflog
git show HEAD@{1} --stat
git reset --hard HEAD@{1}
Use this when the reset has not been pushed, or when nobody else has built work on the commits you removed. If those commits are already on a shared remote, git revert is the undo that leaves the old history in place. A second hard reset followed by git push --force can delete commits other people already have.
Files you changed and never committed are not stored at HEAD@{1}. git reset --hard removes those edits. The reflog can point a branch at an old commit. It cannot rebuild unsaved work.
Recover a deleted branch
git branch -d name and git branch -D name remove the branch name. They do not immediately delete the commits that name pointed at. To recover a deleted branch, create the name again at the old commit.
- Run
git reflog. Look for a line that names the branch, such ascheckout: moving from feature to main. - Copy the hash at the start of that line.
- Run
git branch feature a1b2c3dwith your hash, thengit switch feature.
git reflog
git branch feature a1b2c3d
git switch feature
git log --oneline
If you pushed the branch and the remote still has it, skip the reflog:
git fetch origin
git switch -c feature origin/feature
If the remote branch was deleted as well, git fetch will not recreate the name. The local reflog is the source of the hash, and only on a computer that checked out that branch. A new clone does not contain this reflog.
When git reflog has no line for the branch, this repository no longer has a recent id for it. A new empty branch does not bring the old commits back.
What Git does
Git records changes in a folder as snapshots. Each snapshot is a commit. A commit stores the files at that moment and a short message about what changed and why.
Saving in an editor is not the same as committing. Saving overwrites the current file on disk. A commit adds that state to the history. Until you commit, there is no snapshot to return to.
That history lets you do three things:
- Compare an older commit with the files you have now.
- Split an experiment onto a branch, away from the main line.
- Send that history to another repository, and receive history from it.
Git is not the name of a website that stores your files. GitHub and GitLab are hosts that keep a Git repository for you. You can commit on your own computer with no internet connection.
Three places your files live
- Working tree The files you are editing
- Staging area Changes chosen for the next commit
- Repository The history of commits
git add moves a change from the working tree to the staging area. git commit moves what is staged into the repository.The staging area is also called the index. It holds only the changes you want in the next commit. Anything you leave unstaged stays out of that commit.
That is how each commit can have one reason. If you git add only the files you changed for this step, other files that are still untouched stay out of the commit.
A normal working sequence
- Run
git statusto see what changed. git addonly the files you want to record.- Run
git commit -m "message"to save the snapshot. - Run
git logto confirm the commit is there.
When you are unsure, run git status before any other command. It describes uncommitted changes, staged changes, and the current branch in plain sentences.
git diff shows unstaged changes line by line. git diff --staged shows only what the next commit will contain.
Commit messages
One line is enough. Say what changed. Add why, when the reason does not fit in the same few words.
- Clear:
Fix off-by-one in page count - Hard to use later:
update,asdf
Follow your team's format when it has one. git commit --amend can replace the message of the latest commit. Do not amend a commit you have already pushed. The other copy of the history will no longer match.
Commands you will use often
| Command | What it does |
|---|---|
git init | Makes this folder a repository. |
git status | Shows what changed and which branch you are on. |
git add file | Stages that file's changes for the next commit. |
git commit -m "message" | Saves a snapshot of what is staged. |
git log --oneline | Lists commits, one per line, newest first. |
git diff | Shows changes that are not staged yet. |
git branch | Lists local branches. |
git reflog | Shows recent HEAD positions, including commits no longer on the branch. |
git reset --hard HEAD@{1} | Moves the branch to the previous reflog entry. This restores committed work only. |
git branch name hash | Creates a branch at that commit, which restores a deleted branch name. |
git --version | Prints the installed Git version. |
Branches
A branch is a name that points at one commit. It is not a second copy of the folder. The name main often points at the latest stable commit.
HEAD is where you are checked out. It is usually the latest commit on the current branch.
Start new work by creating a branch and committing there. Merge it into main when the result is ready. To drop the experiment, delete that branch name. Commits that were never merged do not become part of main.
git switch -c feature
# Edit files, then add and commit
git switch main
git merge feature
Lines that start with # are notes. You do not need to type them in PowerShell or bash. On Git older than 2.23, git checkout -b feature does the same job as git switch -c feature: it creates the branch and moves you onto it.
When the same lines were edited both ways
If the two sides changed different parts of a file, Git joins them. If they changed the same lines, you get a conflict, and the file contains markers like these:
<<<<<<< HEAD
contents from the current branch
=======
contents from the branch you are merging
>>>>>>> feature
Keep the text you want and delete the three marker lines. Then git add and git commit finish the merge. A conflict means a person has to choose the result. The command has not failed.
Remotes
A remote is another copy of the same project, stored somewhere else. Its default name is often origin. git remote -v shows the name and the address.
git clone URL— downloads the repository, including its history, for the first time.git fetch— downloads new commits and does not merge them into your files.git pull— fetches, then merges into the current branch.git push— sends your commits to the remote.
# The address below is an example. Use your real repository URL.
git clone https://example.com/team/notes.git
cd notes
git pull
git push
git push sends committed history only. Changes you have added but not committed stay on your machine.
If someone else pushed to the same branch first, your push can be rejected. Pull their commits, then push again. Do not answer that rejection with git push --force. A force push can erase commits other people already have.
Undoing work
The command depends on the situation. Before you throw anything away, check where you are with git status and git log --oneline.
| Situation | Direction |
|---|---|
| Unstage a file and keep its contents | git restore --staged file |
| Discard uncommitted edits in a file | git restore file. Edits since the last commit of that file are removed. |
| Undo a commit you already shared | git revert commit. This adds a new commit that reverses the change, and leaves the old history in place. |
To undo a local git reset --hard, or to put a deleted branch name back, start with git reflog. The steps are in Undo git reset --hard and Recover a deleted branch. Prefer git revert when the commit has already been pushed.
Files to keep out of history
A .gitignore file in the repository root lists patterns that git status should stay quiet about.
.DS_Store
.env
node_modules/
.env— passwords and API keysnode_modules/— dependencies you can install again.DS_Store— extra folder files created by macOS
Adding a file to .gitignore does not remove it from commits that already exist. If you committed a secret, retire that secret and issue a new one. Deleting the file now leaves the old value in earlier commits.
Common mistakes
- Committing without
git status, so a needed file is missing or a log file is included. - Committing
.envor a key file. - Experimenting directly on
main, so unfinished work lands on the stable line. - Rewriting a pushed commit with amend or a force push.
- Leaving the message as
fix, so the reason is gone later.
Try it
Use a new folder. Practicing inside a project that already has files makes those files the subject. If Git is not installed, use the official Git download. This page does not provide an installer.
Lines that start with # are notes. Check your version with git --version.
mkdir git-notes
cd git-notes
git init
git status
If the commit asks you to set a name, run the next two commands in this practice folder only. Skip them when git config user.name already prints a value. The name and email are stored in the commit history on your machine. This website never receives them.
git config user.name "Your Name"
git config user.email "you@example.com"
Create note.txt and write What I learned today.
git add note.txt
git commit -m "Add class notes"
git log --oneline
git switch -c draft
Add one more line to note.txt.
git add note.txt
git commit -m "Expand the notes"
git switch main
git merge draft
git log --oneline
The exercise is done when the log shows two commits. The folder exists only on your computer. Publishing it means creating an empty repository on a host and connecting a remote. This page does not create that account.
Check yourself
Four questions. Scoring happens in this browser only. The answers are not sent anywhere.
Answers and why
git addchooses what the next commit will contain.git pushis the command that sends commits to a remote.- A commit records history in the local repository. The remote receives it only after a push.
- A branch is a name for a commit, not a copy of the folder.
- For a shared commit,
git revertadds a commit that undoes it. A force push can delete history other people already received.
Terms
- Repository
- A project with commit history and Git settings. The history usually lives in a
.gitfolder. - Commit
- A snapshot of one moment, plus its message.
- Hash
- The id of a commit.
git logshows a short hexadecimal form. - Branch
- A name that points at a commit and moves to the new tip when you commit again.
- HEAD
- Where you are working now.
- Merge
- Joining the changes from two lines of history.
- Remote
- A repository stored somewhere else. You receive it first with clone, then exchange commits with pull and push.
About this guide
This page is a short picture of Git for someone using it for the first time, before the official manual. It does not sell a course, issue a certificate, or distribute an installer.
It covers a local repository, commits, branches, merges, remotes, and how git reflog finds a commit after a local git reset --hard or a deleted branch. It does not cover submodules, Git LFS, running a server, rewriting shared history with rebase, or the screens of a particular host.
For the exact behavior of a command, use the official Git documentation. This page is an introduction, so it leaves out options and exceptions.
Last updated:
Privacy
This page is a static document. It has no accounts.
- There is no signup, newsletter, or contact form. The page does not ask for your name, email, or payment details.
- This page loads one Google tag, AW-18503919736, to measure visits that come from a Google ad. Google may set a cookie in your browser for that measurement. This site does not run its own account system.
- Quiz answers are not sent to a server. Check answers calculates the score in this browser.
- The host that serves the page may keep access logs, such as the time, IP address, and browser type. How long those logs are kept is up to that host. This guide has no separate database of visitors.
- There is no account data here to access or delete.
- The page does not collect personal information from children.
The Google tag above is the only third-party script on this page. If another script is added, this notice will be updated first.
Contact
Enrollment, payment, and account recovery are not features of this page. It does not handle those requests.
If an explanation here and the official documentation disagree, follow the official Git documentation.