Pijul a FOSS distributed version control system

(pijul.org)

150 points | by kouosi 5 days ago ago

23 comments

  • WhyNotHugo 7 hours ago

    I like the idea of Pijul, and checked it out a couple of years ago. Some basic quality of life features were missing, and are still missing.

    For example, diffs can't show context. They show lines removed and added, but can't show the previous and following line because of implementation details.

    Here's a diff: https://nest.pijul.com/pijul/pijul/changes/OMGL7JBCLSHWTIYP7...

    It's a little thing, but when looking at a diff, seeing three lines of context helps enormously.

    • winterqt 5 hours ago

      It’s possible this is just a Nest limitation? It appears that all the data is there to construct a diff with context, and I’d hope the CLI would do so…

  • landr0id 11 hours ago

    I think Pijul has some good ideas, but I’m afraid the network effect of git at this point is too strong.

    I think jj’s concept of being a front end for many backends and sharing a common UX over them is a good one, but without a pijul backend for existing tools I have a hard time seeing it catch on.

    • nchmy 9 hours ago

      yeah, jj + jjui is such an exceedingly pleasant experience that I can't imagine trying something else.

    • arikrahman 9 hours ago

      Jujutsu is great, maybe pijujutsu will catch on

  • hansvm 12 hours ago

    Last I tried to run Pijul (IIRC, 2.5yrs ago), there were major, seemingly unresolvable crashes for the simplest of operations on Mac and Linux. Has it gotten better?

    • jona-f 11 hours ago

      I tried it a few weeks ago and found it completely unusable. I do not get how they claim to be using it. I tried what I thought was the intended workflow and it's state got corrupted right away without any warnings.

      • jona-f an hour ago

        Edit: had another try. It seems to work now, very interesting

  • taschmex 12 hours ago

    See also the (slightly unhinged (affectionate)) talk at FOSDEM 2024; https://archive.fosdem.org/2024/schedule/event/fosdem-2024-3...

  • HexDecOctBin 8 hours ago

    Is Pijul implemented in form of a library (a la libgit2)?

  • alkonaut 11 hours ago

    What’s the current state of it in terms of stability, performance, features?

  • EnPissant 10 hours ago

    From their home page:

    > Why?

    > Commutation

    > In Pijul, independent changes can be applied in any order without changing the result or the version's identifier. This makes Pijul significantly simpler than workflows using git rebase or hg transplant. Pijul has a branch-like feature called "channels", but these are not as important as in other systems. For example, so-called feature branches are often just changes in Pijul. Keeping your history clean is the default.

    This is a useless property because the graph is only encoded at the patch layer. In the real world you have far more semantic dependencies than patch dependencies. ie, I have a patch that adds a function that calls a function added in another patch. Pijul doesn't know about that.

    > Merge correctness

    > Pijul guarantees a number of strong properties on merges. The most important one is that the order between lines is always preserved. This is unlike 3-way merge, which may sometimes shuffle lines around. When the order is unknown (for example in the case of concurrent edits), this is a conflict, which contrasts with systems with "automatic" or "no conflicts" merges.

    I can't remember being bitten by this, and you don't need Pijul to solve this. A merge algorithm that leverages `git blame` information would work just as well. It's just nobody cares enough to use such a thing.

    > First-class conflicts

    > In Pijul, conflicts are not modelled as a "failure to merge", but rather as the standard case. Specifically, conflicts happen between two changes, and are solved by one change. The resolution change solves the conflict between the same two changes, no matter if other changes have been made concurrently. Once solved, conflicts never come back.

    Conflicts coming back is not an issue in git. For some reason people think they need to use rebase when they should almost always be using merge.

    > Partial clones

    > Commutation makes it possible to clone only a small subset of a repository: indeed, one can only apply the changes related to that subset. Working on a partial clone produces changes that can readily be sent to the large repository.

    Git and other snapshot-based SCMs do this far far better. Git can checkout only a set of files or directories, and the tree-structure encoded in git objects in its db makes this very efficient. You could even build a fuse layer to lazily fetch content. With Pijul you would have to extremely carefully maintain your history to allow this. ie, when you have a patch that modifies 2 other patches, then those are merged forever if you need the changes in the merger. Imagine a PR that reformatted all files in the repo or changes a top level interface and fixed all users in the same PR. Whoops, everything is now interdependent, no more partial clones.

    • AlotOfReading 9 hours ago

      Git's patching functionality is pretty awful in actual practice. For example, try building a git patch that applies a standard set of patches between two divergent (vendored) kernel trees. It's usually a mess.

      It's also pretty easy to find a set of patches that have to be applied in order. Then someone copies those patches onto another divergent tree, which has it's own set of custom patches without renaming. This is dangerous in git and probably sensible in pijul.

      Haven't use pijul in practice, but it's not hard to imagine being better than git here.

      • EnPissant 9 hours ago

        I think patching/cherry-picking is just inherently complicated and needs intelligence applied. I don't think Pijul is going to be any better here.

        • riffraff 5 hours ago

          I remember working with darcs 20 years ago (pijul should be on that lineage) and cherry picking in that was way better than doing it with git since it meant "get this change and all the required ones" rather than "pick this commit".

          It still required intelligence (changes across files may not be tracked as dependent but actually are) but it was a different experience from what git provides.

          • EnPissant 4 hours ago

            If you really wanted, you could implement this on top of a snapshot based system by mixing in git blame information (or an algorithm that is similar). It's not hard to compute that text based dependency graph on the fly, though maybe expensive without caching.

        • WolfeReader 6 hours ago

          Cherry picking is just convenience for something that anyone could do manually. If it didn't exist in the VCS, people would do it anyway and make tools to do it.

          Fossil's implementation is the best, since a cherry-picked commit always points back to its origin.

    • dan-robertson 10 hours ago

      For patch sets/commutation, I find their system appealing. I think it’s tempting to yearn for something better still (eg darcs had a kind of sed-like patch that could apply its search to patches that are merged with it). If you look at how big companies do development, code review, CI, etc into monorepos, this is typically done with diff-focused thinking. Having the VC system and associated metadata attached to the individual patches (or sets thereof) feels like it could be an improvement over rebases or complex merge structures.

    • emmelaich 6 hours ago

      > Git can checkout only a set of files or directories

      How do you do this? With submodules / subtrees?

    • WolfeReader 6 hours ago

      Speaking as a former Darcs user (Darcs is another patch-based VCS that Pijul draws inspiration from):

      "This is a useless property because the graph is only encoded at the patch layer. In the real world you have far more semantic dependencies than patch dependencies. ie, I have a patch that adds a function that calls a function added in another patch. Pijul doesn't know about that."

      Darcs solved this in two different ways.

      1. Dependencies. While Darcs patches would inherently "depend" on the last patch which affected the same lines, the committer could specify other patches as dependencies, handling exactly the case you described.

      2. Practicality. In reality, there's no scenario where someone is pulling your "use function X" patches and also not pulling the "define function X" patch. They could if they really want to, but this would be a lot of effort for a deliberately bad result. It would be like, in Git, cherry-picking the "use" patches without the "define" patches. In neither system would this happen by accident.

      "Conflicts coming back is not an issue in git. For some reason people think they need to use rebase when they should almost always be using merge."

      There's a big difference between "conflicts shouldn't come back as long as everyone does what I want" and "conflicts don't come back". As long as you're using Git with other people, the rebase-lovers and their problems will be a perpetual issue. I've been on 3 teams in a row with this problem.

      I deliberately moved away from Darcs after a few years - the benefit of snapshot VCS is that you don't just have the change, but you have the whole context in which the change happened. (Also branch discovery in Darcs basically doesn't exist; Pijul fixed this, at least!) I love Fossil and Mercurial for their adherence to accurate history.

      • jona-f 5 hours ago

        What I want is a system that records how conflicts are resolved and tries to apply that resolve. Lets say I have apply patch A, then patch B, there is a conflict, I resolve it. Then someone else applies patch B and then patch A. The VCS should know that this conflict is already resolve and apply the solution. Likewise when applying first patch C, then A and B, it should let you resolve the conflict from AB to ABC and again record the resolved conflict for the future. I'm actually fine with manually resolving conflicts, but don't want to it twice if I don't have to. This would be a great way to organize something like dwm, but I couldn't get it to work with pijul at all.

      • EnPissant 5 hours ago

        > 1. Dependencies. While Darcs patches would inherently "depend" on the last patch which affected the same lines, the committer could specify other patches as dependencies, handling exactly the case you described.

        I don't know who would want to put in the work of mapping out the semantic dependency graph because maybe some day someone might want to compose a slightly different set of patches. And even if everyone tried, it would surely still fail because that's so hard or impossible.

        > There's a big difference between "conflicts shouldn't come back as long as everyone does what I want" and "conflicts don't come back". As long as you're using Git with other people, the rebase-lovers and their problems will be a perpetual issue. I've been on 3 teams in a row with this problem.

        Just stop using rebase is much easier to socialize than let's all move to Pijul. It's also the correct thing to do.

        > the benefit of snapshot VCS is that you don't just have the change, but you have the whole context in which the change happened.

        I strongly agree with this and think it's the only tractable way to operate.