Saturday, January 23, 2021

Git cheat sheet

Clone git repo

git clone

git clone ssh://

Create new repo (add existing project to Git)

# You also have to create your repository in your remote Git server, i.e. create repo

git init -b main # previously master, init.defaultBranch

echo "New project" >

git add . # or simply: git commit -a

git commit -a -m "Initial commit"

git remote add origin

git remote add origin

git remote -v # verify

git push -u origin main # previously master

# configurable default name of main branch:

git config --global init.defaultBranch main

see also:

Get started with GitHub

create new repo in GitHub (how to)

Add existing project to GitHub

GitHub profile

GitHub email settings


git pull # update (fetch) from remote tracking upstream, merge into current branch

# update from origin:

git pull –-all # fetch all remotes

git pull origin # update from origin

git pull origin branch1 # update from origin, merge remote branch1 into current branch

# or:

git fetch origin

git merge origin/branch1

Show branches

# local:

git branch -l


git branch -r

# all:

git branch -a # remotes prefixed with "remotes/"


git branch --show-current

branch parent:

git branch -a

Switch to another git branch

# create or switch to and reset (-B) local branch:

git checkout -B branch1 origin/branch1

# switch to local (existing) branch:

git checkout branch1

# since git 2.23.0:

git switch branch1 origin/branch1

Create/Clone branch and switch into it

# create (-b), checkout new branch (optionally: --track, --no-track)

git checkout -b branch1 origin/master^0 --

More at StackOverflow

Push new local branch to remote

git push -u origin HEAD

git push -u origin refs/heads/branch1:branch1

Merge branch1 to master

git checkout origin/master

git merge origin/branch1

git push

git push origin HEAD

git push origin refs/heads/master:master

Merge - resolve conflicts

resolve conflicts:

vim file1.txt

git add -A -f -- file1.txt

commit resolved changes:

git commit -F C:\git\project1\.git\MERGE_MSG --

git commit -a -m "commit message"

Resolve merge conflicts (helpers)

git status

git log --merges # print only merge commits

git diff

git checkout

git reset --mixed

git merge --abort

git reset

git mergetool # uses merge tool to resolve merge conflicts

git am --show-current-patch # see failed patch (from merge)

see: atlassian - merge conflicts

Merging strategies




octopus (?)


see: atlassian - merge strategy

Merge remote branch1 into current branch

git pull origin branch1

git push

Merge Squash

git checkout origin/master

git merge --squash origin/branch1

git push

Merge and Patch

git checkout feature

git diff main > feature.patch

git checkout main

patch -p1 < feature.patch

git add .

src: stackoverflow


git checkout origin/branch1

git rebase origin/master

git add fixed_file.txt

git commit -m "fixed conflict"

git rebase --continue # skip, abort

git push --force

Rebase pull

git pull --rebase


git config branch.autoSetupRebase

git config --global pull.rebase preserve # set up Git to automatically rebase upon pull

git config --global pull.rebase true

src: stackoverflow

# Change parent branch:

git rebase --onto origin/newBase

# Interactive rebase (squash, drop, ...)

git rebase --interactive origin/master

git rebase -i origin/master

# p, pick = use commit

# r, reword = use commit, but edit the commit message

# e, edit = use commit, but stop for amending

# s, squash = use commit, but meld into previous commit

# f, fixup = like "squash", but discard this commit's log message

# x, exec = run command (the rest of the line) using shell

# d, drop = remove commit

See more about Rebase

The Golden Rule of Rebasing

Never rebase public branches

# Rebase public branch – if ever:

git rebase --fork-point # src

git --fork-point

Rebase issue

# If someone rebases on public branch, after pull all others could see:

Your branch and 'origin/branch1' have diverged,

and have 2 and 3 different commits each, respectively.


git fetch origin

git reset --hard origin/main

src stackoverflow

Rebase issue

Your branch is ahead of 'origin/master' by 3 commits


git fetch -p # clean up local branches

git pull --rebase # pull and rebase my local commits on top of incoming

Better solution (unchecked)

Step 1 : git checkout branch1

Step 2 : git pull -s recursive -X theirs # merge strategies

Step 3 : git reset --hard origin/branch1

Rebase issue explained (long)

git rev-list --count --left-right branch1...upstream

git rev-list --count --left-right origin/master...HEAD


# to see if the local repository is ahead, push needed:

git rev-list origin..HEAD

# to see if the local repository is behind, pull needed:

git rev-list HEAD..origin

# if you have numbers for both, then the two repositories have diverged:

git rev-list --count --left-right origin/master...HEAD

src: stackoverflow




# squash - merge squash:

git checkout origin/master

git merge --squash origin/branch1

git commit

git push --force

# squash - reset soft:

#git reset --soft master

git reset --soft origin/master

git add -A

git commit

git push --force

# squash - reset to merge-base:

git checkout branch1

