Use broot and meld to diff before commit

4 minute read Published: 2020-07-05

Before every commit, I do a short review of what I wrote. And usually there's a few last things to fix, mainly comments.

While I like scm-breeze for most git related operations, I don't find it convenient enough for this specific kind of review.

So, now I type gg which gets me this broot based TUI:

gg

Only the new and modified files are listed, along with their status and modification date.

From there,

This blog post first tells how to configure broot to get this interface, then explains how it works.

Installation

First, if you don't have it, install broot and maybe take the time to learn what it is.

We'll create a specific config file so that we can launch broot in a dedicated "git diff" mode without messing with the standard usages.

Create the git-diff-conf.toml file along the default one (in ~/.config/broot on linux), with this content.

Next create the gg command. My solution is to add a function in ~/.bashrc :

# git diff before commit
function gg {
    br --conf ~/.config/broot/git-diff-conf.toml --git-status
}

This command launches broot with two arguments. The first one tells it to use our specific config file while the other one starts it in "git-status" mode.

If necessary, load the function:

source ~/.bashrc

Now, the gg command will get you something similar to the screenshot illustrating this post.

If you just want it to "work" and it does, you may stop reading here.

If it doesn't work yet, or if you want to know how it's done or to customize the installation, please read along.

What's in the config file ?

The default_flags line tells broot to start with the hidden files visibles, and to show the date.

default_flags = "hd"

We could have alternatively added -hd to the function's command.

The cols_order line specifies the column order. You may swap chars in this string to better understand. The ones which really matter for us are d (date), g (git status), b (branch), and n (file name).

cols_order = "scdgbn"

Following are the verb definitions (see related broot documentation if you want to know more).

First the shortcut for edition:

[[verbs]]
invocation = "edit"
key = "ctrl-e"
shortcut = "e"
execution = "$EDITOR {file}"
leave_broot = false

If $EDITOR isn't defined for you, you may directly write the path to your favourite editor.

Next we add the command for diffing a file on enter:

[[verbs]]
invocation = "git_diff"
shortcut = "gd"
key = "enter"
leave_broot = false
execution = "git difftool -y {file}"
apply_to = "file"

The apply_to attribute prevents this behavior to apply to directory. I prefer to be able to navigate in the usual broot way.

This assumes the difftool has been configured on your system. Here's for example my ~/.gitconfig:

[diff]
	tool = meld
	prompt = false
[difftool]
	prompt = false

The git add on ctrlA is added with this verb definition:

[[verbs]]
invocation = "git_add"
shortcut = "ga"
key = "ctrl-a"
leave_broot = false
execution = "git add {file}"
apply_to = "file"

git checkout lets you cancel the changes for a file:

[[verbs]]
invocation = "git_checkout"
shortcut = "gco"
leave_broot = false
execution = "git checkout {file}"
apply_to = "file"

Finally, the last part of the config file is the [skin]. Changing colors is not strictly necessary but it helps me know when I'm in the "normal" broot and when I'm in the one configured for git diff.

If you use this, or if you'd like to have a different broot configuration and don't see how, come and tell me.