Here are some snippets from my Git configuration file.
These days, I use a much simpler workflow and configuration since doing more trunk-based development, but in general, I rebase instead of merging by default, and prefer to use fast-forward merges that doesn't create a merge commit.
`branch.autosetuprebase = always` and `pull.rebase = true` configure Git to always rebase instead of pull. It does this for all branches, though I might override this for `main` branches.
`pull.ff = only` and `merge.ff = only` prevents creating a merge commit and will prevent the merge if it would create one. If I needed to override this, I could by using the `--no-ff` option on the command line.
I use `checkout.defaultRemote = origin` to ensure that the `origin` remote is used if I have multiple remotes configured, and `push.default = upstream` to set the default remote to push to.
`merge.autoStash` allows for running merges on a dirty worktree by automatically creating and re-applying a stash of the changes, and `fetch.prune` will automatically prune branches on fetch - keeping things tidy.
I also have and use a number of aliases.
Some like `pl = pull` and `ps = push` are shorter versions of existing commands, and some like `aa = add --all`, `fixup = commit --fixup` and some additional arguments to commands.
I also have some like `current-branch = rev-parse --abbrev-ref HEAD` and `worktrees = worktree list` which add simple additional commands, and some like `repush = !git pull --rebase && git push` which use execute shell commands to execute more complex commands or combine multiple commands.
This is a snapshot of my Git configuration. The [full version is on GitHub](https://github.com/opdavies/dotfiles/blob/7e935b12c09358adad480a566988b9cbfaf5999e/roles/git/files/.gitconfig).