<- Back

git

Sign commits
Obtain your key
gpg --list-secret-keys --keyid-format long
Set your key
git config user.signingkey <long-key-id>
Tell git to sign all of your commits
git config commit.gpgsign true
Also sign tags
git config tag.gpgsign true
SSH Keys
Clone with a different ssh key
git clone -c core.sshCommand="ssh -i ~/.ssh/your-ssh-fileName" git@github.com:orgname/repo.git
Revert/Undo
Revert last 3 commits
git revert --no-commit HEAD~3..
Undo last local commit, but keep changes
git reset HEAD~
History
Show file at commit hash
git show 24a255c1:src/main.rs
Show file at absolute date
git show HEAD@{2013-02-25}:src/main.rs
Show file at relative date
git show HEAD@{3 days ago}:src/main.rs
For date older than 90 days
git show (git rev-list -1 --before="2024-07-13" HEAD):src/main.rs
Prune remote branches
Only prune remote branches
git remote prune origin
Update remote branches
git remote update origin --prune
pull & prune
git pull --rebase --prune --autostash
Always prune on fetch/pull globally
git config --global fetch.prune true
Always prune on fetch/pull for current repo
git config remote.origin.prune true
List unpushed branches
git log
git log --branches --not --remotes --no-walk --decorate --oneline
git branch
git branch -vv
cleanup
Delete local branch
git branch --delete branch-name
Delete remote branch
git push --delete origin branch-name
Find non-merged branches
git branch --remote --no-merged
Delete merged local branches
git branch --merged origin/master | grep -v \* | xargs git branch -D
Find largest files (even in history)
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' |   sort --numeric-sort --key=2 | cut -c 1-12,41- | $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
bundle
Complete repo
git bundle create (basename (git rev-parse --show-toplevel)).git.bundle --all
Show repo size (do git gc first)
git count-objects --verbose --human-readable | grep size-pack
List
Count commits per author
git shortlog --summary --numbered --email --no-merges --since "last 2 weeks" [--all]
Count commits per day
git log --date=short --pretty=format:%ad | sort | uniq --count
Show all config entries with their origin
git config --list --show-origin --show-scope
Stash
Stash with name
git stash push -m my-stash
Apply changes to current branch (deletes the stash)
git stash pop
Apply and keep stash
git stash apply
Apply by name
git stash apply stash^{/my-stash}
List
git stash list
Show filenames (most recent stash)
git stash show
Show changes (most recent stash)
git stash show -p
Show changes (specific stash)
git stash show -p stash@{1}
Show full filenames
git stash show -p stash@{0} --name-only
Show diff of single file in stash
git diff stash@{0}^! -- file.txt
Filter commits
by Date and author
git lg --after={2016-09-01} --before={2016-10-01} --author="Andreas Mausch"
since/until
git lg --since="2 year ago" [--until="3 weeks ago"]
Diff from yesterday
git diff @{yesterday}..HEAD
Another variant
git whatchanged --since="1 day ago" -p
Feature branches
Create new feature branch
git checkout -b my-feature main
Create new empty branch
git checkout --orphan empty-branch
Count commits on feature branch
git rev-list [--no-merges] --count origin/master..HEAD
List commits on branch (use git log if alias is not set)
git lg --left-right --graph --cherry-pick [--no-merges] origin/master..HEAD
List commits on branch (via cherry)
git cherry master FEAT-branch
Table of all branches and their commit count compared to origin/master
git for-each-ref refs/heads refs/remotes/origin --format='%(refname:short)' | xargs -i sh -c 'ahead=$(git rev-list --count origin/master..{}); behind=$(git rev-list --count {}..origin/master); printf "%4s %4s {}\n" "+$ahead" "-$behind"'
Merge branch without checkout (merge local dev into local master)
git fetch . dev:master
Check if a specific commit is part of a branch
git branch --contains 818a06f
Create patch
Specific commit
git format-patch -1 <hash>
Unstaged changes
git diff
Staged changes
git diff --staged
Both (unstaged and staged) changes
git diff HEAD
Multiple commits into single file
git format-patch origin/master..HEAD --stdout > commits.patch
Apply multiple commits file
git am commits.patch
Changes between branches
Summary (filenames and amount of changes)
git diff --compact-summary branch..master
Description Shortcut
Jump to next file n
Jump to previous file N
Encoding
Show umlauts in filenames
git config --global core.quotepath false
Default branch / Remote head
Find default branch
git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
Update from remote
git remote set-head origin --auto
Debugging HTTP (for example HTTP 403 Forbidden) and SSH connections
HTTP
GIT_TRACE_CURL=true git pull
HTTP (deprecated)
GIT_CURL_VERBOSE=1 GIT_TRACE=1 git pull
SSH
GIT_SSH_COMMAND="ssh -vvv" git pull
git gui
Description Shortcut
Stage file CTRL+T
Unstage file CTRL+U
Revert file CTRL+J

Github: Search issues created or commented by me

Replace wrong email after commits have been pushed

git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="New Name Value"
NEW_EMAIL="correct@example.com"

if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

Keep in mind you might need to git push --force afterwards. Please be aware of all the consequences of a force push.

Push local repo to a remote url

git remote -v # List remotes
git remote add origin <ssh-url> # e.g. git@gitlab.com:andreas-mausch/repo.git
git push -u origin --all

My git aliases

See here