Hacker News new | ask | show | jobs
by gbersac 1606 days ago
Seems like an interesting project. It's probably impossible to fight against git nowday though. The first mover advantage of git is just too hard to overcome despite all the flaws of git.
11 comments

Git didn't really have first mover advantage. Pijul is essentially a successor to Darcs, and Darcs was around before Git.

The DVCS space was quite diverse for a number of years. I remember the main players being Git, Mercurial, and Bazaar; whose advantages were speed, usability and precise tracking, respectively. Bazaar became pretty much obsolete once git became (slightly) better at tracking history across renames/moves.

Huge projects, like the Linux kernel, Xorg, etc. relied on Git's speed. Since those were also high-profile, and widely used, their adoption of git lead to it becoming the de facto standard. Code hosting sites like Gitorious further cemented git's position, and eventually GitHub came along and made it truly explode.

Git's evolution was interesting to observe at the time.

Back in around 2005, the company I worked for was using Subversion, but then I demoed Darcs to my colleagues (which I had been using at my previous company), and everyone immediately loved it, so we quickly migrated over.

Around 2006, we hired a new developer who was what you might call an early adopter. He wanted to use Nginx back when all the documentation was in Russian — and he also wanted us to use Git. But the benefits of Git were not obvious at the time to someone using Darcs. In fact, Git was positively stone-age at the time — terrible CLI UI, inscrutable commands, steep learning curve for no obvious benefit. And so we resisted the change for several years.

But it was apparent even back then that the writing was on the wall. After all, it came from Linus Torvalds. People were adopting Git en masse, and not much was happening with Darcs. And then, in 2008, GitHub came along, and that was that.

Darcs was amazing to use [1], but it quickly joined the graveyard of technically-superior-at-the-time projects that were too good to succeed: The Amiga, Plan 9, Borland Delphi.

Darcs was ahead of its time in its approach to change management, and I think that we'll eventually have get something like it again. It's probably not going to be sufficient to merely make a better mousetrap, so Pijul isn't it (with all due respect to the technology, which looks nice).

Whatever replaces Git will have some kind of synergy that just means everyone will want to move, similar to what Slack did with chat. Then again, we still use email nearly 50 years later, so it might take a while.

[1] But not perfect. Ultimately its dreaded "exponential-time conflict" bug contributed a lot to its lack of success, I think. It was trivial to get your repository into a state which messed it up permanently. And the bug had no real fix until years later.

Displacing git is certainly impossible in the short term, but that is not the only conceivable goal. Building a sustainable community does not require git levels of success. A few strategic adoptions can go a long way, as shown by Ocaml, Nix, and other similar projects who have small but passionate and vibrant communities. The key there is a core group of users who prioritize a certain set of values over the advantages (ecosystem size, polish, job opportunities perhaps) of technologies with a larger userbase.

There are also ways to displace git without immediately replacing it. Many projects adopted git only after using git-svn for an extended period, giving teams more time to develop git skills without completely disrupting existing workflows. It looks like a pijul-git bridge is planned, which could facilitate gradual adoption. Beyond patch ergonomics, there are many other areas where a concerted effort to provide a better solution than git could yield a highly attractive tool. One that comes to mind immediately is management of multi-repository codebases and dependencies; Pijul (or one of the other git competitors) could provide a better and more cohesive way to manage multi-repository code changes than is possible with git sub[tree,module,...], which would be an adoption magnet. Zig appears to be pursuing such a mixed adoption strategy: they are providing both a new language and a set of tools which support C and C++ and solve several huge pain points -- such as cross-compilaton -- without requiring direct Zig adoption. (the tools have the benefit that they make Zig projects with C or C++ dependencies much easier to bootstrap, which should also allow faster ecosystem growth).

It's not that impossible.

I know to craft a commit in git by hand, but fuck git submodules with a 10 foot pole.

If you ever used git-submodules or a extremely large mono-repo? Pijul can solve it[1].

Which is incidentally what many game companies need.

[1] not by including extra repositories, but excluding extra repositories.

Out of curiosity, why the hate for git submodules? They've worked really well for me over the years. They solve the problem of "pin a specific version of some external 3rd-party repo" really nicely.

The only complaint I have is that the git-submodule CLI has unintuitive syntax. But this is Git after all, so it's par for the course. :v

