In git you can do something like HEAD~ to refer to the parent commit of HEAD. Mercurial has a similar feature called revsets which JJ took inspiration from (including the name). The revset language is a declarative query language—not unlike SQL—that lets you specify a set of revisions (a revset) that match certain criteria. It ends up looking more like set operations than SQL, but the idea is similar. In JJ you can use @ to mean “the current commit”,...| willhbr.net
In my previous post I wrote a compiler that turns Python code into a tmux config file. It makes tmux evaluate a program by performing actions while switching between windows. My implementation relies on a feature in tmux called “hooks” which run an command whenever a certain action happens in tmux. The action that I was using was when a pane received focus. This worked great except I had to do some trickery to avoid tmux’s cycle detection in hooks—it...| willhbr.net
You can use features of tmux to implement a Turing-complete instruction set, allowing you to compile code that runs in tmux by moving windows. I feel like I really have to emphasise this: I’m not running a command-line program in tmux, or using tmux to launch a program. I can get tmux to run real code by switching between windows. Watch a demo of it in action below or on YouTube: This whole mess started when I solved an issue...| willhbr.net
In 2023 I got into running things in containers after a getting over my fear of them. I quickly realised that running podman commands manually was tedious, and after a few different approaches I made pod, a poorly-named wrapper around the podman CLI that lets you define how to build an image and run a container in a config file, then run containers with pod run instead of some long podman command. Since then I’ve used it in basically every...| willhbr.net
It is an accepted wisdom that it’s more important to write code that is easily read and understood, in contrast to writing code that is fast to write1. This is typically used in discussions around verbose or statically typed languages versus terser dynamically typed languages. The kernel of the argument is that it doesn’t take you that much long to write a longer method name, spell out a variable in full, or import a class. Wheres it can take someone...| willhbr.net
Most camera reviews are pretty decent when it comes to photo and video quality (although for the type of cameras I buy, photo quality is usually an afterthought1). The thing that seems to be left out is the annoying nits and limitations that you become aware of after using something for a while. I just upgraded from the DJI Mini 2 to the DJI Mini 3 Pro and oh boy do I have nits to share. Shot on the Mini...| willhbr.net
We all know that it’s hard to share git repositories. Sure, you could upload to a site like GitHub or Codeberg, but that requires both you and whoever you want to share with to make an account. Wouldn’t it be great if you could share directly in your messaging app of choice? Just like you can share pictures and videos? Well, the obvious solution is to encode a git repo into an image, so you can share it however you...| willhbr.net
I’m a serial tinkerer and project starter, which means I end up leaving a trail of half-finished (or half-started) projects everywhere I go. If it’s not new projects, I’ll drop in to some existing project and make some changes, then forget about them for months or sometimes years. Thankfully for a long time I’ve kept all my projects in a consistent location: ~/Projects so they’re not hard to keep track of, but that does mean I have to actually go...| willhbr.net
You know how there’s that scene in Apollo 13 where they need to work out how to fit the different CO2 filter using only the equipment available on the spacecraft? Well imagine if you needed to send a video to someone but the only software they had to play it back was tmux. This hasn’t happened to me yet, but thankfully I’ve prepared in advance. Just in case. The most basic building block here is a tmux window. We’re not...| willhbr.net
podman-remote is a way of running Podman commands on a remote machine (or as different user) transparently. It allows you to add a transparent SSH layer between the podman CLI and where the actual podding happens. For the uninitiated, Podman is basically more-open-source Docker that can be used (mostly) as a drop-in replacement. The biggest difference is that it can run rootless—which means even if a process can escape the container, they’re still limited by standard unix permissions from...| willhbr.net
The question that everyone has been asking me since I compiled Python to run on tmux is: “can you actually do anything useful with this?”. I’m happy to report back that the answer is still no, but I can now use tmux to solve sudoku, and I can do it using a different and trickier approach than the one I used with the compiler. With projects like this, seeing is believing, so I made a quick video showing what it...| willhbr.net
I spent a bunch of time learning how to use JJ properly after I gave up on git. Up until this point, I had been dumping commits directly onto main and just pushing the branch occasionally. I had avoided learning the pull/merge request flow because it’s not something I use on personal projects, but it turns out to work pretty well. With a few tactically-deployed aliases I’ve got a pretty simple flow going. We start a new change with jj...| willhbr.net
tl;dr: I’ve been using jj for version control in my personal projects and it makes me much happier than using git. Continue reading for lukewarm takes on the git CLI. Firstly I’ll just get some disclaimers out of the way: I only use git (now JJ) for personal projects, I don’t use git at work. Also I work at Google, who currently fund development of JJ since the founder and main contributor is a Google employee—read this section of the...| willhbr.net