# git

remote

create empty server repository

git init --bare repo.git

add remote to given repository

# <name> may be "origin"
git remote add <name> <url>

ssh urls

ssh://username@host.xz/absolute/path/to/repo.git/
username@host.xz:relative/path/to/repo.git/

working directory and (linear) commit related stuff

add

git add -i  # interactive staging

diff

git diff --stat
git diff --name-only

log

git log --oneline
git log --oneline --graph
git log --grep 'haaaaands'

stash

git stash --keep-index
git stash show     # show files
git stash show -p  # show diff

removed untracked files

git clean -f -d -x

ignore changes

ignore changes in committed files.

git update-index --assume-unchanged <file>
git update-index --no-assume-unchanged <file>

undo last commit / reset current HEAD to given state

undo commit and reset files to pre commit state (reset index and working tree):

git reset --hard HEAD~1

keep changes (reset index, but not working tree):

git reset [--mixed] HEAD~1

keep changes and keep index, resetted changes will be in staging:

git reset --soft HEAD~1

get changes from other branches

git checkout branch file

non-linear stuff (aka branches)

branch removal

git branch -c <oldbranch> <newbranch>  # copy
git branch -m <oldbranch> <newbranch>  # move
git branch [-d|-D] <branch>        # local, force local
git push origin --delete <branch>  # remote

clear deleted remote branches.

git remote prune origin
git remote update origin --prune    # ?? update and prune?
git fetch origin --prune

pull

git pull                    # `fetch` and `merge` current branch from default remote
git pull <remote> <branch>  # given branch from given remote
git pull ../other_repo      # remote can be local path
git pull --rebase           # rebase local changes on top of remote changes

rebase

branch is getting changed and defaults to current branch.

# put `branch` on top of `upstream`, allowing for fast-forward merges.
git rebase <upstream> <branch>

# put some commits from `branch` on `newbase`, skip the ones also in `upstream`.
git rebase [--onto <newbase>] [<upstream> [<branch>]]

tags

annotations

by convention (tm) tags mark releases, following the pattern:

release name

changelog:
- item 1
- item 2

get commits since last release

git log $(git describe --abbrev=0).. --oneline

get tag message

# list all tags
git tag
# sort by version number, prefix `-` to reverse
git tag --sort v:refname
# ... with first line of annotation (aka "release name")
git tag -n
# ... with "entire" annotation
git tag -n20
# restrict output to last tag
git tag -n20 $(git tag | tail -n 1)
# output tag of current HEAD, nothing if not on tag
git tag -n20 $(git describe)

delete remote tag

git push --delete origin <name>
git push origin :refs/tags/<name>

advanced and other stuff

tweak directories

git --work-tree=/tmp/code --git-dir=/tmp/repo/.git status

export code w/o .git

# clone and `rm -rf .git`
git clone --depth=1 <repo>
# must be supported by server
git archive --remote <repo> master | tar x

cleanup branches

git branch --list [pattern]
git branch --contains [commit]
git branch --merged [commit]
git branch --merged <commit> --format="%(objectname:short) %(refname:short)"
git branch --merged <commit> --format="%(objectname:short) %(refname:short)" --remote
git branch --merged <commit> --format="%(objectname:short) %(refname:short)" --remote --sort=-committerdate

git branch -r --merged origin/master | grep origin | grep -v '>' | grep -v master | grep -v develop | xargs -L1 | sed 's/origin\///'

recover lost stashes

don't really understand thee difference, but try one of

git fsck --dangling
git fsck --unreachable

relax

gource -a 1 -s .5 -f

git gui

sometimes git gui fails to start when monitor position is borked, fix w/ git config --local --unset gui.geometry

ignore file

uses shell globs relative to gitignore file or project root. also supports globstar.

# root w/ `/`
/*.pdf
# mark directories
ignore_dir/
# `!` negates pattern: `notice.txt` will be included, escape if needed
*.txt
!notice.txt
\!ignore_me!.txt