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.
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:
- Source
git-prompt.sh
from your shell init file. - Add the magic incantation somewhere in your prompt (e.g.,
PS1='\u@\h $(__git_ps1 " (%s)")\$ '
). - 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!
The script contains detail usage instuctions, too↩︎