Table of Contents
Introduction
The most common and essential git commands explained/refreshed, like some sort of cheat-sheet. I used git Bash for these commands. I follow these conventions:
- Variables are displayed between < and >. So <branch> means you have to specify your own branch name, without the ‘arrows’ < >.
- Optional flags/parameters I have displayed between ( and ). So (–force) means –force could be added to force this command, without the parenthesis ().
- I use the | (vertical bar) to point out choices, so it reads like “or”.
git branch -f <branch> <to-branch|commit-hash>
This means <branch> will now point to another branch or another commit-hash of your choosing. I use [] when the choice is in the middle of a command. - I have names like <to-branch> it means another branch name.
- With “n” I mean an integer, as in ^n or ~n.
- This means an optional variable (as parameter) filename: (<filename>).
- Where I use origin for remote, this could be another name as well. I do not use <remote> everywhere, sometimes just origin.
Remember that each command has usually several more flags and options you can use. Also keep in mind that commands work from the perspective of the current path you are on and the current branch you are in. You can always check the current branch you’re on with git branch
and the current path with the bash command: pwd
General commands
Command | Result |
git init | Create local git repository of current directory. |
git clone <repository> | Clones the repository to the local computer. |
git fetch | Download commits from remote that local branch does not have. |
git log | See history of commits (Exit by pressing ‘q’). (Commit hashes will be visible as well) |
git add . | Set all that is not ignored (in .gitignore) to staging area. |
git add <filename> | Add specific file to staging area. |
git commit -m "Commit message" | Make a commit from the files in the staging area with a message. |
git commit --amend (-m "New message") | Change the latest commit message. |
git push <remote> <branch> | Push commits to remote repository. |
git status | See the current status of your files. |
git restore <file-path> | Discard changes in your working directory for this file. Careful, this is irreversible. |
git restore --staged <file-path> | Unstage changes. (Reverses git add ) |
git stash | Stash changes without committing. |
git stash pop | Retrieve stashed changes. |
git clean -f | Use with caution! Git clean removes all untracked files in your repository! |
git clean -n (-fd) | See what git clean would have done (dry run). -d is for directories as well. |
git diff (<filename>) | Shows changes you haven’t yet staged. (Filename is optional) |
git diff --staged (<filename>) | Show staged changes you haven’t yet committed. |
git diff <branch> <branch2> (<filename>) | Compares changed between two branches. |
git reset | Remove all files from staging area. |
git reset HEAD <filename> | Undoes git add. |
git reset -- <filename> | Remove file from staging area. Same as git reset HEAD <filename>. |
git reset HEAD~n | Uncommits the last n commits. |
git reset --hard | Resets everything so it reflects the latest commit. All changes are gone. |
git revert HEAD~n | <commit-hash> | Instead of removing a commit, it creates a new commit based on revert parameter that undoes the changes. |
git merge <branch> | Merges <branch> into the current branch you’re on. (More about merging) |
git rm (-r) --cached <file|directory> | Untrack file. You can use -r for untracking an entire directory recursively. |
git rm <filename> | Remove file from version control (next commit) and from working directory. |
git cherry-pick <commit-hash> (<commit-hash-2> ... etc) | Select a one or more commits (with <commit-hash>) and apply it as new commit(s) on your current branch. This often needs resolving merge conflicts. You can setup a merge tool for that. After resolving each conflict you can use: git add <file> before continuing. |
git cherry-pick --abort | --continue | Abort or continue cherry picking. |
git cherry-pick <older-commit-hash>^..<newer-commit-hash> | Cherry picks the entire range of commits, one by one. You can use git mergetool for each conflict. Then git add . then git cherry-pick --continue and so on. You can always abort if needed. |
git mergetool | Use the configured merge-tool to resolve conflicts. |
Branch
A branch in git is like a parallel timeline. You can go in a separate direction with your project, without losing your original data. You can merge the timelines later if you want.
Command | Result |
git branch -a | List all branches. |
git branch <branch> | Create a new branch with specified name. |
git branch -d (--force) <branch> | Delete specified branch. |
git branch -f <branch> <to-branch|commit-hash> | Make <branch> point to another branch or commit hash. |
git branch <new-branch-name> <commit-hash> | Make new branch based on specific commit. |
git branch <new-branch-name> main~^2~ | Create a new branch based on the main branch, but move one commit up, then second parent of a merge (the other branch than its own), then one up. Use git checkout <branch> to reset detached head state. |
git branch -f <branch> (HEAD~n | <commit-hash>) | Move <branch> to a specific commit n parents behind or to a specific commit-hash. Tthis only works with -f for an existing branch. The tip of that branch will now be on that commit. |
git push origin --delete <branch> | Removes <branch> on remote. |
Checkout
You checkout a specific commit (on a specific branch) so your local files (working directory) will now reflect that commit.
Command | Result |
git checkout <branch> | Checkout a branch, your local files (working directory) will now reflect the commit that has been checked out. |
git checkout <tag-name> | Checks out a commit with specified tag-name. |
git checkout <commit-hash> | Checkout a specific commit. HEAD is now detached. |
git checkout -b <new-branch-name> | Create and checkout new branch (shortcut) |
git checkout <branch> ^n | Move HEAD to n parent (n=integer). 1=typically same branch, where 2=merged branch. |
git checkout -- <file-path> | Checkout the version of the file from your last commit. |
git checkout HEAD~n | Follow the first parent of HEAD n times. |
git checkout HEAD^1 | First parent of current HEAD commit. |
git checkout HEAD^2 | Second parent of current HEAD commit. This is the branch that merged with the current branch you are on. |
Rebase
With rebase you can squash several commits into one and place one branch onto another.
Command | |
git rebase <branch> | It places the current branch you’re on entirely on top of <branch>. So if you’re on the dev branch, use git rebase main to put it on top of main. Merge conflicts need to be resolved. You can then merge into main to sync it all. |
git rebase <branch A> <branch B> | Rebases commits from branch A on top of branch B. |
git rebase --continue | If you had to resolve conflicts you can continue. |
git rebase --abort | Abort rebase attempt. |
git rebase -i | Interactive rebase. |
git rebase -i <branch> | Find the common ancestor when running this from another branch than <branch>. If an editor is opened, you can alter the pick in the front of each line (except the first line) and edit it to squash. Save the file. Squashed commits will combine them into one commit. |
git rebase -i HEAD~n | You can squash latest n commits into one. |
git push --force-with-lease origin <branch> | Squashed commits need to be forced to be able to push to remote. You could use --force, but that would overwrite remote regardless of its state, it would remove commits from others that could have been pushed in the meantime. |
Remote
Command | Result |
git push <remote> <branch> | Push commits to remote repository. (Usually the default for remote is origin) |
git push -u origin HEAD|<branch> | Creates the local branch on remote as well. You can have the local branch point to another branch name on remote, but I would not encourage to do so. |
git push origin --delete <branch> | Deletes branch on remote. |
git fetch (--all) | Fetch (all) branches from remote. |
git pull (--all) | Pull (all) branches from remote. (Basically fetch + merge) |
git branch -u <origin/branch> (<branch>) | Without the optional branch at the end, this will make the current local branch track the remote branch. Otherwise, it will make <branch> track the remote branch, even when you’re not currently on that branch. |
git branch --unset-upstream (<branch>) | Removes upstream tracking of current branch or <branch> if provided. |
git push origin <local-branch>:<remote-branch> | Push commits from local branch to specific remote branch. |
git push origin --delete <branch> | Removes <branch> on remote. |
git branch -vv | See which local branch tracks which remote branch. |
Tags
Command | Result |
git tag <tagname> (<commit-hash>) | Tag a commit with a message. Tags current commit it <commit-hash> is not used. (Lightweight tag) |
git tag -a <tagname> (<commit-hash>) -m "Tag message" | Annotated tag. This includes extra metadata. |
git tag -l | -n | List tags. |
git tag -d <tagname> | Delete tag locally. |
git describe (<commit-hash>) | Finds the most recent tag that is reachable from a commit. |
git push origin --delete <tagname> | Delete tag on remote. |
git show <tagname> | Show information about the commit with this tag. |
Setup git mergetool
I’ve had a post about resolving a git conflict with a merge tool, but for completeness I add it here as well.
# Setup a text editor accordingly
git config --global core.editor notepad
# Open the config file
git config --global -e
BashUse the program of your choice for resolving merge conflicts. The content of the core.editor file:
[merge]
tool = kdiff3
[mergetool "kdiff3"]
path = C:/Program Files/KDiff3/kdiff3.exe
trustExitCode = false
[diff]
guitool = kdiff3
[difftool "kdiff3"]
path = C:/Program Files/KDiff3/kdiff3.exe
trustExitCode = false
# Resolve the merge conflict with the mergetool you configured
git mergetool
BashAccess tokens (Bitbucket & Github)
I refer to earlier posts:
- How to Setup a Repository Access Token With Bitbucket and Git
- How to Setup a Personal Access Token for a GitHub Repository
Conclusion
Git is a brilliant tool for version control, but in my opinion definitely not easy to learn. If you don’t use git too often, you can also easily forget the essential commands. I hope to have created a practical reference that covers the most useful basic commands of git.