Because they merely make really hard things hard and simple things painful. They solve a problem (albeit one that can be better solved by a decent package manager like Cargo/NPM).

And in return, basic operations like merge/rebase start breaking in unintuitive ways.

E.g., I work on repo ss14 that has submodules RobustToolbox, but never modify them in my PR.

I rebase my changes. I have changes in RobustToolbox that are only visible in Git Bash. Other Git clients show no changes... Ofc `git submodules update --recursive` might help or something, but it made a simple operation more complicated.

And that's if I didn't change the submodule. If I did, merging/rebasing becomes its own, separate nightmare.

> They solve the problem of "pin a specific version of some external 3rd-party repo" really

With Cargo/NPM you can pin your dependencies to some version you control like a fork or a local directory, making submodules non-necessary.

And unlike submodules, they don't require you to modify your workflow to sprinkle `git submodule update` everywhere.

Agreed that Git submodules aren't a good tool for the problem of "I want to work in multiple repos at the same time".

It's designed for things like "my project needs to check out pinned versions of these 4 external repos", ideally where the pinned version doesn't move all that often.

Git-submodule is best used as a replacement for the "shell script that clones a bunch of dependencies" pattern, not as a multi-repo workflow coordination tool. And in that context, it works very well.

Imagine you had a CLI tool that tool that consumes some text-file list of repos, commits, and paths. Every repo in the list gets cloned to the path you asked, and each repo's requested hash is checked out. The text-file is controlled in your main Git repo.

That's essentially all that Git-submodule is, except that it's built into Git instead of having to roll your own or introduce another tool dependency. There's also some light integration to handle recursive clones and reporting if the submodule state is dirty.

> It's designed for things like "my project needs to check out pinned versions of these 4 external repos",

But I can already do that with Cargo. And it's million times more intuitive.

Cargo is a great tool if you're writing Rust. Go-get is a great tool if you're writing Go. Npm is a great tool if you're writing Javascript. C/C++ options are all nonstandard and maybe bad.

Git submodules is a "none of the above" tool that handles generic situations where you have one top-level repo that depends on pinned versions of a few other repos.

But you can't do it with C!
> And in return, basic operations like merge/rebase start breaking in unintuitive ways.

I just haven't had the same experience at all. Could we work through a specific example?

> I rebase my changes. I have changes in RobustToolbox that are only visible in Git Bash. Other Git clients show no changes.

That's because git-submodule doesn't really interconnect across repos (not much anyways). A submodule is a completely separate repo, with its own stage, commit history, etc. It doesn't even know that it's a being used as a submodule.

Committing/merging/rebasing in your submodule doesn't change the parent. And committing/merging/rebasing in your parent doesn't change the submodule (aside from maybe what commit is checked out).

> That's because git-submodule doesn't really interconnect across repos (not much anyways). A submodule is a completely separate repo

Yeah. I know. Submodules is the file that has link to external repo, and hash to submodule current Head/current version.

----

I think you misunderstood my example.

Ss14 has RobustToolbox submodule.

I changed something unrelated in ss14 on branch fix. But master updates submodules.

I rebase fix on master.

Git bash notes Robust has changed. Nothing else does.

Why? How?

This is just some awful implementation details leaking the flimsy Git submodules abstraction.

> They solve the problem of "pin a specific version of some external 3rd-party repo" really nicely.

My understanding is that they sound to many users like you could do more with them, such as making your repository modular, where in fact if you do that, you run into all sorts of problems.

Yeah I feel the same way. They work quite well but the interface is as typically terrible as you would expect from Git.
Try to move one to a new path!
This "just works" as long as you use `git mv` to do it. Agreed that it's a pile of yuck to try and do it manually though.
Not really, at least right here git mv does not fix structure of `.git/modules` and the submodules break. Just tried it again.

EDIT: apparently git on mac is just too old. Time to brew it. https://stackoverflow.com/questions/4604486/how-do-i-move-an...

Indeed, the first-mover advantage of Go and git shall never be overcome.

Signed, -That Guy Who Used to Check Java out of SVN

It was probably impossible to fight against CVS, and definitely against SVN.

Those systems had undeniable pain points, and so does Git.

Git had git-svn. I used it for a while to interface with a project that was still on subversion. So, I was able to gradually get my team off subversion. Subversion in turn had an easy migration from CVS and of course CVS was a bit painful to use so lots of people ended up migrating. I did such a migration once. It took a while to run but we got it done and kept our version history. We did not look back after that.

