What is a version control system?
A version control system is a piece of software that allows different authors to work collaboratively and asynchronously on a file, keeps track of their changes and alerts them when their edits are conflicting.
It can also be used by single authors to review and revert their changes.
It is distinct from a parallel editor, in which all authors edit the same file concurrently. In a parallel editor, the authors are forced to share all their edits with others, often restricting their creativity and causing data loss.
Why a new version control system?
There are basically two approaches to version control: either snapshot-based (git, mercurial, svn, or their ancestors), or patch-based (darcs). Historically, patch-based systems have been very simple to learn and use, but slow, whereas snapshot-based systems can be extremely fast, but are usually hard to use for more than simple operations. As an example, cherry-picking does not work well in git/mercurial, and merging is sometimes plain wrong.
Pijul combines these approaches, by representing its data in a more general way than snapshot-based systems, that allows for a patch-based interface.
What’s wrong with existing, widely-used, mature solutions?
Some things are really wrong, like using three-way merge for version control in general: there are examples (even real-world ones) where Git, Mercurial and SVN just do the wrong thing. See this article for more details.
Less objectively, our experience with patch-based tools make us believe that this is possibly the simplest way to control versions.
Does Pijul handle monorepos?
Due to the relatively young age of Pijul, we obviously have little experience with that, but the fact that Pijul patches commute means that users can work on arbitrary partial checkouts.
Pijul makes it easy to get only a subset of patches, and takes care of dependencies between patches to produce files consistent with a giant remote repository.
If you are interested in trying it out for a large project, please contact us: we are interested in helping you out, and would love to get feedback.
Where does the name come from?
Pijul is the mexican name of Crotophaga sulcirostris, a bird known to do collaborative nest building.
How does it compare to others?
It improves on darcs by speed, support for branches. Compared to git/mercurial, the workflows are quite different:
- In Pijul, when you work with others, you often type commands such as “send my changes to others”.
- In Git/Mercurial, one of the most common workflows is called “pull request”, by which you instruct the system to “ask the project to compare their current version with the version I have produced since the last time we did this, then compute the minimal set of changes that would “look consistent” with our changes”, where “consistent” is not what you think.
Did you solve the “exponential merge problem” darcs has?
Yes, we solved the exponential merge problem. The only caveat is that Pijul does not (yet) have an equivalent of
In other words, Pijul works in polynomial time for all patches that systems other than darcs know of. We’ve not yet thought all the theory of this through, but it might be added in the future.
Is it possible to refer to a specific version?
Yes! Although nothing is implemented so far, we currently see two possibilities:
The first one is a “git mode”, in which patches are explicitly ordered, by remembering the latest patch applied to a repository, and adding explicit dependencies to all subsequent patches. In this model, a patch hash contains enough information to compute the whole state: indeed, that state is just the transitive closure of dependencies of a single patch. However, this would yield an algorithm in O(|P|), where P is the set of patches in the given states.
The other possibility would be to use a “set hash” function, to compute unique universal identifiers for sets of patches. The main problem with that is that not all authors will know about the same patch set: Alice and Bob producing a patch A and B (respectively) in parallel will not know about patchsets containing the other’s changes, but not theirs.
What is the license of Pijul?
The license is GPL2, or any later version. This means in particular that Pijul is free software, and can therefore be used freely to develop any kind of projects, including commercial ones.
Pijul is trivial for whoever knows category theory.
This is relatively false. Category theory has certainly been an inspiration for Pijul, but categories are neither algorithms nor data structures in themselves. In order to get the semantics we wanted, especially the handling of multiple files, rollbacks and unrecords, designing and implementing new algorithms and data structures was at least as useful as learning theoretical stuff.
Can Pijul handle large files?
To some extent, yes, but this is not super well tested.
Does Pijul use lock files?
We do use lock files, but in a completely transparent way: a Pijul user never needs to interact with them. Of course, concurrent application of very large patches exclude each other.
Is Pijul interoperable with other systems?
Not yet, although the darcs team is working on it. Pijul’s patches do not store exactly the same information as in other systems. However, since Pijul generalizes both git/mercurial/bazaar/svn and darcs, it should not be too hard to convert our patches to these tools.
If you’re interested in the task, please contact us.
Why not a git merge algorithm instead of a whole VCS?
Indeed, we could have attempted to fix just that one bug in git merge where merging a whole branch at once, or all its commits individually, doesn’t always do the same.
Git contains the whole history of a project, so this seems possible. However, that would mean losing the patch-based nature of Pijul, which we think is more intuitive than the commits one (at the cost of requiring new algorithms).
In particular, cherry-picking in Pijul is done in such a way that you can cherry-pick from a branch, and then later merge other patches from that same branch. In git, cherry-picking means reorganizing history in such a way that the commits don’t have the same identity after the cherry-pick.
Moreover, git users sometimes report problems related to committing the inverse of a merge commit. In Pijul, there are no explicit “merge patches”, merging patches from a branch is equivalent to pulling from the branch.
In Git, cherry-picking means taking some commits, but not all, from another branch. This causes these commits to be rebased onto the current branch, losing their identity in the process. It usually works fine the first time it’s done, but then creates artificial conflicts if you want to cherry-pick again between the same branches, for no real reason.
We call that counter-intuitive, because it’s a fairly common workflow: many projects have branches name “stable” and “master”, and backport bugfixes from master into stable.
Do files merged by Pijul always have the correct semantic?
No. Semantics depends on the particular language you’re using, and Pijul doesn’t know about them.