I used darcs before git and it was very nice - the first distributed RCS I'd ever used. I believe pijul is a follow-on to that so it should be great. Later on I used Mercurial and it was very easy with a great GUI and it felt safe.
git is like shaving with a straight shaving razor - alarming until you've developed your set of frequently used commands and ways to stay out of trouble.
Even I have to use git because who uses anything else? Every project that I know that used Mercurial dropped it in the hope of getting more contributions.
We have all rushed like Lemmings into Github - now owned by those nice people at Microsoft - who have used it to automate our jobs with copilot. How ridiculous that Open Source has been embraced into the clutches of the Empire on such a scale! :-) I am joking but only a bit.
Not really. The real innovation of a lot of these alternative DVCS systems is that they free the state of the source from being dependent on the history that got you there. Such that applying patches A & B in that order is the same as applying B' & A' -- it results in the same tree. Git, on the other hand, hashes the actual list of changes to the state identifier, which is why rebasing results in a different git hash id.
So long as you require git compatibility, you're kinda stuck with git's view of what history looks like. Which is rather the point.
Supporting conversion with some lossy tendencies is a good idea, but maintaining compatibility will stifle innovation as al bugs & design decisions cannot be fundamentally worked around.
Adjacent, I heard folks praising Forgejo for its Actions & Microsoft GitHub compatibility, but that means you are still left with the same YAML spaghetti and its other limitations. What would have been nice is something better for CI--something that prompts the project to want to switch to get a better experience. As such, while I agree with the moral reasons to switch to non-proprietary software, the reason for switching is philosophical, not philosophical + technical. I feel being a wrapper around Git or Git compatibility will likely fall in this category rather than being more compelling.
> Even I have to use git because who uses anything else?
It's pretty widely not used in the games industry because its support for media files is poor, it's pretty difficult to train artists to use it, the integration with game engines is pretty poor, git LFS is a layer of complication on a system that already has UX that's difficult for artists, git LFS hosting is an additional can of worms, there's essentially no file/directory-level permissions for managing contract work (and doing so with submodules+LFS is complicated).
There are many people who work on open source professionally, but as a hobbyist programmer I find it odd to worry about Copilot automating my “job.” This is like complaining that your dishwasher or robot vacuum cleaner automates your job because you don’t do the work by hand anymore.
If you’re getting paid then it makes some sense to worry about automation, but if you’re not, automation is good. You can do more. The community can do more. We can take on more ambitious projects.
If you are a hobbyist programmer, it is not your "job" . So it is not automating your job for the moment but the professional programmers' job, isn't it?
There is empirical evidence that git is diabolical: Git can be thought of as an experiment in how to make an API GUI-proof. There is no possible direct manipulation visual representation of git operations that doesn't dumb it down.
I find gitx really helpful at understanding what's going on in git. Especially its ability to drag branches around the tree shows you that branches are just labels, they aren't the actual code. It doesn't do everything, but what it does do certainly isn't dumbed down.
You definitely need a gui to do partial commits. git add -P is just horrible to use.
So Pijul is patch-based. And not in the boring implementation-sense of storing changes as a series of patches. In the interesting sense that patches can be ordered in more arbitrary ways. On the other hand Git is snapshot-based. And Git was built for the Linux Kernel (specifically from the perspective of the lead maintainer). But my impression from the outside is that the Linux Kernel development is very “patch-based”. First of all in the sense of sending patches via email. But also in the sense that these patches can be applied to multiple trees (not just the Linus tree) and different subsystems have to cherry-pick commits (i.e. picking a commit and applying it as a patch, creating a new commit somewhere else). And it seems that people are concerned about tracking what patches are where, what commit (which can correspond to many commits according to cherry-picks) fixes whatever commit. The people behind Patchwork (a tool for maintainers which tracks patch series) is concerned about being able to track patches; the usual `git patch-id`, naming heuristics, etc. does not seem good enough.
And as patches go through different contributors and maintainers they accumulate trailers in the form of signed-off-by and things like that. Even non-trailer (not key-value line) changelogs like: `[<initials>: fixed typo/ fixed off by one]`. And if the change is in the code then the patch content changes (not just the commit message).
The Git project is also pretty patch-based in its development. Even for those who only cares about the maintainer tree: these patches apply to this other in-flight patch series; this diff here can be applied on top of your pending patch series; this patch series is from our ongoing work at Gitlab (company); I’m resending this patch series that X did three months ago but seemed to have abandoned; etc.
My understanding is that a big part of the reason that Git is snapshot based is for reliability and for ease of checkout -- being snapshot based means Git doesn't need to replay commits every time you check things out.
That likely comes with some downsides (cherry-picking does come to mind, yes), but also seems like some serious upsides, one of the biggest one being that simplicity. It's relatively easy for me to reason about what Git is doing under the hood. I like that I'm seeing that Pijul's patch operations are associative, I like at first glance what I'm seeing it say about merges, but it's not making it clear to me what the downsides are.
Is the idea that arbitrary checkouts take longer, but that's generally fine since people don't do them very often? Or am I over-estimating how much complexity/performance costs that building a vcs like this would incur?
There's no reason you can't cache tree snapshots in a pijul/darcs setting. That's just an implementation detail. The difference is more in how a rebase or merge operation works internally, and how essential the particular history is to the current workplace state.
Pijul does a better job of recognizing that "A -> B -> C" is the same as "B' -> A' -> C".
The original author sold it as a stupid content tracker. Which in part meant that the implementation was simple.
There ain’t a whole lot to the first commit of Git. Some hundred lines which consists of manually preparing a commit by sending the current snapshot to the “cache” (nowadays “index”) which compresses it and then building a commit by specifying the parents and a commit message (like git-commit-tree but I don’t know if that was around back then).
Funny timing of this post. This past weekend, I dedicated myself to creating a comprehensive set of tools for integrating Pijul seamlessly into Emacs. This includes collaboration features through org-mode, which I believe will be refreshing. I'm eager to share it with the community shortly. For fellow Emacs & Pijul enthusiasts, keep an eye out!
As probably the person in the entire world who has been wanting this for the longest, thank you!
Please share on Pijul's Zulip, and ask for any help you may need.
I'll try to allocate some time this weekend and also sign up for Zulip. Currently, I'm considering the best way to distribute it. Given that users are familiar with use-package and MELPA, it seems I may need to incorporate Git as well.
I'm just starting to explore Pijul, to be honest. My interest was sparked when I revisited an old Haskell project and remembered using Darcs years ago, which led me to research Pijul. I'll be able to share more insights in a few weekends, once the remote communication components of vc-pijul are established.
I seem to recall very positive comments regarding pijul's underlying architecture/theory. However, as I don't have the headspace to delve into it, I would love a blurb at the beginner level that highlights the benefits of using pijul compared to other VCS, and a very brief and simple comparison between pijul and git (focusing on the differences).
I have the same question every time Pijul comes up on HN, and I have yet to get an answer:
Can someone give me a real world example (person a makes X change, person b makes y change etc. etc.) that would work better in Pijul than Git?
I am a complete believer on a sound underlying model producing better results for users at a high level, but I'm not clear on how it maps through for Pijul. I think that's what they're missing in the sell - the ability to explain to devs "it will make your life easier in the following specific ways".
For example when getting my employer moved from SVN to Git I could talk to people about how much easier it was to create and then merge a temporary branch for a feature in Git. Git understand the topology of the history, knew the merge base and had better merge algos so the only pain you had was when there was an actual conflict - two people editing the same file location. It also could track renames, which were incredibly painful to merge in SVN.
> Can someone give me a real world example (person a makes X change, person b makes y change etc. etc.) that would work better in Pijul than Git?
Simplified example:
Persons A and B check out master branch.
Person A adds a.txt, commits and pushes.
Person B adds b.txt, commits and tries to push and...
1) git will not accept the push because it's not on top of current master branch, person B needs to fetch and merge/rebase before pushing again.
2) pijul will accept the change (after a pull, but no rebase) because patches A and B are independent of each other and does not matter which order they are in the history (keyword: commutation).
The value of Pijul will only start to show when you get into big three way merge scenarios. Which git users avoid like the plague because they are so nasty to deal with. Demonstrating this would need a much larger example.
edit: clarification a pull is still needed in case 2, but no rebase or merge because there isn't one for commutative patches
The thing I like most is that cherry-picks are real, not simulated.
In git, a cherry-pick pulls the change you're interested in off a branch, making a copy in the process. If you later merge or rebase that branch, there are two versions of it in the history, this can have practical consequences, it's not uncommon for this to generate conflicts which wouldn't be there without the cherry-pick.
In pijul, a cherry-pick is just one way to apply a patch. It's the same patch in both branches, so the history doesn't contain two versions of the change, only one. So there is no difference in the result between 'branch, cherry-pick, merge' and 'branch, merge'. Ever.
> It also could track renames, which were incredibly painful to merge in SVN.
They are still a pain in Git as well. Rename a class and its usages in C# project, for example, and it randomly breaks based on some arcane heuristics.
As for actual question you posed - partial checkouts. Your artist don't need to checkout code, but can work on it art folder.
any time you rebase the same feature branch onto current main and solve the same conflicts pijul could probably do much better without hacks like rerere (which most people also do not use, so...)
- There's an example in the "why Pijul" page of our manual where Git completely reshuffles your lines, and no "custom merge algorithm" could possibly solve it. I would be terrified if I were working on crypto/security code and I knew my VCS was doing that: https://pijul.org/manual/why_pijul.html
- Patch commutation makes all big instances small: no need for submodules, partial/shallow clones, etc. Patch commutation lets you work on a small part of the repo by cloning only the patches you're interested in, and submit patches that mechanically commute with all patches on other parts of the repo.
- Free cherry-picking: no need for strict disciplines, you can just introduce a quick fix on your local work branch, and push just that to production. When you're ready merging the rest, you won't have to solve conflicts again (no need for Git rerere/Jujutsu/…)
- Many uses of branches reduced to "just use patches": many people, especially on fast-moving projects and "early days", don't really know what they're working on, and are dragged onto solving problems they didn't plan initially. Well, Pijul lets you focus on your work, then make patches, and then separate them into branches, thanks to commutativity.
- Separation of contents and operations: this really feels like the CSS3/HTML5 of version control. In Pijul, patches have two "detachable" parts, a part describing what the patch does (as concise as "I introduced 1Tb of data", i.e. just a few bytes), and the contents (not concise: the 1Tb themselves). You don't need the data to apply a patch, so when working on large files, you can record 10 different versions, and your co-workers will only download the parts that are still alive after that. No LFS required!
- Precise modeling of conflicts: conflicts are stored in our model, not "recorded" or "artificially first class". They're literally the core of our model, the initial theoretical motivation. Patches are where you need a good tool the most, and we record them and store your precious resolutions as actual patches, so they don't come back (no "git rerere" needed, and conflict resolutions can be cherry-picked).
Now, we also have less game-changing things like:
- Accurate and super fast "blame" (which we call "credit", and which doesn't require Pijul to look at the entire history like Git does).
- Generic diffs, and therefore merge, i.e. not necessarily line-based. We haven't implemented them, but you could in theory implement AST-based diffs on top of Pijul.
In day to day use, there's very little difference in the practical use of git vs. pijul. You edit files, commit then push. Of course the user interface is different and some of the terminology is different but it's still a distributed version control system.
As for the differences, the advantages are listed right there on the front page: commutation, merge correctness, first-class conflicts and partial clones.
Explaining these in more detail in a short example ("a blurb") is not really easy because you'd have to first set up an example three way merge (for example) and then study the behavior of git vs. pijul in detail. I recall seeing a video presentation from the Pijul authors which delved deep into this if you're interested.
But I'll give it a go anyway...
tl;dr: pijul can handle certain merge situations automatically where git requires you to manually resolve them
More than that. If you have ever had to fix a bug in code common to multiple maintained releases of a project, being able to apply the same patch to them all as its own thing instead of having multiple cherry-picked commits with identical content would be nice.
You're describing working on your own single-author project, in which case there is indeed little difference (Pijul has less tooling).
In practice on actual real world cases, there are lots of differences when you start working with others: even on a small project, you don't have to plan your feature branches anymore, conflicts are solved once and for all, you get free cherry-picking of bugfixes to your production branch, etc.
When your project scales, there are even more differences: commutativity handles large repos for free, patches describe large files much more efficiently than by giving their whole contents (which snapshots do).
I think that whatever VCS come today, it will have a hard time finding a broad adoption use case that overweight the massive footprint of git ecosystem.
I feel I'm missing something; for a version control system, you'd think managing different versions would be kinda central but in pijul that seems more like an afterthought. If I'm reading correctly you could use 'channels' same way as you use git tags, but that doesn't seem to be happening in practice.
For example I look at 'sanakirja' project. The current version is 1.4.1 and the previous version was 1.4.0, and the version before that was 1.3.3:
There is "Tags" tab which is empty, and channel selection drop-down that has only "main" channel. So if I want to browse code at version 1.3.3, or see the difference between 1.3.3 and 1.4.0, or even just see what versions there are, how would I do that? To me those seem like very elementary questions, and yet reading through the manual I can find no hints toward this direction.
There is a FAQ entry that seems relevant:
> Is it possible to refer to a specific version?
> Excellent question. Since Pijul operates on patches rather than snapshots, versions are essentially unordered sets of patches. How do we communicate a specific version number to one another? We solve this by abusing elliptic curve cryptography primitives.
But its not clear at all how those "version identifiers" can be used or indeed if they are even implemented at all yet? At least based on the manual, no commands seem to take "version identifier" as argument, nor can I see them anywhere in Nest web UI.
Oops, don't look at what we do! These repos have been used for dogfooding and bootstrapping extensively, they have the worst structures and aren't good examples of nice, clean workflows. The tool isn't really "experimental" anymore, its repos are still used for heavy experiments.
> But its not clear at all how those "version identifiers" can be used or indeed if they are even implemented at all yet? At least based on the manual, no commands seem to take "version identifier" as argument, nor can I see them anywhere in Nest web UI.
`pijul log --state` does that, and various commands (tags, fork) do it as well. Tags are due for a redesign, since they can be made much more efficient with a really cool new design, and make Pijul a perfect hybrid between patches and snapshots.
but the docs do not say anything about that, so it remains a mystery. also its still weird that their own projects do not use those tags, or is it just that the web UI isn't showing them properly?
I have used professionally Darcs, Mercurial, Subversion, and Git. I love distributed version control systems, and I love Git.
However, Pijul looks interesting, nice work!
Pijul has a number of stated strengths over Git, and looks like the version history is implemented as a CRDT from my first impression. Some of the statements make me wonder how many conflicts occur in real use. If they are equal to or less than the number it produces, great. If more than what Git produces, that's a barrier to adoption, as merge conflicts are one of the biggest pains when using Git.
For me though what appears one of its biggest strengths (commutative workflow) is also its biggest drawbacks. There are so many teams that are trained in git workflow and are used to it, that getting them to switch to a completely different style of workflow in sufficient numbers will take years.
Git compatibility is a key missing feature. Git had this with Subversion, and I think it's a big reason why Git won over many of the Subversion crowd.
The basic premise of Pijul is that the way they model changes leads to better merges, fewer conflicts, and (crucially) no cases of bad merges. Git can complete merges and do it incorrectly. https://pijul.org/manual/theory.html
This means that in some cases, Pijul will correctly merge where any of the git merge strategies would create a conflict. It also means that in some other (rarer) cases, Pijul will generate a conflict where git would not: git would guess, in effect, and either get it right or get it wrong. I consider both of these things to resolve in Pijul's favor.
The Pijul model also means that conflicts preserve some crucial state which can be used to resolve the merge. A conflict is modeled as a specific data structure, not as special syntax intruded into the source file. One example of this is that conflicts can in some circumstance be resolved by applying more patches, because the conflict is metadata about the file, it isn't data in the file which screws with subsequent state changes.
What I am excited about Pijul is being able to maintain a personal codebase that can accept changes from multiple upstreams. I’m not looking at commercial teams as much as homelabs or local-first environments.
Isn't it more Pijul vs Git than Git_hub_? There's a massive git community/ecosystem that has nothing to do with Github (e.g. Linux kernel development, at least last I looked).
I've dropped off Github for personal projects since it's trivial to run my own git repo and git version control is built into _everything_ by default, but there are definitely annoyances I've encountered while using git that sound like they would be non-issues in Pijul, so on that level it piques my interest. On the other hand, I would want to be able to do two things before I'd seriously consider switching:
1. Self-host Pijul repos with some web interface similar to e.g. Forgejo/Gitea/Gitlab/etc (i.e. not just source control, but also a bit of project management and CI). Looks like Pijul is developed on something called "The Nest" which looks basically close enough, but the source code for that isn't public yet.
2. Install a plugin in an IDE that would let me leverage it inside the UI (with in-IDE conflict resolution)
Testing Git vs Pijul is hard unless you have other people to work with. I've wanted to use Pijul and other VCS tooling for ages, but it's pointless unless I can try with other contributers. So the hub does matter
Nothing except their own arrogance. See svnhub.com. It was registered by github to block potential competition long before SVN support on github became available.
Github also managed to succeed through being a kind of social network (think "stars").
If you care about Github's dominance being an issue, walk the walk : refuse to do bug reports through it, publicly shame people and companies that use it or advertise it.
If I care about one thing, I should "shame" others who do not care about it? It feels like your comment escalates things up too quickly. Could it be that you wanted to expand your thoughts in between and didn't have the time or just forgot?
Pijul: Version-Control Post-Git [video] - https://news.ycombinator.com/item?id=37094599 - Aug 2023 (163 comments)
Other past threads: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
git is like shaving with a straight shaving razor - alarming until you've developed your set of frequently used commands and ways to stay out of trouble.
Even I have to use git because who uses anything else? Every project that I know that used Mercurial dropped it in the hope of getting more contributions.
We have all rushed like Lemmings into Github - now owned by those nice people at Microsoft - who have used it to automate our jobs with copilot. How ridiculous that Open Source has been embraced into the clutches of the Empire on such a scale! :-) I am joking but only a bit.
Git compatibility is a great way around this problem. I have been enjoying Jujutsu lately.
So long as you require git compatibility, you're kinda stuck with git's view of what history looks like. Which is rather the point.
Adjacent, I heard folks praising Forgejo for its Actions & Microsoft GitHub compatibility, but that means you are still left with the same YAML spaghetti and its other limitations. What would have been nice is something better for CI--something that prompts the project to want to switch to get a better experience. As such, while I agree with the moral reasons to switch to non-proprietary software, the reason for switching is philosophical, not philosophical + technical. I feel being a wrapper around Git or Git compatibility will likely fall in this category rather than being more compelling.
It's pretty widely not used in the games industry because its support for media files is poor, it's pretty difficult to train artists to use it, the integration with game engines is pretty poor, git LFS is a layer of complication on a system that already has UX that's difficult for artists, git LFS hosting is an additional can of worms, there's essentially no file/directory-level permissions for managing contract work (and doing so with submodules+LFS is complicated).
If you’re getting paid then it makes some sense to worry about automation, but if you’re not, automation is good. You can do more. The community can do more. We can take on more ambitious projects.
GUIs will only ever tackle a subset of git’s functionality since if you’re already a power user you’ll be comfortable with the command line.
You definitely need a gui to do partial commits. git add -P is just horrible to use.
And as patches go through different contributors and maintainers they accumulate trailers in the form of signed-off-by and things like that. Even non-trailer (not key-value line) changelogs like: `[<initials>: fixed typo/ fixed off by one]`. And if the change is in the code then the patch content changes (not just the commit message).
The Git project is also pretty patch-based in its development. Even for those who only cares about the maintainer tree: these patches apply to this other in-flight patch series; this diff here can be applied on top of your pending patch series; this patch series is from our ongoing work at Gitlab (company); I’m resending this patch series that X did three months ago but seemed to have abandoned; etc.
My understanding is that a big part of the reason that Git is snapshot based is for reliability and for ease of checkout -- being snapshot based means Git doesn't need to replay commits every time you check things out.
That likely comes with some downsides (cherry-picking does come to mind, yes), but also seems like some serious upsides, one of the biggest one being that simplicity. It's relatively easy for me to reason about what Git is doing under the hood. I like that I'm seeing that Pijul's patch operations are associative, I like at first glance what I'm seeing it say about merges, but it's not making it clear to me what the downsides are.
Is the idea that arbitrary checkouts take longer, but that's generally fine since people don't do them very often? Or am I over-estimating how much complexity/performance costs that building a vcs like this would incur?
Pijul does a better job of recognizing that "A -> B -> C" is the same as "B' -> A' -> C".
There ain’t a whole lot to the first commit of Git. Some hundred lines which consists of manually preparing a commit by sending the current snapshot to the “cache” (nowadays “index”) which compresses it and then building a commit by specifying the parents and a commit message (like git-commit-tree but I don’t know if that was around back then).
Beyond that I don’t know much.
Can someone give me a real world example (person a makes X change, person b makes y change etc. etc.) that would work better in Pijul than Git?
I am a complete believer on a sound underlying model producing better results for users at a high level, but I'm not clear on how it maps through for Pijul. I think that's what they're missing in the sell - the ability to explain to devs "it will make your life easier in the following specific ways".
For example when getting my employer moved from SVN to Git I could talk to people about how much easier it was to create and then merge a temporary branch for a feature in Git. Git understand the topology of the history, knew the merge base and had better merge algos so the only pain you had was when there was an actual conflict - two people editing the same file location. It also could track renames, which were incredibly painful to merge in SVN.
Simplified example:
Persons A and B check out master branch.
Person A adds a.txt, commits and pushes.
Person B adds b.txt, commits and tries to push and...
1) git will not accept the push because it's not on top of current master branch, person B needs to fetch and merge/rebase before pushing again.
2) pijul will accept the change (after a pull, but no rebase) because patches A and B are independent of each other and does not matter which order they are in the history (keyword: commutation).
The value of Pijul will only start to show when you get into big three way merge scenarios. Which git users avoid like the plague because they are so nasty to deal with. Demonstrating this would need a much larger example.
edit: clarification a pull is still needed in case 2, but no rebase or merge because there isn't one for commutative patches
In git, a cherry-pick pulls the change you're interested in off a branch, making a copy in the process. If you later merge or rebase that branch, there are two versions of it in the history, this can have practical consequences, it's not uncommon for this to generate conflicts which wouldn't be there without the cherry-pick.
In pijul, a cherry-pick is just one way to apply a patch. It's the same patch in both branches, so the history doesn't contain two versions of the change, only one. So there is no difference in the result between 'branch, cherry-pick, merge' and 'branch, merge'. Ever.
They are still a pain in Git as well. Rename a class and its usages in C# project, for example, and it randomly breaks based on some arcane heuristics.
As for actual question you posed - partial checkouts. Your artist don't need to checkout code, but can work on it art folder.
- There's an example in the "why Pijul" page of our manual where Git completely reshuffles your lines, and no "custom merge algorithm" could possibly solve it. I would be terrified if I were working on crypto/security code and I knew my VCS was doing that: https://pijul.org/manual/why_pijul.html
- Patch commutation makes all big instances small: no need for submodules, partial/shallow clones, etc. Patch commutation lets you work on a small part of the repo by cloning only the patches you're interested in, and submit patches that mechanically commute with all patches on other parts of the repo.
- Free cherry-picking: no need for strict disciplines, you can just introduce a quick fix on your local work branch, and push just that to production. When you're ready merging the rest, you won't have to solve conflicts again (no need for Git rerere/Jujutsu/…)
- Many uses of branches reduced to "just use patches": many people, especially on fast-moving projects and "early days", don't really know what they're working on, and are dragged onto solving problems they didn't plan initially. Well, Pijul lets you focus on your work, then make patches, and then separate them into branches, thanks to commutativity.
- Separation of contents and operations: this really feels like the CSS3/HTML5 of version control. In Pijul, patches have two "detachable" parts, a part describing what the patch does (as concise as "I introduced 1Tb of data", i.e. just a few bytes), and the contents (not concise: the 1Tb themselves). You don't need the data to apply a patch, so when working on large files, you can record 10 different versions, and your co-workers will only download the parts that are still alive after that. No LFS required!
- Precise modeling of conflicts: conflicts are stored in our model, not "recorded" or "artificially first class". They're literally the core of our model, the initial theoretical motivation. Patches are where you need a good tool the most, and we record them and store your precious resolutions as actual patches, so they don't come back (no "git rerere" needed, and conflict resolutions can be cherry-picked).
Now, we also have less game-changing things like:
- Accurate and super fast "blame" (which we call "credit", and which doesn't require Pijul to look at the entire history like Git does).
- Generic diffs, and therefore merge, i.e. not necessarily line-based. We haven't implemented them, but you could in theory implement AST-based diffs on top of Pijul.
This comment (that probably prompted this submission) gave me some idea at least.
As for the differences, the advantages are listed right there on the front page: commutation, merge correctness, first-class conflicts and partial clones.
Explaining these in more detail in a short example ("a blurb") is not really easy because you'd have to first set up an example three way merge (for example) and then study the behavior of git vs. pijul in detail. I recall seeing a video presentation from the Pijul authors which delved deep into this if you're interested.
But I'll give it a go anyway...
tl;dr: pijul can handle certain merge situations automatically where git requires you to manually resolve them
In practice on actual real world cases, there are lots of differences when you start working with others: even on a small project, you don't have to plan your feature branches anymore, conflicts are solved once and for all, you get free cherry-picking of bugfixes to your production branch, etc.
When your project scales, there are even more differences: commutativity handles large repos for free, patches describe large files much more efficiently than by giving their whole contents (which snapshots do).
That you definitely would have to double check because it might be that it hallucinates.
For example I look at 'sanakirja' project. The current version is 1.4.1 and the previous version was 1.4.0, and the version before that was 1.3.3:
https://crates.io/crates/sanakirja/versions
but if I look at the repository, there is no way to see any of that?
https://nest.pijul.com/pijul/sanakirja
There is "Tags" tab which is empty, and channel selection drop-down that has only "main" channel. So if I want to browse code at version 1.3.3, or see the difference between 1.3.3 and 1.4.0, or even just see what versions there are, how would I do that? To me those seem like very elementary questions, and yet reading through the manual I can find no hints toward this direction.
There is a FAQ entry that seems relevant:
> Is it possible to refer to a specific version?
> Excellent question. Since Pijul operates on patches rather than snapshots, versions are essentially unordered sets of patches. How do we communicate a specific version number to one another? We solve this by abusing elliptic curve cryptography primitives.
But its not clear at all how those "version identifiers" can be used or indeed if they are even implemented at all yet? At least based on the manual, no commands seem to take "version identifier" as argument, nor can I see them anywhere in Nest web UI.
> But its not clear at all how those "version identifiers" can be used or indeed if they are even implemented at all yet? At least based on the manual, no commands seem to take "version identifier" as argument, nor can I see them anywhere in Nest web UI.
`pijul log --state` does that, and various commands (tags, fork) do it as well. Tags are due for a redesign, since they can be made much more efficient with a really cool new design, and make Pijul a perfect hybrid between patches and snapshots.
Is there some repo that is then a good showcase?
https://nest.pijul.com/pijul/pijul:main/QL6K2ZM35B3NI.JIAAA
but the docs do not say anything about that, so it remains a mystery. also its still weird that their own projects do not use those tags, or is it just that the web UI isn't showing them properly?
However, Pijul looks interesting, nice work!
Pijul has a number of stated strengths over Git, and looks like the version history is implemented as a CRDT from my first impression. Some of the statements make me wonder how many conflicts occur in real use. If they are equal to or less than the number it produces, great. If more than what Git produces, that's a barrier to adoption, as merge conflicts are one of the biggest pains when using Git.
For me though what appears one of its biggest strengths (commutative workflow) is also its biggest drawbacks. There are so many teams that are trained in git workflow and are used to it, that getting them to switch to a completely different style of workflow in sufficient numbers will take years.
Git compatibility is a key missing feature. Git had this with Subversion, and I think it's a big reason why Git won over many of the Subversion crowd.
This means that in some cases, Pijul will correctly merge where any of the git merge strategies would create a conflict. It also means that in some other (rarer) cases, Pijul will generate a conflict where git would not: git would guess, in effect, and either get it right or get it wrong. I consider both of these things to resolve in Pijul's favor.
The Pijul model also means that conflicts preserve some crucial state which can be used to resolve the merge. A conflict is modeled as a specific data structure, not as special syntax intruded into the source file. One example of this is that conflicts can in some circumstance be resolved by applying more patches, because the conflict is metadata about the file, it isn't data in the file which screws with subsequent state changes.
I'd love to see it get 1% of the investment Github gets...
I've dropped off Github for personal projects since it's trivial to run my own git repo and git version control is built into _everything_ by default, but there are definitely annoyances I've encountered while using git that sound like they would be non-issues in Pijul, so on that level it piques my interest. On the other hand, I would want to be able to do two things before I'd seriously consider switching:
1. Self-host Pijul repos with some web interface similar to e.g. Forgejo/Gitea/Gitlab/etc (i.e. not just source control, but also a bit of project management and CI). Looks like Pijul is developed on something called "The Nest" which looks basically close enough, but the source code for that isn't public yet.
2. Install a plugin in an IDE that would let me leverage it inside the UI (with in-IDE conflict resolution)
If you care about Github's dominance being an issue, walk the walk : refuse to do bug reports through it, publicly shame people and companies that use it or advertise it.