There probably is already some work on this but the path to success for pijul would be removing as many obstacles as possible between git and pijul and alternative systems such as mercurial. Make migrations easy. Make interfacing with git remotes easy for pijul remotes or interfacing with pijul users easy for git users.

Git is well entrenched of course with web UIs, IDE integrations, CI/CD support, etc. So there's more to replacing it than just writing a bunch of cli tools.

Neither of those had something like GitHub behind them.
Sourceforge was pretty big at the time. And they lacked git support for quite some time. Github basically burried them by the time they figured out they had a problem. Of course it still exists but it's not a very obvious place for people to park their code at this point.
So? Source Forge is long abandoned, nothing says Github will be super popular forever.
What pijul needs to truly succeed is an halo project. Git got where it is now only because it was developed for linux kernel. Not only is it a major pr boost, but it also gets all sorts of kinks ironed out pretty quickly, and that the tool fits into different peoples workflows; for linux that means that git format-patch and am were pretty much day1 features so that it works with lkml flow seamlessly.

rustc could be one strong candidate as such halo project, but it is probably pretty difficult to convince them to switch, especially as it means not only switching away from git, but also github which they use heavily.

Which conveniently brings to last point that to get any major project to switch to pijul, the transition story needs to be really solid and not disruptive to the day-to-day development. For git it meant not only that it needed to work well with lkml, but git also had really solid svn and cvs (and others!) clients pretty early on. It allowed people to use both git and the legacy vcs in parallel during transition. Beyond that, individuals could use git to work with svn (and other vcs) repos that had no plans to transition anywhere, and still reap some of gits benefits.

For pijul I think it means that it is necessary to be able to work with git repos seamlessly similarly that git-svn allowed git users to work with svn repos.

I am not saying git is flawless but most complaints seem to be about the "porcelain" and not its inherent design. I think Git tremendously outgrow the original audience so a larger proportion of people complain.

Complaining about the porcelain is like complaining about vim's complexity: It takes some time to master but ultimately it is rewarding.

Context: I'm the main author of Pijul, and also a big fan of Git.

This sounds like a potential strawman argument to me, so let's be clear about the complaints you've heard, and my complaints against Git (which, again, I love and admire as the most elegant design I've ever seen for a tool like that).

Mine are not at all in the porcelain, but in the plumbing. My specific complaints are:

- Merges in Git don't have enough information to do the job, and the optimisation problem it tries to solve is underspecified, regardless of which merge algorithm it uses (3-way merge or other): sometimes, there are multiple solutions, and Git ends up choosing a random one. This breaks a fundamental expectation on merges called associativity.

- Solving conflicts doesn't really solve them, it just records a version without the conflict. This can waste engineering time in two ways: either because you need to think deeply about the tool when solving the conflict (and use `git rerere`), or you need to follow a strict workflow, making your work methodology serve the tool rather than the opposite.

- Similarly, rebasing is operational transform. It works most of the time, but not always, and is quite clunky and hackish. Pijul fixes that by using a datastructure that happens to be a CRDT for that part.

In my opinion, all the porcelain issues and the proliferation of unintelligible commands comes from these basic shortcomings in the plumbing.

I don't think GP was trying to make a strawman, for me DCVS is a solved problem thanks to git, and all arguments I ever heard were basically people not wanting to put any effort into it and then pretending this is because 'git is too hard'.

These are pretty advanced issues which are worth solving, so I find these to be beautiful motivation. But I suspect most people are not aware some projects are trying to fix these issues. It's a bit as if you are trying to solve some of Haskell flaw while most people are still stuck doing javascript...

The homepage is giving this motivation but it was not clear from the linked page, which is the point where the discussion in this thread is starting from. Congrats on the milestone and good luck!

> I don't think GP was trying to make a strawman

Potential doesn't mean intentional! Sometimes just a lack of precision causes one to argue against a point that was never made (such as "porcelain is the problem").

IME/IMO, one of the big piles of crap in Git’s porcelain is that gitrevisions(7) is absolutely terrible (and, of course that git diff then proceeds to do something which looks the same but behaves completely differently).

Does pijul have something better for navigating and working with sets of changes? For reference, though I didn’t get to use them that much mercurial’s revsets were a pleasure, mixing readability, expressivity, and flexibility (modularity).

> Complaining about the porcelain is like complaining about vim's complexity: It takes some time to master but ultimately it is rewarding.

It really really is not. All it is is a hurdle you get used to in your way towards getting work done.

Git’s porcelain is at best a beating whose reward is more beatings. I could count the numbers of times git’s porcelain has delighted me on two hands even if both had been cut off and burned to ashes.

Learning to master something that is complicated for no reason is not rewarding, it is a massive waste of time and effort, and only feels like an ongoing drain.
> I am not saying git is flawless but most complaints seem to be about the "porcelain" and not its inherent design.

This my line of thinking as well.

Git has a great low-level API that's very powerful and flexible, but the porcelain and the way that we use the remotes (the Hub's and Lab's) could be a lot better. The current way is neither intuitive nor shaped after how most developers want to work (it's hard for beginners to get started, collaborate, and share ideas, etc).