git reset $(git merge-base master $(git branch --show-current))

git add -A

git commit

git push --force

# src:

# Note: git merge-base branch2 branch3


git push # Push to tracked/upstream/remote

git push origin branch1 # Push to branch1

git push -u origin branch1 # Push to branch1 and set upstream

git push -u origin local1:remote1 # push local1 to remote1 and set-upstream

See Push default

Push force

git push --force-with-lease

git push --force-with-lease origin X

src: stackoverflow

src: stackoverflow

Push tags

git push --tags # tags are not pushed automatically

Push all

git push --all # all branches

Delete branch

# Local:

git branch -d branch1

# Force local

git branch -D branch1

# Remote:

git push --delete origin/branch1

# SOLVED: fatal: --delete doesn't make sense without any refs

git push origin :branch1 # actually deletes branch1


# Delete local branches without remotes

git remote prune origin --dry-run # prunes tracking branches not on the remote

git fetch -p

git fetch -p && for branch in $(git branch -vv | grep ': gone]' | awk '{print $1}'); do git branch -D $branch; done

Note: see differences between differences between git remote prune, git prune, git fetch --prune, etc

Git tag

# Tags are ref's pointing to git history. Types: 

lightweight tags (absence of the -a, -s, -m), 

annotated tags

# Lightweight tag (absence of the -a, -s, -m)

# Create a new tag checksum and store it in the .git/ of project's repo

git tag v1.4

# Annotated Tag

# full objects in the Git database (store the tagger name, email, and date)

git tag -a v1.4

# Add (commit-like) tag message:

git tag -a v1.4 -m "my version 1.4"

# List tags

git tag

git tag -l *-rc*

# Tag old commit

git log --pretty=oneline

git tag -a v1.2 commit-id

# fatal: tag 'v0.4' already exists => force

git tag -a --force v1.4 commit-id

# Push tag:

git push origin v1.4

# Checkout tag:

git checkout v1.4

# Delete tag:

git tag -d v1

# Prune tags:

git fetch --prune-tags


Reset branch (move back in history)

# reset your branch to master and destroy changes:

git reset --hard origin/master

# reset your branch to master and keep changes as commited:

git reset --soft origin/master

# reset your branch to master and mixed (not added to index):

git reset --mixed origin/master

Reset Demystified

Commit References (move back in history)


~ most of the time

^ on merge commits



Tilde ~ is almost linear in appearance and wants to go backward in a straight line

Caret ^ suggests an interesting segment of a tree or a fork in the road


Order of Parent Commits

Show 89e4fcb0dd’s immediate parents in sequence:

git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3

src: good article: stackoverflow

Cherry pick

# Syntax:

git cherry-pick commit-sha

# i.e.: you want to get f into Main:

    a - b - c - d   Main


           e - f - g Feature

git checkout main

git cherry-pick f


git cherry-pick -x f # generate standard commit message – keep track of origin of commit

git cherry-pick --edit f # you can edit commit message

git cherry-pick --no-commit f # do cherry pick but do not commit and keep changes in working directory

git cherry-pick --signoff f # add signoff signature to end of cherry-pick commit message

git cherry-pick --abort --continue –quit # when solving conflicts

Copy notes attached to cherry pick:

git notes copy <from> <to>

src: atlassian: cherry-pick



see also: atlassian: merge-strategy

Revert file

remove untracked including ignored:

git clean -f -d or git clean -fd # remove untracked directories and untracked files

git clean -f -X or git clean -fX # remove only ignored files

git clean -f -x or git clean -fx # remove directories, ignored and non-ignored untracked files (include build target)

src: stackoverflow

answer: stackoverflow

-n, --dry-run # dry run

git clean -i # interactive

git add --all && git reset --hard HEAD


# undo/revert local changes:

git reset --hard

git stash

git reset HEAD file1.txt # unstage to current commit

git checkout -- file1.txt

git checkout HEAD -- file1.txt

# revert (remove) uncommited file:

git rm --cached -f -- file1.txt

git reset file1.txt

See more at Revert all local changes


# simple:

git stash

git stash pop

# include ignored and untracked:

git stash -u

git stash pop

# name stash:

git stash save "my stash name"

# list

git stash list

# apply and keep

git stash apply stash@{0} # apply and keep

git stash pop # apply and drop

# branch from stash

git stash branch branch1 stash@{2}

# view details

git stash show

# delete

git stash drop stash@{1}

# delete all

git stash clear

Git log

git log --oneline --decorate

git log --graph --oneline --decorate

git log --pretty=format:"%cn committed %h on %cd"

git log -3 # 3 lines

git log main..feature

git log --no-merges

git log -–merges


# Pretty format

git log --all --decorate --oneline –graph # "A Dog" 

git config --global alias.adog "log --all --decorate --oneline --graph"


Ref log

# Show git commands history:

git reflog

git reflog --relative-date

git reflog --all

git reflog show

