Pijul, better version control
Pijul is built on a mathematically sound theory of patches. It is fast, composable, and correct by construction.
Why look beyond Git?
Git is very successful, and for good reasons.
But success does not always mean that every design decision was the best, or that things can't be further improved on.
I accept that version control is complex. That's why we need tools. However, I want the tool make the easy things easier and the complex things simpler, instead of just "making things possible"!
With Git, I suffer. Rebasing, unecessary merge conflicts, or the distinction between commits and the changes. They all add friction, and it seems to be imposed by the tool itself, not by the unavoidable nature of version control itself.
I am not alone in thinking that, that is why there are still new version control tools being worked on. I can't say I have looked at all of them, but here are two that I have checked out:
- Jujutsu seems to focus on simplifying some of the classic Git "gotchas". It was designed to remain git-compatible.
- Pijul is a different angle: changes are first-class objects. Rather than treating history primarily as a sequence of snapshots, it is designed around patches and the dependencies between them. Pijul was inspired by Darcs, is written in Rust and self-hosted (i.e. version controlled in Pijul).
A different model of change
An interesting feature is composability. Independent changes can be combined without requiring everyone to agree on one privileged linear history. That is quite nice when work naturally happens in parallel.
Why is this interesting?
I am less interested in version control as "a collection of commands" than as "a model for collaborative work". Or course, there are marginal improvements if cleaning up the syntax of commands or streamlining the expression of version control operations into commands (this seems to be what Jujutsu is doing?). However the more fundamental difference with Pijul is conceptual:
- Is a patch-based theory a better deal?
- Can we reduce the number of conflicts rather than only provide different or slightly easier commands to resolve them?
Pijul is really looking promising, check out the "Why pijul" and the "See it in action" sections on the Pijul front page, they really hit hard and pinpoint exactly the opportunity!
Of course, there is also a practical question. A better model is only useful if it can coexist with the great ecosystem built around Git. History is full of tools that were "better on paper" but failed to gain much adoption (Betamax anyone?). That makes Pijul's interoperability with Git at least as important as its underlying theory.
Here is a kind of mind map I start with:
| Topic \ Tool | Git | Jujutsu | Pijul |
|---|---|---|---|
| Fundamental object | Commit/snapshot | Change + snapshot | Patch/change |
| History | Graph of commits | Graph of changes/commits | Dependencies between patches |
| Working copy | Special state outside history | Always a commit | Working tree relative to recorded changes |
| Branches | First-class refs | Mostly just names/bookmarks | Channels |
| Merge | Merge commits / 3-way merge | Merge commits/change graph | Apply/compose patches |
| Rebase | Important operation | Much less important | Largely unnecessary |
| Conflict | Merge state in working tree | Conflicts can be recorded in commits | Conflicts are part of repository state |
| Git compatibility | Native | Excellent | No |
| Mathematical change model | No | No | Yes |
A word on Channels
Formally, a channel is simply a pointer to a set of patches or changes.
- There is always a default main channel in every repository.
- You can list channels with
pijul channel, create a new one withpijul fork <name>orpijul channel new <name>, and switch between them usingpijul channel switch <name>.
Key and interesting differences from Git Branches:
- Commuting Changes: In Pijul, independent changes commute, meaning their order does not matter. Because of this mathematical property, you often do not need to create a separate channel for things you would use a Git branch for.
- Same Rebase and Merge: A change's identity does not depend on the channel it resides on. Rebase and merge are fundamentally the same operation.
- Persistent Conflict Resolution: Conflicts happen between changes rather than branches or line numbers. Resolving a conflict on one channel automatically solves that same conflict across all other channels, eliminating the recurrence of solved merge conflicts. (Are you getting interested now? If you've been using git… you probably are!)
Experimenting further
For now, I want to explore to see if it works and feels better. I will try to use Pijul on some personal projects and compare the day-to-day workflow with Git, especially around parallel changes and publishing repositories.
React or leave a comment
Comments are moderated by email — nothing you send here is published automatically.