Create a repository
git initTurns the current folder into a Git repository with an empty history. Nothing is tracked until you add and commit it.
git initArticleFree · customizable · printable
Stuck on a Git command or need a quick refresher? We used git-sim to build an animated cheat sheet with every Git command you could possibly need.
(because only you know which commands you always forget...)
A repository is a project folder with its history in a hidden .git folder. Make a new one, or copy one that already exists.
git initTurns the current folder into a Git repository with an empty history. Nothing is tracked until you add and commit it.
git initArticlegit clone <url>Downloads a repository with its whole history into a new folder, and remembers where it came from as origin.
git clone ../your_project.git your_project_copyArticlegit clone --depth 1 <url>Makes a shallow clone with just the newest commit, so a big repository downloads fast. Any number of commits works.
git clone --depth 3 ../your_project.git your_project_copygit clone -b <branch> <url>Clones the repository and checks out <branch> instead of the remote's default branch.
git clone -b feature ../your_project.git your_project_copySettings made with --global apply to every repository on your computer and live in ~/.gitconfig. Leave out --global to set something for the current repository only.
git config --global user.name "<name>"Every commit records who made it. Set your name and email once per computer.
git config user.name "Jacob Stopak"Articlegit config --global user.email "<email>"Records your email in every commit you make. Use the one your Git host knows, so it links the commits to your account.
git config --global user.email "jacob@initialcommit.io"git config --global --unset user.emailgit config --global init.defaultBranch mainMakes git init start every new repository on a branch called main instead of master.
git config --global init.defaultBranch maingit config --global core.editor "code --wait"Sets the editor Git opens for commit messages and interactive rebases. This one is VS Code.
git config --global core.editor "code --wait"git config --listPrints every setting Git is using here, from the system, global and repository config files.
git config --listgit config --global alias.<name> <command>Creates your own Git command. After alias.st status, typing git st runs git status.
git config --global alias.st statusgit config --global pull.rebase trueMakes every git pull rebase your local commits on top of what came down, with no merge commits.
git config --global pull.rebase truegit config --global fetch.prune trueMakes every git fetch remove origin/<branch> labels for branches deleted on the remote.
git config --global fetch.prune truegit config --global core.autocrlf trueOn Windows, Git converts line endings to CRLF when checking files out and back to LF when committing.
git config --global core.autocrlf truegit config --global credential.helper <helper>Saves your username and password or token, so Git stops asking on every push and pull.
git config --global credential.helper cacheGit saves your work in two moves: you stage the changes you want, then commit them as one snapshot.
git statusLists what's staged for the next commit, what's changed but not staged, and files Git isn't tracking yet.
git statusArticlegit add <file>Puts the file's current changes in the staging area, ready for the next commit.
git add app.py notes.txtArticlegit commit -m "<message>"Saves everything in the staging area as a new commit, and moves the current branch to it.
git commit -m "Describe the project in the README"Articlegit reset --soft HEAD~1git commit -am "<message>"Stages every change to files Git already tracks, then commits. New files still need git add first.
git commit -a -m "Tweak the app and the header"Articlegit reset --soft HEAD~1Delete, rename, untrack and ignore files, and clear out the ones Git doesn't track.
git rm <file>Deletes the file and stages the deletion, so the next commit removes it from the project.
git rm login.htmlArticlegit restore --staged --worktree <file>git rm --cached <file>Takes the file out of Git but leaves it on disk. Add it to .gitignore so it stays out.
git rm --cached .envArticlegit add <file>git mv <old> <new>Renames the file and stages the rename in one step.
git mv app.py main.pyArticlegit mv <new> <old>git check-ignore -v <file>Prints the .gitignore file, line number and rule that ignores the file. Prints nothing if it isn't ignored.
git check-ignore -v debug.log build/app.js app.pygit clean -fDeletes every file Git isn't tracking. Add -d to delete untracked folders too.
git clean -fArticlegit clean -n first to preview.git clean -fdxDeletes every untracked file and folder, including the ones .gitignore hides, like build output and .env files.
git clean -fdxgit clean -ndx first to preview.Every commit keeps its author, date and changes. These commands list them, filter them and search through them. None of them change anything.
git logLists the commits on the current branch, newest first, with their hash, author, date and message.
git logArticlegit log --allIncludes the commits of every branch, not just the one you're on.
git log --allgit log --oneline --graph --allDraws the history of every branch as a text graph, one line per commit, with the branch labels on it.
git log --oneline --graph --allgit log -p <file>Lists the commits that changed the file, each with the lines it added and removed.
git log -p app.pygit log --follow <file>Keeps listing the file's commits past the point where it was renamed. Without --follow the history stops there.
git log --follow main.pygit log -S "<text>"Lists the commits that changed how many times <text> appears, which is where it was added or removed.
git log -S "logging"git log --author "<name>"Lists only the commits whose author's name or email contains <name>.
git log --author "Ada"git log --since "2 weeks ago" --until "yesterday"Lists only the commits made in that window. Dates like 2024-05-01 work too.
git log --since "2024-05-01 11:00 +0000" --until "2024-05-01 13:00 +0000"git show <commit>Shows a commit's message and the changes it made.
git show HEAD~1Articlegit blame <file>Prints the file with the commit, author and date that last changed each line.
git blame app.pyArticlegit shortlog -snLists everyone who made commits on the current branch, with how many each, most first.
git shortlog -sngit describePrints a name like v1.0-2-g1a2b3c4: the latest tag, how many commits since it, and the commit's short hash.
git describegit grep -n "<text>"Finds <text> in every tracked file and prints each matching line with its file and line number.
git grep -n logginggit bisect start <bad> <good>Checks out the commit halfway between a bad one and a good one. Mark each test with git bisect good or git bisect bad until Git names the culprit.
git bisect start HEAD 4114b2cArticleSee exactly which lines changed between your files, the staging area, commits and branches. Nothing is changed.
git diffShows the lines you've changed but haven't staged yet.
git diffArticlegit diff --stagedShows the lines you've staged, which is exactly what the next commit will contain.
git diff --stagedgit diff <commit> <commit>Shows everything that changed between two commits, branches or tags.
git diff HEAD~2 HEADgit diff <branch>..<branch>Shows every difference between the tips of the two branches.
git diff main..featuregit diff --statLists each changed file with how many lines were added and removed, instead of the lines themselves.
git diff --statA branch is a movable label on a commit, and HEAD marks the one you're on. Branches are cheap, so make one for every piece of work.
git branch <name>Puts a new branch label on the current commit. You stay on the branch you're on.
git branch bugfix-headerArticlegit branch -aLists your local branches, then the remote-tracking ones like remotes/origin/main. The * marks the one you're on.
git branch -agit branch -vvLists each branch with its latest commit and the remote branch it tracks, like [origin/main: ahead 1, behind 2].
git branch -vvgit branch --mergedLists the branches whose commits are all in the current branch already.
git branch --mergedgit branch --no-mergedLists the branches that have commits the current branch doesn't. Deleting one needs -D.
git branch --no-mergedgit switch <branch>Moves HEAD to the branch and updates your files to match its latest commit.
git switch featureArticlegit switch -Goes back to whichever branch you were on before this one. Run it again to flip back.
git switch -git switch <branch>When only origin/<branch> exists, Git creates a local branch from it that tracks it, and switches to it.
git switch featuregit switch -c <name>Creates the branch on the current commit and switches to it in one step.
git switch -c hotfixArticlegit switch -c <name> <start>Creates the branch at <start>, which can be a commit, a tag or a branch like origin/main, and switches to it.
git switch -c search origin/featuregit branch -m <old> <new>Moves the label to a new name. The commits don't change.
git branch -m feature searchArticlegit branch -m <new> <old>git branch -d <name>Removes the label. Git refuses if the branch has commits that aren't merged anywhere.
git branch -d docsArticlegit branch <name> <hash>git branch -D <name>Removes the label even when its commits aren't merged. Only the reflog still knows them.
git branch -D featureArticlegit branch <name> <hash>git switch --detach <commit>Moves HEAD onto the commit itself, not a branch (a detached HEAD). Good for looking around.
git switch --detach 96c4fc2ArticleA merge brings another branch's work into yours and keeps the history as it happened.
git merge <branch>Brings the branch's commits into yours with a merge commit that has two parents.
git merge featureArticlegit reset --hard ORIG_HEADgit merge <branch>When your branch has nothing of its own, Git just slides its label forward (a fast-forward). No merge commit.
git merge mainArticlegit merge --no-ff <branch>Makes a merge commit even when a fast-forward would do, so the branch still shows in history.
git merge --no-ff mainArticlegit reset --hard ORIG_HEADgit merge --squash <branch>Stages all of the branch's changes without committing. Your next commit holds them as one.
git merge --squash featureArticlegit merge --continueOnce you've fixed the conflicted files and staged them with git add, this makes the merge commit.
git merge --continueArticlegit merge --abortStops the merge and puts everything back the way it was before it started.
git merge --abortArticleRun the merge againA rebase replays your commits on top of another branch, so the history reads as one line. A cherry-pick copies single commits the same way.
git rebase <branch>Copies your branch's commits onto the tip of <branch>, one by one, as new commits with new hashes.
git rebase mainArticlegit reset --hard ORIG_HEADgit rebase -i <base>Opens a list of your commits after <base>. Change pick to squash, reword or drop, or reorder the lines.
git rebase -i mainArticlegit reset --hard ORIG_HEADgit rebase --onto <new-base> <old-base>Moves only the commits after <old-base> onto <new-base>, leaving the rest behind.
git rebase --onto main featureArticlegit reset --hard ORIG_HEADgit rebase --continueOnce the conflict is fixed and staged, this commits it and replays the rest.
git rebase --continueArticlegit rebase --skipLeaves out the commit that stopped the rebase and carries on with the rest.
git rebase --skipArticlegit rebase --abortStops the rebase and returns the branch to where it was before it started.
git rebase --abortArticleRun the rebase againgit cherry-pick <commit>Applies the changes of one commit from anywhere as a new commit on your branch.
git cherry-pick fc19889Articlegit reset --hard HEAD~1git cherry-pick <from>..<to>Copies every commit after <from> up to <to>, in order.
git cherry-pick 96c4fc2..featureArticleA remote is a named link to another copy of the repository, usually on GitHub or a server. A clone starts with one called origin.
git remote add <name> <url>Gives a remote repository a short name, so you can fetch from it and push to it.
git remote add upstream ../your_project.gitArticlegit remote -vLists each remote with the URL Git fetches from and the one it pushes to.
git remote -vgit remote show originAsks the remote for its branches and shows which ones you track, which are new, and what git pull and git push do for each of yours.
git remote show origingit remote set-url <name> <url>Points the remote at a new address, like after a repository moves or you switch from HTTPS to SSH.
git remote set-url origin ../shop.gitgit remote set-url <name> <old-url>git remote rename <old> <new>Renames the remote, and its remote-tracking branches and branch settings with it.
git remote rename origin upstreamgit remote rename <new> <old>git remote remove <name>Deletes the link to the remote and its remote-tracking branches. The remote repository itself isn't touched.
git remote remove origingit remote add <name> <url>git ls-remoteAsks the remote for every branch and tag it has and the commit each points to. Nothing is downloaded.
git ls-remotegit branch -u origin/<branch>Sets the remote branch your current branch tracks, so plain git pull and git push know where to go.
git branch -u origin/featureFetch and pull bring a remote's new commits down, and push sends yours up.
git fetchDownloads what's new on the remote and updates origin/<branch>. Your own branches and files don't change.
git fetchArticlegit fetch --allFetches from each remote in turn, like origin and upstream in a fork, and updates all their remote-tracking branches.
git fetch --allgit fetch --pruneFetches, then removes origin/<branch> labels for branches that were deleted on the remote.
git fetch --pruneArticlegit pullFetches, then merges the remote branch into yours. Makes a merge commit when both sides have new commits.
git pullArticlegit reset --hard ORIG_HEADgit pull origin <branch>Fetches <branch> from origin and merges it into the branch you're on, whatever that branch tracks.
git pull origin maingit reset --hard ORIG_HEADgit pull --rebaseFetches, then replays your local commits on top of what came down, so history stays in one line.
git pull --rebaseArticlegit pushSends your branch's new commits to the remote branch it tracks.
git pushArticlegit push -u origin <branch>Creates the branch on the remote and links yours to it, so plain git push and git pull work from then on.
git push -u origin hotfixArticlegit push --force-with-leaseReplaces the remote branch with yours after a rebase or amend, but refuses if someone pushed since you last fetched.
git push --force-with-leaseArticlegit push --forceReplaces the remote branch with yours, whatever is there.
git push --forceArticle--force-with-lease instead.git push origin --delete <branch>Removes the branch from the remote. Your local branch stays.
git push origin --delete featureArticlegit push origin <branch>A tag is a permanent label on a commit, usually a release like v1.0. Unlike a branch it never moves, and it stays in your repository until you push it.
git tag <name>Puts a permanent label, like v1.0, on the current commit. Unlike a branch, a tag never moves.
git tag v1.0Articlegit tag -a <name> -m "<message>"Makes an annotated tag, which stores who tagged it, when, and a message. Use these for releases.
git tag -a v1.0 -m "First release"git tag -d <name>git tag -lLists every tag in alphabetical order.
git tag -lgit tag -d <name>Removes the tag from your repository. The commit stays.
git tag -d v1.0Articlegit push origin <tag>Sends a single tag, and any commits it needs, to the remote.
git push origin v1.1git push origin --delete <tag>git push --tagsTags stay local until you push them. This sends every tag the remote doesn't have.
git push --tagsArticlegit push origin --delete <tag>Removes the tag from the remote. Your local tag stays until you run git tag -d <tag>.
git push origin --delete v1.0git push origin <tag>The stash is a shelf for changes you're not ready to commit, so you can switch branches with a clean working directory.
git stashSaves your staged and unstaged changes on the stash and resets the working directory to the last commit.
git stashArticlegit stash popgit stash -uStashes untracked files along with your changes. Plain git stash leaves them where they are.
git stash -uArticlegit stash popgit stash push -m "<message>"Stashes your changes under a message of your own, so git stash list tells you what each entry is.
git stash push -m "Try a grid header"git stash popgit stash push <file>Stashes the changes to the files you name and leaves every other change where it is.
git stash push styles.cssgit stash popgit stash listShows every stash entry, newest first, as stash@{0}, stash@{1} and so on.
git stash listArticlegit stash popApplies the newest entry to your files and removes it from the stash.
git stash popArticlegit stash applyApplies the newest entry but leaves it on the stash, so you can apply it again elsewhere.
git stash applyArticlegit stash dropDeletes the newest entry. Name one to drop, like stash@{1}.
git stash dropArticlegit stash apply <hash> brings it back until Git cleans it up.git stash show -pShows the changes the newest entry holds, line by line. Name an entry to look at another, like stash@{1}.
git stash show -pgit stash branch <name>Creates a branch at the commit you stashed from, applies the entry there and drops it. Good when the stash no longer applies cleanly.
git stash branch try-hellogit stashgit stash clearEmpties the stash, deleting every entry at once.
git stash cleargit stash list first.A worktree is a second folder checked out from the same repository, so you can work on two branches at once without switching back and forth.
git worktree add <folder> <branch>Checks the branch out in a second folder that shares this repository, so you don't have to switch back and forth.
git worktree add ../hotfix-tree featureArticlegit worktree listLists every folder checked out from this repository, with its commit and branch.
git worktree listgit worktree pruneClears Git's record of worktrees whose folders no longer exist, so their branches can be checked out again.
git worktree pruneMost mistakes in Git can be undone, as long as you know which command undoes what. The badge on each card says what's at stake.
git restore --staged <file>Takes the file out of the next commit. Your edits stay in the file.
git restore --staged README.mdArticlegit restore <file>Puts the file back the way it was at the last commit. git restore . does every file.
git restore app.pyArticlegit stash first if you're not sure.git restore .Puts every file in the current folder back the way it was at the last commit. Staged changes stay staged.
git restore .git clean for those.git checkout -- .The command Git had before restore. The -- means what follows is a file or folder, not a branch.
git checkout -- .git restore --source <commit> <file>Replaces the file in your working directory with its version from <commit>. Commit it to keep the old version.
git restore --source HEAD~1 app.pygit restore <file>git commit --amendReplaces the last commit with a new one. Stage a forgotten file first, or change the message with -m.
git commit --amend -m "Update dependencies and README"Articlegit reset --soft HEAD@{1}git reset --soft HEAD~1Moves the branch back one commit. The commit's changes wait in the staging area, ready to commit again.
git reset --soft HEAD~1Articlegit reset --soft ORIG_HEADgit reset HEAD~1Moves the branch back one commit and unstages its changes. The files keep every edit.
git reset HEAD~1Articlegit reset ORIG_HEADgit reset --hard <commit>Moves the branch to <commit> and makes the staging area and every file match it.
git reset --hard HEAD~2Articlegit reset --hard ORIG_HEADgit reset --hard origin/<branch>Throws away your local commits and changes on the branch and moves it to where the remote's is. Run git fetch first.
git reset --hard origin/maingit reset --hard ORIG_HEADgit revert <commit>Adds a new commit that reverses <commit>. History stays intact, so it's safe on a shared branch.
git revert HEADArticlegit revert <the new commit>git revert -m 1 <merge>Reverses everything a merge brought in. -m 1 keeps the side you merged into.
git revert -m 1 HEADArticlegit revert <the revert commit>git revert --no-commit <from>..<to>Reverses every commit after <from> up to <to> and stages the result without committing, so one commit undoes them all.
git revert --no-commit HEAD~2..HEADgit revert --abortgit reflogLists every commit HEAD has pointed to, including ones no branch reaches anymore. Copy the hash you need.
git reflogArticlegit reset --hard HEAD@{1}HEAD@{1} is wherever HEAD was one move ago, so this jumps back past the reset that lost your commits.
git reset --hard HEAD@{1}reset --hard, it discards uncommitted edits.git branch <name> <hash>Git prints the hash when it deletes a branch. Point a new branch at it and nothing is lost.
git branch feature 1117a34Nothing matches that search.
Build your own Git cheat sheet in 3 steps
Git Cheat Sheet: 12 Essential Git Commands for Intermediate Users
In this article, we’ll discuss 12 essential Git commands for intermediate users.
Git cheat sheet: 12 essential Git commands for beginners
In this article, I will explain 12 essential Git commands that are especially important for a beginner.