This is an old revision of the document!
Table of Contents
Git Cheat-Sheet
A lot of this info was collected from the following sources as I used them myself to learn Git.
- https://git-scm.com/doc - Comprehensive and well organized documentation.
- https://githowto.com - A hands-on tutorial that is a wonderful learning tool for beginners.
- https://www.atlassian.com/git/tutorials - More great tutorials here.
- https://help.github.com - GitHub documentation.
I was using git version 2.16.2.windows.1
in the Bash shell while documenting and testing these commands.
First Time Configuration
After installing Git on a new system, there are a few things that should be setup first.
For further configuration options, see the Git documentation.
Set name and e-mail address for commits
git config --global user.name "First Last" git config --global user.email "email@domain.com"
Set handling of line endings
# For Windows git config --global core.autocrlf true git config --global core.safecrlf true # For Mac/Unix git config --global core.autocrlf input git config --global core.safecrlf true
Set alias for pretty log output
More helpful aliases are demonstrated here.
This log command will give nice and pretty output:
git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
It can be configured in to a global alias like so:
git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
So now it's simply enough to do:
git hist # or for all branches git hist --all
Visual Studio Code as Git editor and diff tool
More info here about Git integration with Visual Studio Code.
Set Visual Studio Code as the default Git editor, and configure it to wait for the editor to close before continuing:
git config --global core.editor "code --wait"
Now it's possible to edit the Git config in Visual Studio Code like so:
git config --global -e
Leveraging the above, add the following to .gitconfig
:
[diff] tool = default-difftool [difftool "default-difftool"] cmd = code --wait --diff $LOCAL $REMOTE
Review Git Configuration
# show all configuration settings git config -l # show global settings only git config --global -l # show system settings only git config --system -l # show repo settings only (must be in repo folder) git config --local -l
Create and Clone Repos
A repo is created with git init
, and cloned with git clone
.
Create a repo in the current folder:
git init
Create a repo in the folder MyRepo
(folder will be created if it doesn't exist):
git init MyRepo
From the parent folder, it's possible to clone a repo with:
git clone <origin> <dest> # ex: git clone MyRepo cloned_MyRepo
NOTE: A cloned repo will have a single master
branch and remote branches tracked from the origin repo.
Bare Repos
Doing git init
or git clone
commands with the –bare
switch will make a repo without a working directory, only Git data. A bare repo is intended for sharing (fetch/push/pull) only.
It's common for bare repos to have the suffix .git
.
# create a new bare repo in current folder git init --bare # create a new bare repo in folder MyRepo.git git init --bare MyRepo.git # clone repo MyRepo into a bare repo MyRepo.git git clone --bare MyRepo MyRepo.git
Multiple Repos
Syncing
Commits are pulled down from a remote repo via git fetch
, however this doesn't automatically merge them in to the local branches.
# ex: git fetch # review status git hist --all
However, merging remote fetched commits is the same as any other commits. This will merge all the commits from origin/master
in to the currently checked out branch:
git merge origin/master
It's possible to effectively perform git fetch
and git merge
in a single command via git pull
.
# fetch and merge origin/master in to current branch git pull
Sending changes upstream to a remote repo is done via git push
.
# push to <remoterepo> local <branch> git push <remoterepo> <branch> # ex: git push origin master # push everything git push --all
If, as mentioned in managing remote repos, local branches are already configured to track remote branches, it shouldn't be necessary to specify any parameters. Simply running git push
should be enough.
Tracking Branches
When a repo is cloned, the only local branch is master
, and while the other remote branches are tracked, git pull
and git push
are only setup between the local and remote master
branches. This can be confirmed by reviewing the remote configuration.
# check configured remote repos git remote # show details for a configured remote repo git remote show <repo> # ex: git remote show origin
It is possible to create a local branch that tracks commits from a remote branch:
# create a new localbranch to track remotebranch git branch --track <localbranch> <remotebranch> # ex: git branch --track dev1 origin/dev1
It is also possible to modify an existing local branch and set it to track commits from a remote branch:
# for currently checked out branch git branch -u <remotebranch> # ex: git branch -u origin/dev1 # for NOT currently checked out branch git branch -u <remotebranch> <localbranch> # ex: git branch -u origin/dev1 dev1
NOTE: After using git branch -u
the local branch will display as fast-forwardable
via git remote show origin
. To clear this up, simply force a git push
:
# push all refs git push --all
Managing Remote Repos
# add a remote repo git remote add <reponame> <repopath> # ex: git remote add origin ../folder # remove remote repo git remote rm <reponame> # ex: git remote rm origin
With git push -u
it's possible accomplish the same things as git branch -u
, the latter being more specific in how to link branches.
# configure branchname to track remote branchname on reponame git push -u <reponame> <localbranch> # ex: git push -u origin master git push -u origin dev1 # alternatively, this will do above for all branches git push -u --all
When a repo is cloned, remote HEAD
tracking is configured automatically. When setting up remote repos manually it's possible to do this with git remote set-head
.
# set reponame/HEAD as master git remote set-head <reponame> -a # ex: git remote set-head origin -a # remove reponame/HEAD as master git remote set-head <reponame> -d # ex: git remote set-head origin -d
In some cases it may be desired to disable git push
and effectively setup a pull only repo. There is no official disable switch, but it's possible to provide a bogus URL that will generate an error.
# set the remoterepo push url git remote set-url --push <remoterepo> <url> # ex: git remote set-url --push origin DISABLE
Stage, Confirm, Commit, and Tag
Note: Before the initial commit occurs on a new repo, the master
branch doesn't exist yet, and many commands will throw errors.
Stage files:
# a single file git add file.txt # multiple via wildcard git add *.txt # all via shell wildcard # - will ignore what shell ignores, like .folders git add * # all via git wildcard # - will pull in everything that isn't in .gitignore git add .
Confirm repo status:
git status
Commit changes:
# commit and launch default editor to provide comment git commit # commit and provide comment in-line git commit -m "Commit comment"
To correct a mistake in the last commit:
- Make the necessary changes
- Stage the necessary files
- Perform a new commit with the
–amend
switch
git commit --amend -m "Commit comment"
Tag commits for easier management:
# tag the current commit with a friendly name git tag <name> # ex: git tag v1 # tag the previous commit using '^' notation git checkout v1^ git tag v0 git checkout v1 # remove tag git tag -d v1
Undo Changes
Unstaged changes can be rolled back via git checkout
.
# checkout a single file git checkout file.txt # checkout all files git checkout .
This is not an undo, but instead of checking out files, it's possible to checkout a commit via the first 7 digits of the hash (from git hist
if the alias is defined), or tags:
git checkout <hash> # ex: git checkout 9b2c81a
To return to the latest commit do:
git checkout <branch> # ex: git checkout master
Staged changes can be rolled back via git reset
.
# unstage all currently staged changes git reset # unstage a particular file git reset HEAD <file> # ex: git reset HEAD file.txt
NOTE: The working directory still has modified and unstaged files, use git checkout
to replace them with committed version:
git checkout . # or, for a single single file git checkout file.txt
Commits can be canceled (but not removed) via git revert
. Cancel commits by targeting their hash, or other identifiers.
This will cancel wherever HEAD
is, which is usually the last commit:
git revert HEAD
Commits can be removed from history via git reset
.
To revert the working directory to a specified commit, and remove all later commits from history:
git reset --hard <hash> # ex: git reset --hard e54ff04
NOTE: If removed commits had tags, those tags need to be removed or the commits will remain in history. This can be done after git reset
:
git tag -d BadVersion
Moving Content
Content can be moved inside the repo via git mv
, this is the best option when moving a single file, although more files just mean repeating the command for them.
# files and/or folders can be moved like this git mv <source> <dest> # ex: git mv file.txt folder\file.txt git mv folder1 folder2 # it's better to use 'git mv' instead of native file system # to avoid more steps: mv file.txt lib git add folder/file.txt git rm file.txt
If using the file system to move content around, especially serious restructuring, it's a better idea to use git add -A
.
# update the entire worktree git add -A # update current folder and down git add -A . # update a specific folder git add -A MyFolder
Branches
Branches are managed via git branch
, switched via git checkout
, and merged via git merge
.
Create, List, Checkout, and Delete
# list branches git branch # create a new branch git branch <name> # ex: git branch dev1 # list local branches git branch # list all branches git branch -a # switch working directory to branch dev1 git checkout dev1 # it's possible to create a new branch and checkout in one command git checkout -b dev2 # to delete a branch (can't be checked out) git branch -d dev1
Merging
# merge <branch> in to the currently checked out branch git merge <branch> # ex: # this brings all the changes from dev1 in to master git checkout master git merge dev1
Rebasing
Branches can be rebased with git rebase
. Rebasing merges the branch histories in to a single thread, effectively performing a merge and then flattening the commit tree.
# rebase the currently checked out branch in to <branch> git rebase <branch> # ex: # this flattens the dev1 history in to master git checkout dev1 git rebase master
NOTE: Rebasing can get tricky in some scenarios and cause issues, check the documentation for further details:
git rebase --help