# This config requires `git` v2.40+ # (e.g., Debian 12's v2.39 is too old) # # The most recent features used are: # # v2.40 help.autocorrect with "prompt" # v2.38 rebase.updateRefs # v2.37 push.autoSetupRemote # v2.35 merge.conflictstyle with "zdiff3" # # Older `git` versions do NOT fail on all of these # but may warn about some unknown values [alias] # `git` commands are defined in three places: # # 1) Plain abbreviations and short "!" one-liners # are defined in this file # # 2) ~/.local/bin/ holds `git-*` utilities # for everything with control flow or an error path, # which `git` registers as sub-commands automatically # # 3) ~/.config/shell/aliases defines short form aliases for the shell, # for example, `gap` for `git add --patch` # # Below, the aliases are grouped by task: # Full-name aliases come first in each group, # followed by short abbreviations # # Tab complete works out of the box in `bash`, # whereas a `zstyle` line in ~/.zshrc makes that work for `zsh` # # Run: # - `git aliases` for just 1) # - `git aliases-n-sub-commands` for 1) and 2) # - `git help -a` for ALL sub-commands, built-in and custom # Inspect the repository # # See also this sub-command in ~/.local/bin: # # git-cat-all current-branch = rev-parse --abbrev-ref HEAD project-root = rev-parse --show-toplevel # List all authors with their commit counts contributors = shortlog --summary --numbered --email # Ignore whitespace and follow lines moved or copied between files blame-follow = blame -w -C -C -C bi = bisect bl = blame-follow rl = reflog sh = show s = status ss = status --short # Stage changes & sync the working directory into the index sync = !git sync-deleted && git add . --all sync-deleted = !git ls-files -z --deleted | xargs -r -0 git rm a = add aa = add --all ap = add --patch # No-ops so that the `gmv` and `grm` aliases are created mv = mv rm = rm # Commit changes # Keep the commit message and skip the editor amend-commit = commit --amend --no-edit ci = commit cia = commit --amend cian = amend-commit cif = commit --fixup cim = commit --message # Undo things, named as "specified" in the `git status` header discard = checkout -- uncommit = reset --soft HEAD~1 unstage = reset HEAD -- rev = revert rh = reset rhh = reset --hard rhs = reset --soft rs = restore rst = restore --staged u = uncommit # Manage tags de = describe --tags ta = tag taa = tag --annotate tad = tag --delete tal = tag --list # Make minimal diff the default diff-minimal = diff --color-words=. --ws-error-highlight=all diff-last-commit = diff --color-words=. --ws-error-highlight=all HEAD diff-staged = diff --color-words=. --ws-error-highlight=all --staged d = diff-minimal dlc = diff-last-commit ds = diff-staged # Make the logs look nice by default log-format1 = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%an @ %ad => %ar%n' --date=format:'%a %Y-%m-%d %H:%M:%S %z' log-format2 = log --pretty='%C(auto)%h: %s%d%Creset%n%C(dim)%aN @ %ad => %ar%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S %z' history = log-format2 --graph summary = log-format1 --graph oneline = log --pretty='%C(auto)%h: %s%d' --graph last-commit = log-format2 -1 -p --stat lg = log lga = log --all hi = history hia = history --all su = summary sua = summary --all ol = oneline ola = oneline --all lc = last-commit # Search the history of specific files/paths # Follow a single file through renames history-file = log-format2 --graph --follow -- history-file-diff = log-format2 --graph --follow -p --stat -- # Show all commits touching a path (e.g., a folder) history-path = log-format2 --graph -- history-path-diff = log-format2 --graph -p --stat -- hif = history-file hifd = history-file-diff hip = history-path hipd = history-path-diff # Search the repository # Search the tracked files for source code, # showing the enclosing function of each match grep-code = grep --break --context 1 --full-name --heading --line-number --show-function # Search the commit messages across all branches grep-commit-msg = log --all --regexp-ignore-case --pretty='%C(auto)%h: %s%+D%Creset%n%C(reverse)%C(dim)%aN @ %ad = %ar%Creset%n%+b' --date=format:'%a %Y-%m-%d %H:%M:%S' --grep # Find commits whose diff contains added or removed lines # matching a regex, with or without the patches shown grep-diff = log-format1 -p -G grep-diff-list = log-format1 -G # Find commits that change the NUMBER of occurrences of a regex, # which ignores lines merely moved around (unlike grep-diff) grep-pickaxe = log-format1 -p --pickaxe-regex -S # Search the tracked files for plain text, ignoring case grep-text = grep --break --context 1 --full-name --heading --ignore-case --line-number repc = grep-code repcim = grep-commit-msg repd = grep-diff repdl = grep-diff-list repp = grep-pickaxe rept = grep-text # Manage the branches & move between them # # See also these sub-commands in ~/.local/bin: # # git-checkout-dev # git-checkout-main # git-checkout-first-existing-branch # # git-point-branch-at # # git-prune-delete # git-prune-show # `git branch` sorts by recency (see [branch] below) # => This alias restores the alphabetical listing branch-alpha = branch --sort=refname rename-branch = branch --move br = branch bra = branch --all brd = branch --delete brdd = branch --delete --force brm = rename-branch brp = point-branch-at # Which branches are (not) fully contained in `HEAD` brme = branch --all --merged brnome = branch --all --no-merged co = checkout cob = checkout -b cod = checkout-dev com = checkout-main sw = switch swc = switch --create # Integrate changes from other branches cp = cherry-pick mb = merge-base me = merge mea = merge --abort mec = merge --continue meff = merge --ff-only menoff = merge --no-ff rb = rebase --committer-date-is-author-date rba = rebase --abort rbc = rebase --continue rbi = rebase --interactive # --autosquash is added in [rebase] below rbia = rebase --interactive --autosquash rbq = rebase --quit rbs = rebase --skip # Exchange changes with the remotes # # See also these sub-commands in ~/.local/bin: # # git-ff-all # git-match-remote cl = clone fe = fetch # --prune is added in fea = fetch --all # [fetch] below fep = fetch --prune fepa = fetch --prune --all ff = ff-all fff = match-remote # ~ fast-forward with force pl = pull plrb = pull --rebase ps = push psf = push --force-with-lease psff = push --force re = remote --verbose # Put changes aside temporarily st = stash sta = stash push --include-untracked stam = stash push --include-untracked --message stapp = stash apply stl = stash list stp = stash pop stsh = stash show # Work with several working directories wt = worktree wta = worktree add wtl = worktree list wtm = worktree move wtp = worktree prune wtr = worktree remove # Clean the project folder with intuitive commands # # See also these sub-commands in ~/.local/bin: # # git-clean-all # git-clean-ignored # # git-gc-everything # Keep this "-e" list in sync with the other two copies: # - `$KEEP` in ~/.local/bin/git-clean-ignored # - the preview in ~/.local/bin/git-clean-all clean-untracked = clean -x -d -e ".python-version" -e ".env" -f # because the "-e" flag does not work with "-X" cln = clean --interactive [branch] # `git branch` lists the most recently used branches first sort = -committerdate [clean] # Refuse to run `git clean` without --force or --dry-run requireforce = true [column] # Print listings (e.g., branches) in columns ui = auto [color "branch"] current = cyan dim bold reverse local = green bold remote = cyan bold [color "decorate"] HEAD = cyan dim bold reverse branch = green bold remoteBranch = cyan bold stash = magenta dim bold reverse tag = magenta bold [color "diff"] context = white frag = blue dim bold reverse meta = yellow dim bold reverse new = green bold old = red bold whitespace = red dim bold reverse # Lines that are merely moved around (see "diff.colorMoved" below) newMoved = cyan bold oldMoved = magenta bold # Alternation shades to tell adjacent moved blocks apart (~ "zebra") newMovedAlternative = cyan oldMovedAlternative = magenta [color "grep"] context = white filename = yellow dim bold reverse function = white bold linenumber = blue dim bold reverse match = yellow bold selected = white separator = blue dim bold reverse [color "interactive"] error = red dim bold reverse header = white help = blue bold prompt = white dim bold reverse [color "status"] added = green bold branch = cyan dim bold reverse changed = yellow bold header = white localBranch = green bold nobranch = red dim bold reverse remoteBranch = cyan bold unmerged = red dim bold reverse untracked = blue bold [commit] # Set this in ~/.config/git/config_local to enable signing # # gpgSign = true # Strip comment lines and excess whitespace from the message cleanup = strip template = ~/.config/git/commit_msg_template.txt # Show the staged diff below the commit message template in the editor verbose = true [core] excludesfile = ~/.config/git/ignore pager = less --chop-long-lines --ignore-case --LONG-PROMPT --no-init --quit-if-one-screen --RAW-CONTROL-CHARS --status-column # Speed up `git status` by caching untracked files untrackedCache = true # Flag tabs in the indentation but allow spaces before tabs whitespace = -space-before-tab,tab-in-indent [diff] # Better diff hunks for reordered code than the default "myers" algorithm = histogram # Color lines that are merely moved around differently # from actually added/removed ones # => "default" is a synonym for the "zebra" mode colorMoved = default # Show "i/" (index) and "w/" (working tree) etc. instead of "a/" and "b/" mnemonicPrefix = true # Detect renamed files instead of showing delete-plus-add renames = true # Show submodule changes as their list of commits submodule = log [fetch] # Auto-remove remote-tracking refs deleted on the remote prune = true [help] # Suggest a command on a typo and ask before running it autocorrect = prompt [init] defaultBranch = main [merge] # Show the common ancestor's version inside conflict markers, # minus the lines that both sides agree on conflictstyle = zdiff3 # Refuse `git merge` if a merge commit would be needed # => Use `git menoff` to create one on purpose ff = only [pull] # Replay local commits on top of the fetched branch # and do not create merge rebase = true # Guard: A merge-style pull must be a fast-forward ff = only [push] # Auto-create the upstream on the first push of a new branch autoSetupRemote = true # Push the current branch to its upstream default = upstream # Refuse to push if a submodule's commits are unpushed recursesubmodules = check [rebase] # Auto-apply "fixup!" commits in every interactive rebase autosquash = true # Stash away and restore local changes around a rebase autostash = true # Also move stacked branches that point into the rebased range updateRefs = true [rerere] # Record conflict resolutions and reuse them when they reappear enabled = true [tag] # Sort "v1.10" after "v1.9" sort = version:refname [url "ssh://git@bitbucket.org/"] # Enables, for example, `git clone bb:atlassian/aui` insteadOf = bb: # Push always via SSH, even for HTTPS-based remotes pushInsteadOf = bbh: pushInsteadOf = https://bitbucket.org/ [url "https://bitbucket.org/"] # The HTTPS fallback on machines without SSH keys insteadOf = bbh: [url "ssh://git@github.com/"] # Enables, for example, `git clone gh:torvalds/linux` insteadOf = gh: # Push always via SSH, even for HTTPS-based remotes pushInsteadOf = ghh: pushInsteadOf = https://github.com/ [url "https://github.com/"] # The HTTPS fallback on machines without SSH keys insteadOf = ghh: [url "ssh://git@gitlab.com/"] # Enables, for example, `git clone gl:gitlab-org/gitlab` insteadOf = gl: # Push always via SSH, even for HTTPS-based remotes pushInsteadOf = glh: pushInsteadOf = https://gitlab.com/ [url "https://gitlab.com/"] # The HTTPS fallback on machines without SSH keys insteadOf = glh: [url "ssh://git@git.webartifex.de/"] # Enables, for example, `git clone wa:alexander/dotfiles` insteadOf = wa: # Push always via SSH, even for HTTPS-based remotes pushInsteadOf = wah: pushInsteadOf = https://code.webartifex.de/ [url "https://code.webartifex.de/"] # The HTTPS fallback on machines without SSH keys insteadOf = wah: [user] # Set this in ~/.config/git/config_local to enable committing and signing # # name = ... # email = ... # signingKey = ... [include] path = ~/.config/git/config_local