Programming for fun and profit

Programming tutorials, problems, solutions. Always with code.

Git Cheat Sheet

List of common Git problems and solutions in a concise format.



Note: Config files are plain text files and can be edited manually.
Options can be stored:

  • per repository (project/.git/config),
  • globally for user (~/.gitconfig) – use –global parameter
  • globally for all (/etc/gitconfig) – use –system parameter

Local settings override global, which override system wide options.

# List all config values including local:
git config -l

# List only global options:
git config --global -l

# set user name for the current repository:
git config 'Ludovico Zamenhof'

# set email for the current repository:
git config

# set editor globally:
git config --global core.editor emacsclient

# pass traffic through *HTTP Proxy*:
git config http.proxy
# or add the following to the .gitconfig file:
# [http]
#     proxy =

Create a new repository for project:

mkdir myproject
cd myproject
git init

Clone existing repository:

# myDir is optional target directory name
git clone <path-to-my-git-repository>/myproject.git [myDir]

Doing changes

Adding files:

# Start tracking new file:
git add new-file-name

# Add tracked file to the current changeset:
git add tracked-file

# Add all files (including tracked) from the current
# dir or below to the current changeset:
git add .

# Show every chunk and ask for adding it:
git add --patch

Removing files:

# Remove specified file:
git rm file-name

# Remove all files from the current dir or below:
git rm -r .

Reverting changes

# remove from the current changeset if it has been added:
git reset HEAD filename

# Undo last commit, preserving local changes:
git reset --soft HEAD^ # HEAD~1 in Windows

# Undo last commit, deleting local modifications:
git reset --hard HEAD^

# checkout the last committed version, when not in changeset:
git checkout filename

Good description is the 2nd answer here.

Committing changes

# commit staged changes:
git commit -m 'message'

#commit all changes (omitting staging area):
git commit -a -m 'message'

# the same:
git commit -am 'message'

Correcting commits

Correct the most recent commit:

  1. Save your work. :-)
  2. Commit the changes in “amend” mode:
    git commit --all --amend

    Recommits with added all changes since last commit.
    Note: If there were no changes allows to reedit commit message.

  3. The new changes are added to the old commit.
    git log
    # and/or:
    git diff HEAD^

Correcting any previous commits:

  1. Use git status at any stage to see what is happening!
  2. Save and stash changes.
  3. Copy from git log ID of the commit you want to correct.
  4. Start the interactive rebase:
    git rebase --interactive ID^
    # ^ refers to the parent of selected commit.
    # Or just use the following to rebase last 3 commits:
    git rebase -i HEAD^3     # HEAD~3 for Windows
  5. Editor will come up with several lines like:
    pick 19cdb76 commit message
    With one line for each commit since the oldest one.
  6. Change pick to edit for commits you want to change.
  7. Save and quit.
  8. Edit files you want and then run:
    git commit --all --amend
  9. To move to the next commit run:
    git rebase --continue

    Git will move to the next commit you would like to fix, stop for resolving conflicts (follow Git’s instructions then), or will finish the rebase.


Note: A branch in Git is simply a pointer to one of commits.

Showing branches:

git branch              # list local branches
git branch -v           # like above, but with the last commit
git branch -a           # all (including remote/SVN and tags)
git branch --merged     # show merged branches
git branch --no-merged  # show not merged branches
git tag -l              # show all tags

Creating branches:

git branch newBranchName [master]
  • master is the branch you are forking from
  • no need to add parent name, when forking from the current branch

Create and open new branch in one step:

git checkout -b new_branch_name [old_branch_name]

# Creates local branch newLocalBranch, connected to remote branch remoteBranch
git checkout -b newLocalBranch remoteBranch

Open existing local branch:

git checkout newBranchName

Connect local repository to a remote branch

You can do the following (assuming you are checked out on master and want to push to a remote branch master):

# Set up the 'remote' if you don't have it already:
git remote add origin ssh://repo.url

# Now configure master to know to track:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master

# And push:
git push origin master

Merge branch (back to master):

# Switches back to master:
git checkout master

# Merges branch-name to the current branch, which is
# master in this case. In case of conflicts, you will
# be prompted to fix them in your editor. Add fixed
# conflicts with "git add" and commit.
git merge branch-name

# Or to always create commit merge:
git merge branch-name --no-ff

# Or to merge branch's commits as one large commit:
git merge --squash branch-name

# Show conflicting changes. Staging them will automatically
# mark them resolved:
git status

# Then just commit merge and delete branch if needed.

# Abort the merge process and try to reconstruct
# the pre-merge state:
git merge --abort

Rebasing – integrating changes with linear history

It takes patch of the change introduced in a branch and reapplies it on top of another branch. Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together.

