# core config
[core]
    pager = delta
    excludesFile = ~/.config/git/exclude
[user]
    name = Bill Mill
    email = bill@billmill.org
    signingkey = ~/.ssh/id_ed25519.pub

#
# config options
#
# https://blog.gitbutler.com/how-git-core-devs-configure-git/
[branch]
    sort = -committerdate # sort branches by most recently committed
[column]
    ui = auto # show branch names in columns
[commit]
    verbose = true # add the commit diff to the editor message
    gpgsign = true
[credential]
    helper = osxkeychain
[diff]
    algorithm = histogram
    colorMoved = default
    compactionHeuristic = true
    # replace the a/ and b/ in your diff header output with where the diff is
    # coming from, so i/ (index), w/ (working directory) or c/ commit.
    mnemonicPrefix = true
    renames = true # detect if a file was renamed (slightly more expensive)
    # don't show the annoying a/ and b/ prefixes in git diffs, though setting
    # this option breaks patch/apply. Sigh.
    # https://stackoverflow.com/a/57340649
    # noprefix = true
    # show the difference between branches in a submodule in a git diff
    submodule = log
[fetch]
    all = true
    prune = true
    pruneTags = true
    writeCommitGraph = true
[help]
    autocorrect = prompt
[http]
    # I was getting hangs when pushing to github, and this resolved it 🤷
    postBuffer = 524288000
[init]
    defaultBranch = main
[interactive]
    diffFilter = delta --color-only
[merge]
    conflictstyle = zdiff3
[push]
    autoSetupRemote = true
    default = simple
    followTags = true # always push local tags, without tag push
[rebase]
    autoSquash = true
    autoStash = true
    updateRefs = true
[rerere]
    enabled = true
    autoupdate = true
[tag]
    sort = -authordate # sort tags by most recently authored

# Git doesn't check the validity of commit hashes by default
# https://groups.google.com/forum/#!topic/binary-transparency/f-BI4o8HZW0
#
# ... I turned this off a few months later because several of the git repos
# I depend on for vim plugins have fsck errors. Even python requests does.
# I wish they didn't.
#
#[transfer]
#    fsckobjects = true
#[fetch]
#    fsckobjects = true
#[receive]
#    fsckObjects = true

#
# aliases
#
[alias]
    br = branch
    ci = commit
    co = checkout
    # to debug an alias:
    # git debug <aliasname>
    # https://stackoverflow.com/a/39468026/42559
    debug = !GIT_TRACE=1 git
    lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%C(bold blue)<%an>%Creset' --abbrev-commit

    # git alias for listing the files in the current directory, along with
    # their hash, author, and a hyperlink to the filename
    #
    # git aliases operate in the root of the git repo by default, so we need to
    # cd into the current directory using GIT_PREFIX
    # https://stackoverflow.com/a/26243454/42559
    #
    # Using :(glob)* gets us the files in the current directory only, instead of
    # listing recursively
    #
    # Here's a version that doesn't use hyperlinks for the file names:
    # ls = ! cd ${GIT_PREFIX:-.} && git ls-files -z ':(glob)*' | xargs -0 -n1 -I{} -- git log -1 --format=\"%<(20,trunc)%aN %<(12)%h%<(24)%ar{}\" {}
    #
    # Here's a version that does use hyperlinks:
    # - use %x1b for literal escape characters
    # - use %x3b for semicolons; otherwise git can't parse this config file
    # - escape backslashes
    # - git's parser turns them into single slashes inside the single quotes
    # - hyperlink format: \e]8;;<url>\e\<link text>\e]8;;\e\ 
    #
    # this became: https://github.com/llimllib/git-ls
    #
    # ls = ! cd ${GIT_PREFIX:-.} && git ls-files -z ':(glob)*' | xargs -0 -n1 -I{} -- git log -1 --pretty=format:'%<(20,trunc)%aN %<(12)%h%<(24)%ar%x1b]8%x3b%x3bfile:{}%x1b\\{}%x1b]8%x3b%x3b%x1b\\' {}

    re = restore
    st = status
    sw = switch
    wt = worktree

    # Show branches, verbosely, sorted by last touch, with commit messages.
    brv = "!f() { git branch --sort=-creatordate --color=always --format='%(color:reset)%(creatordate:short) %(color:bold white)%(align:2,right)%(upstream:trackshort)%(end)%(color:nobold) %(align:40,left)%(color:yellow)%(refname:short)%(end) %(color:reset)%(contents:subject)'; }; f"
    gone = !git branch --format=\"%(refname:short) %(upstream:track)\" | grep \"\\[gone\\]\"
    rm-gone = !git branch --format=\"%(refname:short) %(upstream:track)\" | grep \"\\[gone\\]\" | cut -f1 -d \" \" | xargs -I{} git branch -D {}

#
# Delta config
# https://github.com/dandavison/delta
#
[delta]
    navigate = true  # use n and N to move between diff sections
    light = false # set to true if you're in a terminal w/ a light background color (e.g. the default macOS terminal)
    # https://dandavison.github.io/delta/configuration.html
    features = decorations
    line-numbers = true
    # enabled dynamically in zshrc instead; used for wide terminals but not for
    # narrow ones. https://github.com/dandavison/delta/issues/359
    # side-by-side = true

    # enable clicking on line numbers to jump right to the file in vim.
    # Unfortunately because of the way I've configured kitty, right now this
    # doesn't work when you're in the pager.
    #
    # https://dandavison.github.io/delta/grep.html?highlight=hyper#grep
    # https://notes.billmill.org/computer_usage/terminals/kitty.html#opening-files-with-clicks
    # https://mastodon.social/@cfbolz/112095079659025365
    hyperlinks = true
    hyperlinks-file-link-format = "file:///{path}#{line}"

#
# color config
#
[color]
    branch = auto
    diff = auto
    status = auto

[color "branch"]
    current = yellow reverse
    local = yellow
    remote = green

[color "diff"]
    meta = yellow
    frag = magenta
    old = red
    new = green

[color "status"]
    added = yellow
    changed = green
    untracked = cyan

#
# LFS config
# not sure where I got this from or if it's a good idea, honestly
#
[filter "lfs"]
    clean = git-lfs clean -- %f
    smudge = git-lfs smudge --skip -- %f
    required = true
    process = git-lfs filter-process --skip

[worktree]
	untrackedfiles = .claude
	untrackedfiles = .env
	untrackedfiles = .env.local
	untrackedfiles = .envrc
	untrackedfiles = .pi
	untrackedfiles = .tool-versions
	untrackedfiles = db.sql
	untrackedfiles = mise.local.toml
	untrackedfiles = mise.toml
	untrackedfiles = modd.conf
	untrackedfiles = staticfiles
	backgroundcopy = node_modules
	backgroundcopy = staticfiles

[gpg]
	format = ssh
