Skip to content
Tips: git tips and conveniences

Tips: git tips and conveniences

Why am I bothering to write about Version Control Systems(VCS) when so much material has been written already by more dedicated, more knowledgeable, more capable writers than me? At least partly1 because since there is so much writing about git (and the ecosystem of ancillary tools and workflows for how to use it/them well) that when I want to remind myself of some aspect or improve my usage, I start searching and get distracted by the firehose.

Digging

I spent much more time reading code than I do writing it2.

Filtering git log

Filter the change history shown by git log ...:

  • by branch with git log <branch_name>
  • by author(--author=...) or committer(--committer=...)
  • by date (--since=2025-04-03 or --before=2025-09-03)
  • by path

Viewing changesets

  • git diff COMMIT~ COMMIT shows the difference between that COMMIT’s ancestor and the COMMIT
  • See the manpage gitrevisions(7) for comprehensive details about specifying revisions and revision ranges in git commands.

Cloning repositories incompletely

Do you really need the entire history of a large repo that’s been around for ages? Probably not, eh?

  • git clone --single-branch ...: Clone only the history leading to the tip of a single branch
  • git clone --depth <n> ...: Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch
  • git clone --shallow-since="2025-01-01" ...: Clone commits since a specific date.

See https://git-scm.com/docs/git-clone and https://git-scm.com/docs/partial-clone for more.

stash

Use git stash when you want to record the current state of the working directory and the index, but want to go back to a clean working directory.

I will not try to improve the above sentence, from the git docs. I use git stash all the time - especially when I’m poking around reviewing someone else’s PR/MR branch and it stimulates an idea for a change I want to make that should not be part of this/their changeset.

I particularly like it in the form “in order to keep my focus on the effort of this review, stash my changes, put them into a new branch which I can then work on later”:

$ git stash
$ git stash branch new-branch-name

Clean up

Already-merged branches

Even if the filesystem usage of old, already-merged branches is not meaningful waste, let’s get into the habit of cleaning them up occasionally because cognitive burden is The Enemy.

Here’s the command that Spencer Dixon3 ended up with:

$ git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d

I prefer that:

  • it should be sorted by the date of the last commit
  • so I can conveniently review and then delete deliberately
$ git branch --merged origin/main --sort=-committerdate --format='%(committerdate:short) %(refname:short)'| grep -vE "^[0-9]{4}-[0-9]{2}-[0-9]{2}\s*(\*|main|develop)"

This conveniently allows passing to various invocations of head(1) or tail(1) for additional filtering with criteria like “N most recent” or “N oldest”.

Pending branches?

In the rush of development, sometimes I’m not allowed the luxury of only working on one changeset at a time - this show which local branches have not yet been merged to HEAD.

$ git branch --no-merged | grep -v '\\*\\|main\\|develop'

Configuration

There are so many knobs that enable customization of git(1). Here are a few that I usually want (by .gitconfig section):

core

  • editor vim --nofork
  • excludesfile

user

  • name
  • email
  • signingKey

aliases

The shell (bash, zsh, powershell, etc.) provides alias functionality that replaces the typed text before interpreting. git(1) also provides alias functionality.

Choosing which approach to use is mostly personal preference as far as I can tell, but I recommend choosing one and sticking with it everywhere. If you regularly work with git using several different shells, it’s possibly worthwhile to keep your aliases for working with git confined to git because then you can use the same .gitconfig, regardless of the shell/environment.

Specify in the [aliases] section of your .gitconfig:

[aliases]
# Reverse sort branches by last commit date, i.e. a proxy for "recent activity"
recent="branch --sort=-committerdate --format='%(committerdate:short) %(refname:short)'"

Tools

Tools I use

  • GitHub and GitLab both provide their own CLI tools for interacting with their services: gh and glab
  • gcli is a CLI client to interact with multiple software forges such as forgejo, github, gitlab.
  • difi: aid for reviewing.
  • ggc provides a more interactive interface than git(1).

Tools I’m exploring

See Also

worktree

TODO: look at https://blog.safia.rocks/2025/09/03/git-worktrees/ for combining worktree usage with –bare

Branching & Merging workflows


  1. plus my usual reasons↩︎

  2. This is already proving to be even more true in the new world of AI/LLM-assisted development. It was true before - not least because of “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” - Brian Kernighan. But also because I review code written by previous-me and others. ↩︎

  3. This was inspired by @spencerldixon and apparently the CIA↩︎

Last updated on