The intention is to keep interesting tools around git here, maybe even experimental ones

Junio C Hamano, git/contrib/README

Git’s source repo includes a “contrib” directory containing tools that extend git.

But these tools are hidden from most users. And they require extra steps to install. So they’re less well-known than they should be.

These are the tools I’ve found useful.

diff-highlight

diff-highlight makes git diff easier to read, making subtle changes stand out.

Standard git diff (top) vs. diff-highlight (bottom)

Git diff-highlight’s author described it as “a simple and stupid script for highlighting differing parts of lines in a unified diff.”

Try it out with:

git log -p --color | /usr/share/doc/git/contrib/diff-highlight/diff-highlight

If you like what you see, make it your pager with this oneliner:

git config --global core.pager '/usr/share/doc/git/contrib/diff-highlight/diff-highlight | less'

git-prompt.sh

git-prompt.sh makes information from git status accessible at a glance.

For the basics, it’s easy1:

  1. Source git-prompt.sh from your shell init file.
  2. Add the magic incantation somewhere in your prompt (e.g., PS1='\u@\h $(__git_ps1 " (%s)")\$ ').
  3. Tweak with environment variables until you get a prompt that works for you.

Here’s my config:

GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWUPSTREAM="auto verbose"
. ~/bin/git-prompt.sh
PS1='\u@\h $(__git_ps1 " (%s)")\$ '

Inside a repo on main in a clean worktree, this shows:

me@💻 (main|u=)$

If you make a big mess, the prompt makes it impossible to miss:

me@💻  (main *+%|u+1-1)$
         │   │││ │ │ │
         │   │││ │ │ └── count: changes behind upstream (-1)
         │   │││ │ └──── count: changes ahead of upstream (+1)
         │   │││ └────── indicator: upstream set (u)
         │   ││└──────── indicator: untracked file (%)
         │   │└───────── indicator: staged, uncommitted change indicator (+)
         │   └────────── indicator: unstaged change (*)
         └────────────── info: current branch name

A git-aware shell prompt solves a multitude of woes. My prompt has saved me from countless sticky git situations.

subtree

git submodule allows you to include other git repos within your repo. But anyone who’s used it can tell you: it gets confusing fast.

git subtree eases git submodule pain.

Both submodule and subtree let you add a library as a subfolder of your project.

But subtree integrates the history of the library into your main project. And you can get it back out as a standalone library later.

This lets you branch and tag a project along with its libraries—a critical limitation to git submodule.

For example:

git clone https://github.com/thcipriani/my-parent && cd my-parent
git subtree add --prefix=mylib https://github.com/thcipriani/my-library

Adds my-library to the my-parent project in a folder called mylib—the two projects’ history gets merged. From there, it works like a monorepo.

After I’ve made a series of changes inside my-parent, including changes to mylib, I can extract the history of mylib with:

git subtree split --prefix=mylib
0b64183b7a0a27ad1f466d5cac61cbfefd1e598e
git push https://github.com/thcipriani/my-library 0b64183b7a0a27ad1f466d5cac61cbfefd1e598e:master

Or, in one step:

git subtree push --prefix=mylib https://github.com/thcipriani/my-library main

More

  • git worktree: is an example of a contrib script that’s made the jump to a git built-in command. Maybe, in time, other commands in this list will, too.
  • git-jump: opens your editor to interesting bits of code. For example, git jump diff opens vim to the first diff hunk.
  • mw-to-git: lets you read and edit MediaWiki wikis (like Wikipedia) as if they were a local git repo (cf: maintaining userscripts with git)
  • pre-auto-gc-battery: a hook that prevents git’s automatic garbage collection if you’re on a laptop using battery power

And there are even more weird gems to unearth. Take a look!


  1. The script contains detail usage instuctions, too↩︎