# Rebase changes from the current branch onto target-branch:
git rebase target-branch

# Rebase changes from the from-branch onto the target-branch:
git rebase [target-branch] [from-branch]

# Check out the client branch, figure out the patches from
# the common ancestor of the client and server branches,
# and then replay them onto master:
git rebase --onto master server client

After rebase fast-forward the target branch to include the latest changes:

git checkout target-branch
git merge topic-branch
git branch -d topic-branch

To turn on rebasing on pull (very useful):

git config --global pull.rebase true

Delete branch

# Delete branch:
git branch -d branch_name

# Delete branch even having changes:
git branch -D branch_name

# Deleting remote branch:
git push origin :branch_name

# Removing local ref to deleted remote branch
# (by default "fetch" preserves them):
git fetch -p origin

Renaming branches

# Create a branch from a commit (e.g. master~10^2)
git checkout -b new-master

Fixing remote master branch

Especially useful for teams that start with git ;-).

# Rename the new branch to master dropping changes
# on old master:
git branch -M new-master master

# Force pushing my master as the new origin/master
# (without fast-forward and using changes on
# origin/master):
git push -f origin master:master

# Getting new master on other machines:
get fetch
git reset --hard origin/master

Ignoring changes

Add to .gitignore files you don’t want to track

cd myproject
cat .gitignore
# a comment :-)

Stop tracking file, but keep its local copy:

git rm --cached <file>

Ignoring local modifications to tracked files:

#Ignore local changes:
git update-index --assume-unchanged <file>

#Stop ignoring local changes:
git update-index --no-assume-unchanged <file>

#Stop ignoring local changes on all files:
git update-index --really-refresh

Finding things

git diff
git diff --word-diff         # by word
git diff --word-diff=color   # by word colored
git diff <commit> -- <path>  # diff a file with specific commit

# Find commits for file:
git log -- <path>

# Show unpushed commits between remote master and local HEAD:
git log origin/master..HEAD

# Show commits between remote branch and local version:
git log refs/remotes/myremotebranch..HEAD

# List all files modified in given commit:
git show --name-only <commit>

# Show number of commits per user on all branches:
git shortlog -s -n --all

# Find commits that contain a string:
git log -S 'aoeu' --source --all


Importing local repository to other server

cd local-repo
git push --mirror
cd ..
rm -rf local-repo
git clone

Pushing tags to remote

git push --tags -v

Configure a remote for a fork

# Add remote repo:
git remote add upstream <remote-repo>

# List all remotes:
git remote -v

Syncing a fork

# Fetch all from configured upstream:
git fetch upstream
# Change to local master:
git checkout master
# Merge changes from upstream (if there were no local
# commits, then it does Fast Forward):
git merge upstream/master


Reflog keeps lost commits until next Garbage Collection (2 weeks by default)

git log --walk-reflogs mybranch

Turn reflogs on server

git config core.logAllRefUpdates true
# Configure it system wide:
git config --system core.logAllRefUpdates true


# Ignore local changes temporarily:
git config --global alias.ignore-temporarily 'update-index --assume-unchanged'

# Display history nicely:
git config --global alias.hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short

# Show nicely fetched changes:
git config --global = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short HEAD..origin/master

Working with SVN (git-svn plugin)

Checking out project from SVN:

git svn clone -s repo.url/mysvnproject myproj
  • “-s” tells to git-svn that SVN repository has a standard layout (trunk/branches/tags). If it doesn’t, you can leave that off
  • it creates git repo in “myproj” directory and maps it to trunk
  • empty directories are not tracked in git, so not shown
  • files ingored is SVN are not ignored automatically

Getting changes from SVN:

# Download all new changesets from SVN, apply them to
# the last checkout from SVN, and then re-apply your
# local changes on top of that:
git svn rebase

# Downloads all changes (including new branches)
# from remote repository.
git svn fetch

# Like above, but skips tags:
git svn fetch --ignore-paths="^tags"
git svn fetch --ignore-paths=".*tags.*"

Ignore svn:ignored files:

git svn show-ignore > .gitignore

Commit back to Subversion:

Enable pushing with merge info

# set svn:mergeinfo when pushing merge commits
# (pushmergeinfo = true in gitconfig):
git config --global svn.pushmergeinfo true

Pushing to SVN repository

# Push all commits from the current branch to tracked remote:
git svn dcommit

# Like above, but also remove empty dirs:
git svn dcommit --rmdir

# It can be done also with config param: svn.rmdir
git config --global svn.rmdir true

Moving SVN repository to Git (using svn2git program):

mkdir repo
cd repo
svn2git https://svn.repo.url
git remote add origin https://git.repo.url
git push origin master
git push --tags
Share with the World!