Using git worktree to work with different PostgreSQL patches

PostgreSQL send patches over the email for contribution and code reviewing and some times organizing multiple patch versions of different works can be confusing. In this post, I’ll share how I use git worktree to organize the development and reviewing of different PostgreSQL patches.

git worktree

The git worktree command allows you to organize multiple working directories associated with a single Git repository. This is extremely useful when you need to check out different branches simultaneously without the overhead of cloning the repository multiple times. Each worktree acts as an independent checkout, sharing the same .git directory and object database.

Untracked files in one worktree don’t exist in others. That isolation becomes really useful during development and review workflows.

If you work on multiple patches at the same time—or if you frequently review patch series—it’s common to accumulate different versions of the same patch. For example, after working on the extension_control_path patch, I ended up with a collection of untracked patch files like:

?? v1-0001-Fix-extension-control-path-tests.patch
?? v1-0001-Flesh-out-docs-for-the-prefix-make-variable.patch
?? v1-0001-Make-directory-work-with-extension-control-path.patch
?? v2-0001-extension_control_path.patch
?? v3-0001-extension_control_path-fix-TODOs-and-add-tests.patch
?? v4-0001-Flesh-out-docs-for-the-prefix-make-variable.patch
?? v5-0001-Make-directory-work-with-extension-control-path.patch
?? v7-0001-extension_control_path.patch
...

Since these are all untracked files and I usually don't want to remove them because sometimes I need to go back to a previous version to compare with the new one, simply switching branches with git switch <branch> would leave me with a cluttered directory full of unrelated .patch files from other developments or reviews.

On top of that, different patches may require different build configurations and reconfiguring the build system every time I switch branches is not cool.

How I use it

To manage this situation, I use a separate worktree for each patch that I’m reviewing or developing, and I create a dedicated PostgreSQL build and installation for each of them.

My main PostgreSQL source tree lives at ~/dev/pgdev, and I create worktrees as:

~/d/pgdev ❯❯❯ ls -lh ~/dev/pgdev/
dblink-scram/
postgresfdw-scram/
extension-control-path/
pgdump-non-textmode/
postgresql/ # <- Master

I create a new worktree from the master branch/worktree like this:

git worktree add ../new-patch

I then configure the build system for each worktree:

meson setup build --prefix $(pwd)/pginstall --buildtype=debug -Dcassert=true -Dtap_tests=enabled

This keeps things clean and isolated. I don’t have to worry about untracked files for other branches when I'm working. Each patch lives in its own directory with its own build artifacts and settings.

Fast Switching with Fish Shell

I also use the Fish shell, and I’ve bind <ctrl>w to quickly switch between worktrees using fzf:

function switch_git_worktree
    set selected_path (git worktree list | fzf | awk '{print $1}')
    if test -n "$selected_path"
        cd "$selected_path"
        commandline -f repaint
    end
end

bind \cw switch_git_worktree

Final Thoughts

Just give a try to git worktree it might be something really useful, even if it's sounds a bit strange at first.

Comments

Popular posts from this blog

Hacking PostgreSQL - How SQL is compiled using LLVM?

Paper notes - Exploiting Cloud Object Storage for High-Performance Analytics