My git notes



git init

git add

git commit

git commit -a

Skips staging(i.e. git add) altogether.

git commit –amend

Changes the last commit message. Also works with "git add" and "git remove".

git clone

git clone user@server:/.../project.git

git status

git diff


  • kdiff3
  • tkdiff
  • meld
  • xzdiff

git commit

git rm

remove just from git

git rm --cached <file>

git mv

A convenience command:

git mv README.txt README

is equivalent to:

git rm README.txt
git add README

git log

git log -p

include diffs

git log -3

show last 3 commits

git reset HEAD <file>

Use this to unstage a <file> e.g. after

git add *

git checkout

git checkout – <file>

discard changes to a <file> this is dangerous: there's no way to recover uncommited changes.

git checkout <branch>

switch to <branch>

git checkout -b <branch>

a shorthand for git branch <branch> git checkout <branch>

git remote add <alias> <url>

Create an alias for a remote repository

git tag

List tags

git tag -a

annotated tag

git tag <name>

lightweight tag

git tag -a v1.2 -m 'version 1.2' 0fceb02

tag an earlier commit

git branch

git branch <branch>

create branch

git branch -d <branch>

delete branch

git checkout <branch name>

switch to branch

git merge

git mergetool

visual merge with e.g. meld.

git fetch <origin>

synchronize with a remote branch <origin> that someone else commited to

git push <origin> <branch>

push your commits to remote branch

git diff HEAD HEAD~1 <file>

git reflog

show where HEAD has been recently.

git stash

save dirty directory onto stack to avoid a commit.

git blame <file>

Show the <file> line by line, alongside the commit that added them.

git blame -C <file>

Add a column showing which file the line came from.


hide ^M in diff output

git config --global core.whitespace cr-at-eol

ignore file permissions

git config core.fileMode false


omit password

git clone [email protected]:abo-abo/function-args.git

If I clone like this, I don't need to enter the password.

Generating SSH Keys github:help

  • step 1
  • step 2
  • step 3

    Remember to copy the ~/.ssh to newly installed systems.

make bare repository

  • remove everything but .git
  • move .git/* to .
git config --bool core.bare true

diff staged

git diff --cached

move master to branch

git branch -m master old_master
git checkout -b master

subtree merging

cd ~/Dropbox/org
git remote add thermal_remote ../thermal
git fetch thermal_remote
git checkout -b thermal_branch thermal_remote/master
git read-tree --prefix=research/thermal/ -u thermal_branch
git merge --squash -s subtree --no-commit thermal_branch

undo last commit

git reset --soft HEAD^1

summary of commits

git shortlog -s

commits of author

git log --author="Jon"
git log --author=Jon
git log --author=Smith

diff ignoring whitespace

git diff -w

Also, Meld/Edit/Preferences/Text Filters/All whitespace.

squashing commits

  1. git rebase -i HEAD~4
  2. leave one commit, place 's' by others
  3. add a new comment

grep entire history:

git grep "step 8" $(git rev-list --all)


This one will echo the commit messages for when the number of matches was changed.

git log -Shydra-create --

There's also -G. This one will show the log if a line that matches the search string was added, removed, or changed:

git log -Ghydra-create --

remove multiple files that aren't on the disk

git rm $(git ls-files --deleted)

merge vr. rebase

avoid merge commits that result from git pull

When you push, but someone else pushed before you, you have to pull in their changes first. Normally, git does a merge commit in this situation.

Such merge commits can be numerous and convey no useful information and litter the history.

Therefore, always pull with git pull --rebase.

git config --global --bool pull.rebase true

interactively rebase local commits before pushing

Every time before pushing a set of commits:

git rebase -i

add github upstream

git remote add upstream
git fetch upstream
git merge upstream/master

add github pages to a repository

cd ~/git/lispy
mkdir gh-pages
cd gh-pages
git clone [email protected]:abo-abo/lispy.git .
git checkout --orphan gh-pages
git rm -rf .

git bisect

  1. git bisect start <good commit> <bad commit(usually HEAD)>
  2. git bisect good git bisect bad

git am (apply patch)

  1. Find the patch in .git/rebase-apply/0001
  2. git apply .git/rebase-apply/0001 –reject
  3. magit RC.

source: Deal with git am failures

getting git subtree to work

sudo chmod +x /usr/share/doc/git/contrib/subtree/
sudo ln -s /usr/share/doc/git/contrib/subtree/ $(git --exec-path)/git-subtree

remove old history from a git repository

delete remote branch

git push origin --delete scratch/outline


remove submodule

git submodule deinit foo
# no trailing slash
git rm foo

add submodule

git submodule add [email protected]:abo-abo/plain-org-wiki.git git/plain-org-wiki

format-patch for a single commit

git format-patch -1 bad234

Emacs tools


magit shortcuts

  • E - interactive rebase
  • lf - follow file
  • M-s M-h M-2 M-4 - visibility

edit older commit message

  1. ll
  2. E
  3. r (reword)
  4. C-c C-c


* to refine match

ELPA workflow

-s subtree method

Getting Started

  1. packages/hydra must not exist
  2. create a branch hydra tracking the upstream
  3. git subtree add –prefix packages/hydra hydra

Merging from upstream

  1. Switch to the branch that tracks upstream:
git checkout hydra && git pull
  1. Switch to master and merge:
git checkout master
git subtree merge --prefix packages/hydra hydra

Github tasks

force push

git push --force origin master

push tags

git push --tags

get user pubkeys


get all the pulls locally


[remote "upstream"]
    url =
    fetch = +refs/heads/*:refs/remotes/upstream/*
    fetch = +refs/pull/*/head:refs/pull/upstream/*


git fetch --all

This results in all pull requests available in the local repo in the local pull/ namespace. To check out e.g. PR #42:

git checkout -b foo refs/pull/upstream/42

reference other repo