See more Many undo possibilities

See on Atlassian

Push default

git config --global push.default matching # old default behavior

git config --global push.default simple # new default behavior

See default git push

See push -u

Upstream config

# snippet of git config – refs remotes upstreams :

git config --local -–list | grep '^remote'

# remote and refspec def :



# branch master :

git config --list | grep "^branch"




Set branch upstream

# If you create new branch:

git checkout -b branch1 origin/branch1

# you have to set upstream branch during push:

git push -u origin HEAD

git branch -u origin/branch1 branch1

git push origin refs/heads/branch1:branch1 --set-upstream

git push origin refs/heads/branch1:branch1 -u

# updates git project config as :



# Config branch:

git config branch.master.remote origin

git config branch.master.merge refs/heads/master

Remote origin (add show update)

git remote add origin

git remote show origin

git remote update

Set remote URL (https or ssh)

git remote set-url origin

git remote set-url origin

# Check remote URLs

git remote -v

origin (fetch)

origin (push)

# Show Git remote URL

git config --get remote.origin.url

Parent branch - merge base

git merge-base branch2 branch3

git merge-base origin/main branch1

git reset $(git merge-base master $(git branch --show-current))

git show --summary `git merge-base foo master` # when was branch created

git log --first-parent

Git commands workflow

HEAD working tree, index, staging area:

Workspace is the directory tree of (source) files that you see and edit.

Index is a single, large, binary file in <baseOfRepo>/.git/index, which lists all files in the current branch, their sha1 checksums, time stamps and the file name -- it is not another directory with a copy of files in it.

Local repository is a hidden directory (.git) including an objects directory containing all versions of every file in the repo (local branches and copies of remote branches) as a compressed "blob" file.

src: stackoverflow

See: Git Branch, HEAD, Refs

See index, commit, repo


git config core.autocrlf true

git config core.autocrlf false

git config core.autocrlf input

# src:

Different Git configs

git config --list                              # local: /.git/config - repo-specific

git config --global --list # global: /.gitconfig - user-specific

git config --system --list # system: $(prefix)/etc/gitconfig - system-wide

git config --global --edit # edit

Global proxy settings

git config --global http.proxy

Global SSL verify

git config --global http.sslVerify "false"

git config --global --unset http.sslVerify

Project specific SSL verify

cd C:\git\my-project

git config http.sslVerify "false"

:: git config --unset http.sslVerify

Git template dir:

# ~/.config/git/config or ~/.gitconfig


    templateDir = ~/.config/git/template/

Relative Refs

# display the grandparent of HEAD:

git show HEAD~2

merge commits => more complicated

merge commints => more parents => more paths to follow

i.e. 3-way merge:

1. parent == main branch you merged into

2. parent == branch mentioned in git merge branchName

~ = follow first parent of merge commit

^ = follow different parent

i.e.: if HEAD is merge commit, display second parent of HEAD by:

git show HEAD^2

Combine into:

git show HEAD^2^1

it is: grandparent of HEAD (if merge commit) which is on the second parent.


# Only list commits that are parent of the second parent of a merge commit

git log HEAD^2

# Remove the last 3 commits from the current branch

git reset HEAD~3

# Interactively rebase the last 3 commits on the current branch

git rebase -i HEAD~3

# get back before you ran git reset

git checkout HEAD@{1}


Git branch_name vs refs

git show-ref origin/main

1. If $GIT_DIR/<refname> exists, that is what you mean (this is usually useful only for HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD and CHERRY_PICK_HEAD);

2. refs/<refname> if it exists;

3. refs/tags/<refname> if it exists;

4. refs/heads/<refname> if it exists;

5.  refs/remotes/<refname> if it exists;

6. refs/remotes/<refname>/HEAD if it exists.


Long aside: how this all works (read only if sufficiently curious) :


Git server repository (docker git repo)

Alpine Git client

JKarlos Docker Git server

Gogs and Podman Git server

Gogs Git server

Gogs by Pirates - GitHub like Git server

Gitea in Docker - demo - github

GitColony docker server - obsolete

Git server:

Google it:

Git server list - wiki:





Wiki says: External projects like gitolite, which provide scripts on top of git software to provide fine-grained access control.




Gitea = fork of Gogs

Git Web interface self-hosted:

Options – list – good overview:

GitLab = web git, “Confluence” wiki, “Jira” tracker

Gitea – community fork of Gogs:

Savannah = GNU = free software foundation (FSF)

GitBucket – Open source

Gogs - self hosted Git:


Awesome Selfhosted:



Git web UI – including proprietary and closed-source:


ProGit Book

Reset Demystified

git branch vs git checkout -b

track remote branch

IntelliJ Idea branches

Cheat sheets

Atlassian git cheat sheet page

GitHub cheat sheet

GitLab cheat sheet

Atlassian git advanced – crossroad

Rebase reset revert log hooks refs reflog