Depends. It all comes down to the ratio between switching benefit and switching cost, with the added requirement that Pijul must fix a significant pain point people have with git that is visible to decision makers.

Possible pain point candidates: Monorepo speed, submodules, large files. Don't know if Pijul solves any of that.

I saw a project a while ago that was a non-Git version control system that used the Git disk format. I thought that was a pretty great idea. Totally compatible with all of the existing Git stuff, and the Git disk format is pretty good, but you can avoid all the UX mistakes Git made.
Perhaps it was OpenBSD's http://gameoftrees.org/ (git -> got)?
I'd like to think it was my project (https://github.com/martinvonz/jj), but other possibilities include Gitless (https://gitless.com/) or Bazaar (https://bazaar.canonical.com/).
It was your project! I still haven't tried it yet I'm afraid but it looks very well designed.
git does not have first mover advantage. The reason that the current VCS darling is difficult to topple is the high cost of migration as made apparent by how many companies have yet to migrate to git from e.g., Perforce and SVN.
> as made apparent by how many companies have yet to migrate to git from e.g., Perforce and SVN.

So like, hardly any? Almost all companies use Git these days. As I understand it an exception is game companies because Perforce is much better at handling large binary assets (Git LFS is a pretty ugly hack).

Spend some time in hardware manufacturing shops that don't focus on software. SVN is "easy" and has been in use for decades at this point. The SVN mindset is entrenched.

Migrating requires someone know how to handle the command line, buy in from management, and so on...

It takes a lot to get a behemoth (even a small one) moving in a new direction.

I actually do work in a hardware manufacturing company at the moment. We use git. But anyway, hardware manufacturers are a tiny proportion of all companies that write software.

Obviously it's hard to get good numbers but if you look at job adverts on https://www.itjobswatch.co.uk/ they say 778 ads for Subversion and 9579 for git.

I have visited various embedded development shops and have only personally witnessed one using git exclusively. P4, clearcase, and svn are all quite common still.
If you think “hardly any” companies use other VCS’s then I’d say you don’t get out much.

Many enterprises are either still stuck or only just now planning migration to git. They come from Perforce, TFVC, SVN, and god knows what. Big game studios are using perforce (places like Ubisoft), although my info is dated. Google does not use Git for its products either - it uses Piper.

Heck, many high-profile open-source projects held out for a long time with things like FreeBSD only recently migrating from SVN, and other BSDs even sticking to CVS.

Remember that the software development industry is extremely large, much bigger than what you read about on HN.

Would it be possible to add the "this" as a backend to git?
That was obviously the first idea, but it isn't really possible. Git is meant to prevent commutation of patches, while Pijul is design to maximise it.

Two-way conversion is still a goal, though.

Thanks! Also congrats on 1.0!

Is there a FAQ that explains this? I sort of have an intuition for what does that ("prevent commutation of patches") mean, but I don't know how complete (or useful) it is :)

(I guess it has something to do with commit hashes depending on the whole chain of commits, so even if the diff between two commits is empty if they are not the same hash, they are not the same ... thing. But I don't really understand the practical implications of this. To me it seems like there's none. If two branches have the same content I'll treat them as equal. (And with some simple heuristics - like rebase is better, reverts are ugly - I'll pick the nicer one to keep. I don't really care how they ended up equal.

What am I missing?)

Practical implications: merges are 100% predictable and deterministic, this isn't always the case in Git, sometimes lines are shuffled around (look for "associativity" in the manual).

Also, you can actually cherry-pick.

And rebases are not a hack.