This is a great example of why I’d really like a “flag: blatantly incorrect”.
On Mercurial, as many others have pointed out, the author didn’t actually read the page they wrote on. Contemporary Mercurial runs great on Python 3, thank you very much, and is well on the way to porting to Rust.
I’m no Fossil fan, but even I know that the error they’re highlighting with Fossil is because the Git repository isn’t valid. [edit: see note below; I’m wrong on the issue on that repo, but the rest of this paragraph is vald.] I hit this type of issue all the time while working on Kiln’s Harmony code. If you’re bored, try setting fsckObjects to true in your .gitconfig. You won’t be able to clone roughly a third of major repos on GitHub. (The ratio improves dramatically for more recent projects until it hits 100% success for stuff that was kicked off in the last couple of years, but anything five or more years old, you’re gonna hit this type of issue.)
Darcs is evicted over its website being HTTP, which has nothing to do with Darcs. Pijul over the author having no clue how to write code in Windows.
The author is trolling. Poorly. And somehow this is highly ranked on the front page. Let’s do better.
Edit: correction the Fossil bit: After two seconds of poking with Fossil and Git fast-export on Windows, the actual issue with their Windows repository is that they’re in a command shell that’s piping UTF-16 and/or sending \r\n. This is also something any Windows dev should recognize and know how to deal with. If you’ve set the default shell encoding to UTF-8 or use a shell like yori that does something sane, you won’t hit this issue, but I’d sure hope that anyone using Windows full-time who refuses to set a UTF-8 default is habitually slamming | Out-File -encoding utf8 after commands like that.
For Pijul it’s even worse, it’s over (1) the author relying on contributors to test and fix on platforms other than Linux and (2) WSL not implementing POSIX correctly, but blaming Pijul’s author is easier than blaming Microsoft.
Also, she knows it, has contributed to Pijul after that post, and has never updated it.
I wouldn’t go as far as saying “the author is trolling”. To me it’s an opinion piece where, sure, the author could have put some more effort, but that’s their particular style and how they chose to write it. To be fair I did not expect it to be this controversial. It does mention some points on what a “better git” would need to do, even if it’s a bit snarky. Particularly the suggestions at the end. At the very least this thread has brought a bunch of good alternatives and points 🤷♀️.
I’m glad the post essentially says “no” after trying most contenders. I hope people make better porcelain for git, but moving to another data model makes little sense to me, and I hope the plumbing remains.
I did kind of raise my eyebrows at the first sentence:
Most software development is not like the Linux kernel’s development; as such, Git is not designed for most software development.
It’s been a long time since git was developed only for the needs of Linux! For example github has a series of detailed blog posts on recent improvements to git: 123456.
The problem with Git is not the “better porcelain”, the current one is fine. The problem is that the fundamental data model doesn’t reflect how people actually work: commits are snapshots, yet all UIs present them as diffs, because that’s how people reason about work. The result of my work on code has never produced an entire new version of a repository, in all cases I remember of I’ve only ever made changes to existing (or empty) repos.
This is the cause of bad merges, git rerere, poorly-handled conflicts etc. which waste millions of man-hours globally every year.
I don’t see any reason to be “glad” that the author of that post didn’t properly evaluate alternatives (Darcs dismissed over HTTP and Pijul over WSL being broken: easier to blame the author than Microsoft).
In my experience, the more pain and suffering one has spent learning Git, the more fiercely one defends it.
Not my experience. I was there at the transition phase, teaching developers git. Some hadn’t used SCM at all,. most knew SVN.
The overall experience was: They could do just as much of their daily work as with SVN or CVS very quickly, and there were a few edge cases. But if you had someone knowledgeable it was SO much easier to fix mistakes or recover lost updates. Also if people put in a little work on top of their “checkout, commit, branch, tag” workflow they were very happy to be able to adapt it to their workflow.
I’m not saying none of the others would do that or that they wouldn’t be better - all I’m saying is that IMHO git doesn’t need fierce defense. It mostly works.
(I tried fossil very briefly and it didn’t click, also it ate our main repo and we had to get the maintainer to help :P and I couldn’t really make sense of darcs. I never had any beef with Mercurial and if it had won over git I would probably be just as happy, although it was a little slow back then… I’ve not used it in a decade I guess)
The underlying data model problem is something that I’ve run across with experienced devs multiple times. It manifests as soon as your VCS has anything other than a single branch with a linear history:
If I create a branch and then add a commit on top, that commit doesn’t have an identity, only the new branch head does. If I cherry pick that commit onto another branch and then try to merge the two, there’s a good chance that they’ll conflict because they’re both changing the same file. This can also happen after merging in anything beyond the non-trivial cases (try maintaining three branches with frequent merges between pairs of them and you’ll hit situations where a commit causes merge conflicts with itself).
Every large project where I’ve used git has workflows designed to work around this flaw in the underlying data model. I believe Pijul is built to prevent this by design (tracking patches, rather than trees, as the things that have identity) but I’ve never tried it.
I don’t understand, is it “not your experience” that:
Snapshots are always shown as diffs, even though they aren’t diffs
Bad merges, git rerere and conflicts happen. A lot.
The author of the original post didn’t evalute things correctly?
In any case, none of these things is contradicted by your explanation that Git came after SVN (I was there too). That said, SVN, CVS, Git, Fossil and Mercurial have the same underlying model: snapshots + 3-way merge. Git and Mercurial are smarter by doing it in a distributed way, but the fundamentals are the same.
Darcs and Pijul do things differently, using actual algorithms instead of hacks. This is never even hinted at in the article.
Snapshots are always shown as diffs, even though they aren’t diffs
Its more meaningful (to me at least) to show what changed between two trees represented as the commit as the primary representation rather than the tree, but
there’s a button to move between the two in most user interfaces github / elsewhere
Bad merges, git rerere and conflicts happen. A lot.
I don’t tend to use workflows that tend to use merges as their primary integration method. Work on a feature, rebase on mainline, run tests, merge clean.
The author of the original post didn’t evalute things correctly?
The author’s use cases are contradicted by the vast majority that use git successfully regardless of the problems cited. I’d say the only points that I do agree with the author on are:
Git is fundamentally a content-addressable filesystem with a VCS user interface written on top of it.
Not the author’s quote, but there’s a missing next step there which is to examine what happens if we actually do that part better. Fossil kinda has the right approach there. As doe things like Beos’ BFS filesystem, or WinFS which both built database like concepts into a filesystem. Some of the larger Git systems build a backend using databases rather than files, so there’s no real problem that is not being worked on there.
approach history as not just a linear sequence of facts but a story
The one thing I’d like git to have is the idea of correcting / annotating history. Let’s say a junior dev makes 3 commits with such messages as ‘commit’, ‘fixed’, ‘actual fix’. Being able to group and reword those commits into a single commit say ‘implemented foobar feature’ sometime after the fact, without breaking everything else would be a godsend. In effect, git history is the first derivative of your code (dCode/dTime), but there’s a missing second derivative.
Snapshots can be trivially converted to diffs and vice-versa, so I don’t see how this would impact merges. Whatever you can store as patches you can store as a sequence of snapshots that differ by the patch you want. Internally git stores snapshots as diffs in pack files anyway. Is there some clever merge algorithm that can’t be ported to git?
What git is missing is ability to preserve “grafts” across network to ensure that rebase and other branch rewrites don’t break old commit references.
I actually thought about the problem a bit (like, for a few years) before writing that comment.
Your comment sounds almost reasonable, but its truth depends heavily on how you define things. As I’m sure you’re aware, isomorphisms between datastructure are only relevant if you define the set of operations you’re interested in.
For a good DVCS, my personal favourite set of operations includes:
In Git terms: merge, rebase and cherry-pick.
In Pijul terms: all three are called the same: “apply a patch”.
Also, I want these operations to work even on conflicts.
If you try to convert a Pijul repo to a Git repo, you will lose information about which patch solved which conflict. You’ll only see snapshots. If you try to cherry pick and merge you’ll get odd conflicts and might even need to use git rerere.
The other direction works better: you can convert a Git repo to a Pijul repo without losing anything meaningful for these operations. If you do it naïvely you might lose information about branches.
Honestly I’m of the opinion that git’s underlying data model is actually pretty solid; it’s just the user interface that’s dogshit. Luckily that’s the easiest part to replace, and it doesn’t have any of the unfortunate network effect problems of changing systems altogether.
I’ve been using magit for a decade and a half; if magit (or any other alternate git frontends) had never existed, I would have dumped git ages ago, but … you don’t have to use the awful parts?
Honestly I’m of the opinion that git’s underlying data model is actually pretty solid; it’s just the user interface that’s dogshit.
For what it’s worth, I do disagree, but not in a way relevant to this article. If we’re going to discuss Git’s data model, I’d love to discuss its inability to meaningfully track rebased/edited commits, the fact that heads are not version tracked in any meaningful capacity (yeah, you’ve got the reflog locally, but that’s it), that the data formats were standardized at once too early and too late (meaning that Git’s still struggling to improve its performance on the one hand, and that tools that work with Git have to constantly handle “invalid” repositories on the other), etc. But I absolutely, unquestionably agree that Git’s UI is the first 90% of the problem with Git—and I even agree that magit fixes a lot of those issues.
I’ve come to the conclusion that there’s something wrong with the data model in the sense that any practical use of Git with a team requires linearization of commit history to keep what’s changing when straight. I think a better data model would be able to keep track of the history branches and rebases. A squash or rebase should include some metadata that lets you get back the state before the rebase. In theory, you could just do a merge, but no one does that at scale because they make it too messy to keep track of what changed when.
I don’t think that’s a data model problem. It’s a human problem. Git can store a branching history just fine. It’s just much easier for people to read a linearized list of changes and operate on diffs on a single axis.
Kind of semantic debate whether the problem is the data model per se or not, but the thing I want Git to do—show me a linear rebased history by default but have the ability to also show me the pre-flattened history and the branch names(!) involved—can’t be done by using Git as it is. In theory you could build what I want using Git as the engine and a new UI layer on top, but it wouldn’t be interoperable with other people’s use of Git.
It already has a distinction between git log, git log --graph and git log --decorate (if you don’t delete branches that you care about seeing). And yeah, you can add other UIs on top.
BTW: I never ever want my branch names immortalized in the history. I saw Mercurial do this, and that was the last time I’ve ever used it. IMHO people confuse having record of changes and ability to roll them back precisely with indiscriminately recording how the sausage has been made. These are close, but not the same.
git merge –no-ff (imo the only correct merge for more than a single commit) does use the branch name, but the message is editable if your branch had a useless name
They’re not supposed to! Squashing and amending are important tools for cleaning up unwanted history. This is a very important ability, because it allows committing often, even before each change is final, and then fixing it up into readable changes rather than “wip”, “wip”, “oops, typo”, “final”, “final 2”.
What I’m saying is, I want Git for Git. I want the ability to get back history that Git gives me for files, for Git itself. Git instead lets you either have one messy history (with a bunch of octopus merges) or one clean history (with rebase/linearization). But I want a clean history that I can see the history of and find out about octopuses (octopi?) behind it.
No. The user interface is one of the best parts of Git, in that it reflects the internals quite transparently. The fundamental storage doesn’t model how people work: Git reasons entirely in terms of commits/snapshots, yet any view of these is 100% of the time presented as diffs.
Git will never allow you to cherry-pick meaningfully, and you’ll always need dirty hacks like rerere to re-solve already-solved conflicts. Not because of porcelain (that would have been solved ten years ago), but because snapshots aren’t the right model for that particular problem.
The author of this is some degree of bombastic or clueless.
the foundations on which Git is built are overkill on the largest scale
Have you ever looked under the hood at kernels and filesystems? O right you are running Windows, you can’t easily look under the hood. Anyhow … the “scale” of overhead in Git is remarkably low for what it accomplishes. Not that it couldn’t be better –I grant there is quite a bit of room for improvement– but if you think blob storage with a hash scheme to address it is the largest scale overkill possible then you haven’t seen the alternatives!
you can totally be better than Git by having monotonically-ish increasing revision numbers
If you want “monotonically-ish increasing revision numbers” you have to go back to centralized version control instead of distributed. I suspect the author of this screed wasn’t around for CVS or the systems that came before it and has lost sight of what gains DVCS in general and Git in specific brought to the scene.
In one paragraph they mention that they mostly work solo. In such case, a centralised VCS could be just enough. But then all generalisations are invalidated and that should be acknowledged. Like “why I would like a simpler git”. To be honest though, I wouldn’t like to go back to SVN or something even for personal throwaway projects.
…and force linear history with no branching, forking, rebasing, or basically any fun in life. If I ate that many rocks for breakfast every day I could just go back to RCS.
What a crappy writeup… the amount of time given to fossil does it no justice. I’ve been using it locally for a few months now and hosting multiple repos and I’ve had such a good experience. So easy to run from a jail on my TrueNAS and even add offsite backups to because all the projects sit in the same directory with a single file each. For open source I think you could easily do some sort of “fossil localdev to public git” flow. The focus on windows/WSL is also annoying but I suppose it allows the whole post to be dismissed for folks who use neither. Hopefully the mention of all the different projects sparks folks’ interest. I think it’s fun to tinker with using different VCS tools.
The focus on windows/WSL is also annoying but I suppose it allows the whole post to be dismissed for folks who use neither.
Windows compatibility is really interesting: it’s important for a lot of users but not something a lot of developers have the computers, interest, or even awareness to match. Anything that wants to seriously compete with git would need to run natively on windows without wsl.
But Fossil does (it’s a single drop-in executable via either winget or scoop), and Git not only runs fine on Windows; it’s the default SCM that Microsoft internally uses these days. This would be like evaluating Subversion on Linux by running TortoiseSVN on WINE.
Git runs on Windows but it’s not “fine” - it’s painfully slow and a little finicky to setup.
Personally it doesn’t bother me enough to run through WSL, but I’ve heard people suggest it.
It’s slow enough that for big operations I’ll occasionally switch over to the shell and manually run git commands instead of using Magit, because Magit will often run multiple git commands to get all of the information it needs, and it just slows down too much.
Context for this response: I did Windows dev professionally from 2005 to 2014, and as a hobbyist since then. Half the professional time was on an SCM that supported both Mercurial and Git on Windows.
Git runs on Windows but it’s not “fine” - it’s painfully slow and a little finicky to setup.
Setup is literally winget git (or scoop git, if you’re weird like me), aaaand you’re done–or at least in the same git config --global hell everyone on Linux is in. Performance has been solid for roughly four years if you’re on an up-to-date Git. It’s not up to Linux standards, because Git relies on certain key aspects of Unix file and directory semantics, but there are even official Microsoft tools to handle that (largely through the Windows equivalent of FUSE).
Running anything through WSL on files will perform atrociously: WSL1 is slower than native, but mostly okay, but WSL2 is running on p9, so you’re doing loopback network requests for any file ops. I do run Git in WSL2, but only when working on Linux software, where it’s running natively on Btrfs. You’re trying to lick a live propeller if you use WSL2 Git on Windows files.
I have zero experience with magit on Windows because Emacs on Windows is, in my opinion, way too painful to deal with. I love Emacs on *nix systems! Keep it! It’s awesome! This is just about Windows. And in that context, things like e.g. Emacs assuming it’s cheap to fork a new process–which it is on Linux, but not on Windows–can make a lot of Emacs stuff slow that doesn’t need to be. That said: if you’re using native Git, and not e.g. Cygwin or WSL1 Git, it should perform well out-of-the-box.
To clarify, most of the finicky setup on Windows was related to SSH keys, because Windows doesn’t support SSH well. Eventually I ended up getting it working with Putty, IIRC.
I have the opposite experience with Emacs on Windows. It more or less “just works” for me, and it’s really the only way I can tolerate using Windows for development. Somethings are slower (basically anything that uses a lot fork/exec, like find-grep), but for the most part it’s the same as on Linux and OSX, but a version or two behind :-/
I suspect we just have different expectations as far as Git performance, though. I’m using the latest version (as of a couple months ago) from https://gitforwindows.org/, have “core.fscache” turned on, and other “tricks” I found via StackOverflow (a lot of people think it’s slow on Windows) to speed things up, and it’s still noticeably slower than on Linux - especially for large commits with big diffs.
As a reminder, this article was about Git versus other SCMs. That said:
To clarify, most of the finicky setup on Windows was related to SSH keys, because Windows doesn’t support SSH well
SSH and ssh-agent are built in since at least Windows 10. It’s directly from Microsoft, requires no third-party dependencies, and integrates directly with the Windows crypt store and Windows Services manager.
I suspect we just have different expectations as far as Git performance, though
Git on Windows does perform meaningfully worse than on Linux. Two reasons are generic (sort of) to Windows, one to Git. On the Windows front: the virus scanner (Windows defender) slows things down by a factor of 4- to 10x, so I would disable it on your source directories; and second, NTFS stores the file list directly in the directory files. This hurts any SCM-style edit operation, but it’s particularly bad with Git, which assumes it’s cheap. That last one is the one that’s partially Git-specific.
In the context of this article, though, Git should be performing on par with the other SCMs for local ops. That’s a separate issue from the (legitimate!) issues Git has on Windows.
Eh, that’s fair; Microsoft’s decision to call over half a decade of Windows updates “Windows 10” leads to a lot of confusion. But in this case, the SSH bits I’m talking about were added in 2018—five years ago. That’s before React Hooks were public, or three Ubuntu LTS versions ago, if you want a fencepost.
That’s definitely a bit older than I thought. If I had to answer when it shipped in mainstream builds without looking it up, I’d have said it was a 20H1 feature. At any rate, I wasn’t calling it new so much as saying that “at least Windows 10” reads as “2015” to me.
I have the opposite experience with Emacs on Windows. It more or less “just works” for me, and it’s really the only way I can tolerate using Windows for development. Somethings are slower (basically anything that uses a lot fork/exec, like find-grep), but for the most part it’s the same as on Linux and OSX, but a version or two behind :-/
Same. Emacs on Windows is good. I use it for most of my C# development. If you want to not be a version or two behind, let me point out these unofficial trunk builds: https://github.com/kiennq/emacs-build/releases
Git runs on Windows but it’s not “fine” - it’s painfully slow and a little finicky to setup.
I’d say that setup is not finicky if you use the official installer — these days it sets up the options you absolutely need. It’s still painfully slow, though, even with the recently-ish-improved file watcher. It’s generally OK using from the command line, but it’s not fast enough to make magit pleasant, and it’s slow to have git status in your PowerShell prompt.
I have a hard time imagining a potential Git replacement actually reaching critical mass and replacing Git, at least in the next 5-10 years. It’s not perfect by a long shot but it seems to be good enough, and the associated costs of replacing it are enormous. At this point I think it’d be like trying to replace Imperial units in the U.S. or convincing the countries that drive on the wrong side of the road to drive on the other side… are there good arguments to do things differently? Yes. Can they overcome inertia, habit, and the costs of switching? No.
I guess the timing of Git simply matched the wider spread introduction of doing VCS at all. But before the popularity of git, there was GForge (and of course Sourceforge, its main user), which was initially CVS-only. For example, Ruby gems were typically developed on Rubyforge, there was gnu.org for GNU projects etc. I think when the Pragmatic Programmer book came out, that was a big influence on people to start using version control.
People really were using version control before Git became popular, and as it became popular, doing VCS became popular as well. Then, Ruby on Rails’ massive hype train also boosted Git (and GitHub) usage. But that might just be my perspective, as I was doing Ruby development at the time (although GitHub being one of the first big commercial softwares written in Rails may have had something to do with its rise to fame).
It doesn’t seem that far fetched to me, but then again I watched Git mostly replace Subversion, Mercurial, CVS, and the rest.
On the other hand, it didn’t take much to convince people Git was better than the other systems because they all had big limitations and weren’t nearly as flexible. Mercurial was closest, but it doesn’t handle things like branching and forking as well as Git (IMO, I guess).
All that said, articles like this are kind of silly. It’s not all or nothing. If the author doesn’t like Git, they don’t have to use it. But everybody else can choose for themselves, too, and nowadays they mostly choose Git.
but then again I watched Git mostly replace Subversion, Mercurial, CVS, and the rest.
Me too! Which is why I don’t see anything supplanting Git anytime soon. People largely unified behind a single solution and it’s reached a point where it’s ubiquitous and just part of the landscape. It’s hard for me to picture something that’s either Git++ as a drop-in replacement with additional goodness (why not just add to Git?), or that’s so good that projects would tolerate the friction of adopting something that’s not part of the standard toolset. Git has a few holdouts, sure, but the friction for startup efforts would be enormous.
Well, I have some bad news. From the download page, under “Requirements”:
Mercurial uses Python (version 2.7). Most ready-to-run Mercurial distributions include Python or use the Python that comes with your operating system.
Actually that’s listed under Development requirements if you take a quick pick at https://www.mercurial-scm.org/downloads you actually see that the installers for Windows bundle Python 3.
Mercurial 6.2 (to be released) and newer only has support for Python 3.6+. Mercurial 5.2 and newer has support for Python 2.7 and Python 3.5 and newer. Mercurial 4.3 and newer require at least Python 2.7. Python must include the following standard library components:
Python 3.5 support is being dropped in Mercurial 6.2. Python 2 support is being dropped in Mercurial 6.2.
So probably it’s just that part being outdated in the page. Mercurial 6.2 was released so that’s outdated too.
EDIT: I just read the post’s date 22 Feb 2021 so the author was right when it was posted. (the title is now updated to reflect this)
“Development Repositories” are on the same heading level as “Requirements”. There’s also no “Development requirements” section. I’d be my reading too to assume py 2.7 is a hard requirement, the year notwithstanding.
This reminds me of the excellent discussion from this thread on my earlier article. Some of the comments were really great and, as the author, I appreciated how candid folks were.
The objective there was actually to apply Alloy to reduce the number of ways of releasing the ghosts and make a friendlier experience. Fulfills the objective of being able to natively import git repos too.
Yes, it was built in a startup in the city I live. It’s probably the best VCS out there if you’re a GUI person or work with big binary files, however, the setup was a bit complicated at the time (it is both distributed and centralized VCS, but to accomplish that, you should run several components at the same time). They’re now focused on videogames use cases and never wanted to replicate the famous free and social aspects of GitHub or GitLab on their hosted services.
LFS (and Mercurial’s equivalent) are painful compared to Perforce, Plastic, or even Subversion: the gap between what’s in the repository, and what the repository means, is a problem unique to that style of “fix”. Narrow and shallow cloning combined get pretty close to matching the quality of Plastic/Perforce/Subversion/etc., but it’s still half-baked when present in the FOSS DVCSes.
Dismissing hg because their download page says “Python 2.7” seems excessive and lazy. Their “Supported Python Versions” page linked from that very download offers a much more detailed explanation of their python support, and it addresses all of our succulent friend’s complaints.
(I understand the point ze is making, but it really amounts to “you can’t be better than git if your webpage sucks” in my opinion. And if you’re writing things off on that basis, it seems like maybe git isn’t that bad.)
i was hoping to see a comparison of the data models and the contrast in their workflows, but this post just describes the author’s inability to install packages. it writes off brilliant software with weak arguments.
Personally I am really interested in Pijul. Cherry-picking in Git and maintaining a downstream patchset is very painful and it sounds like Pijul may be the solution to managing changes (which us how I think if VCS) more natively instead of just versions.
I did. It uses words like “is bad” and “not a fan” and “I like” and not much else of substance. If they’re not a fan, and more power to them I guess, they’re welcome to do something else. They don’t need us to agree to it.
The only one of those phrases in the article is “is bad”, and it immediately leads into talking about other VCS systems. About 9/10ths of the article is about the basic failings of other VCS systems and what they’d need to do to be able to compete with git.
This is a great example of why I’d really like a “flag: blatantly incorrect”.
On Mercurial, as many others have pointed out, the author didn’t actually read the page they wrote on. Contemporary Mercurial runs great on Python 3, thank you very much, and is well on the way to porting to Rust.
I’m no Fossil fan, but even I know that the error they’re highlighting with Fossil is because the Git repository isn’t valid. [edit: see note below; I’m wrong on the issue on that repo, but the rest of this paragraph is vald.] I hit this type of issue all the time while working on Kiln’s Harmony code. If you’re bored, try setting
fsckObjects
totrue
in your.gitconfig
. You won’t be able to clone roughly a third of major repos on GitHub. (The ratio improves dramatically for more recent projects until it hits 100% success for stuff that was kicked off in the last couple of years, but anything five or more years old, you’re gonna hit this type of issue.)Darcs is evicted over its website being HTTP, which has nothing to do with Darcs. Pijul over the author having no clue how to write code in Windows.
The author is trolling. Poorly. And somehow this is highly ranked on the front page. Let’s do better.
Edit: correction the Fossil bit: After two seconds of poking with Fossil and Git
fast-export
on Windows, the actual issue with their Windows repository is that they’re in a command shell that’s piping UTF-16 and/or sending\r\n
. This is also something any Windows dev should recognize and know how to deal with. If you’ve set the default shell encoding to UTF-8 or use a shell like yori that does something sane, you won’t hit this issue, but I’d sure hope that anyone using Windows full-time who refuses to set a UTF-8 default is habitually slamming| Out-File -encoding utf8
after commands like that.For Pijul it’s even worse, it’s over (1) the author relying on contributors to test and fix on platforms other than Linux and (2) WSL not implementing POSIX correctly, but blaming Pijul’s author is easier than blaming Microsoft.
Also, she knows it, has contributed to Pijul after that post, and has never updated it.
I wouldn’t go as far as saying “the author is trolling”. To me it’s an opinion piece where, sure, the author could have put some more effort, but that’s their particular style and how they chose to write it. To be fair I did not expect it to be this controversial. It does mention some points on what a “better git” would need to do, even if it’s a bit snarky. Particularly the suggestions at the end. At the very least this thread has brought a bunch of good alternatives and points 🤷♀️.
I’m glad the post essentially says “no” after trying most contenders. I hope people make better porcelain for git, but moving to another data model makes little sense to me, and I hope the plumbing remains.
I did kind of raise my eyebrows at the first sentence:
It’s been a long time since git was developed only for the needs of Linux! For example github has a series of detailed blog posts on recent improvements to git: 1 2 3 4 5 6.
The problem with Git is not the “better porcelain”, the current one is fine. The problem is that the fundamental data model doesn’t reflect how people actually work: commits are snapshots, yet all UIs present them as diffs, because that’s how people reason about work. The result of my work on code has never produced an entire new version of a repository, in all cases I remember of I’ve only ever made changes to existing (or empty) repos.
This is the cause of bad merges,
git rerere
, poorly-handled conflicts etc. which waste millions of man-hours globally every year.I don’t see any reason to be “glad” that the author of that post didn’t properly evaluate alternatives (Darcs dismissed over HTTP and Pijul over WSL being broken: easier to blame the author than Microsoft).
In my experience, the more pain and suffering one has spent learning Git, the more fiercely one defends it.
Not my experience. I was there at the transition phase, teaching developers git. Some hadn’t used SCM at all,. most knew SVN.
The overall experience was: They could do just as much of their daily work as with SVN or CVS very quickly, and there were a few edge cases. But if you had someone knowledgeable it was SO much easier to fix mistakes or recover lost updates. Also if people put in a little work on top of their “checkout, commit, branch, tag” workflow they were very happy to be able to adapt it to their workflow.
I’m not saying none of the others would do that or that they wouldn’t be better - all I’m saying is that IMHO git doesn’t need fierce defense. It mostly works.
(I tried fossil very briefly and it didn’t click, also it ate our main repo and we had to get the maintainer to help :P and I couldn’t really make sense of darcs. I never had any beef with Mercurial and if it had won over git I would probably be just as happy, although it was a little slow back then… I’ve not used it in a decade I guess)
The underlying data model problem is something that I’ve run across with experienced devs multiple times. It manifests as soon as your VCS has anything other than a single branch with a linear history:
If I create a branch and then add a commit on top, that commit doesn’t have an identity, only the new branch head does. If I cherry pick that commit onto another branch and then try to merge the two, there’s a good chance that they’ll conflict because they’re both changing the same file. This can also happen after merging in anything beyond the non-trivial cases (try maintaining three branches with frequent merges between pairs of them and you’ll hit situations where a commit causes merge conflicts with itself).
Every large project where I’ve used git has workflows designed to work around this flaw in the underlying data model. I believe Pijul is built to prevent this by design (tracking patches, rather than trees, as the things that have identity) but I’ve never tried it.
I don’t understand, is it “not your experience” that:
In any case, none of these things is contradicted by your explanation that Git came after SVN (I was there too). That said, SVN, CVS, Git, Fossil and Mercurial have the same underlying model: snapshots + 3-way merge. Git and Mercurial are smarter by doing it in a distributed way, but the fundamentals are the same.
Darcs and Pijul do things differently, using actual algorithms instead of hacks. This is never even hinted at in the article.
I simply think it matches very well. Yes, we could now spend time arguing if it’s just the same as SVN, but that was not my real point.
Not the OP, but I’ll respond with my experiences:
Its more meaningful (to me at least) to show what changed between two trees represented as the commit as the primary representation rather than the tree, but
I don’t tend to use workflows that tend to use merges as their primary integration method. Work on a feature, rebase on mainline, run tests, merge clean.
The author’s use cases are contradicted by the vast majority that use git successfully regardless of the problems cited. I’d say the only points that I do agree with the author on are:
Not the author’s quote, but there’s a missing next step there which is to examine what happens if we actually do that part better. Fossil kinda has the right approach there. As doe things like Beos’ BFS filesystem, or WinFS which both built database like concepts into a filesystem. Some of the larger Git systems build a backend using databases rather than files, so there’s no real problem that is not being worked on there.
The one thing I’d like git to have is the idea of correcting / annotating history. Let’s say a junior dev makes 3 commits with such messages as ‘commit’, ‘fixed’, ‘actual fix’. Being able to group and reword those commits into a single commit say ‘implemented foobar feature’ sometime after the fact, without breaking everything else would be a godsend. In effect, git history is the first derivative of your code (dCode/dTime), but there’s a missing second derivative.
Snapshots can be trivially converted to diffs and vice-versa, so I don’t see how this would impact merges. Whatever you can store as patches you can store as a sequence of snapshots that differ by the patch you want. Internally git stores snapshots as diffs in pack files anyway. Is there some clever merge algorithm that can’t be ported to git?
What git is missing is ability to preserve “grafts” across network to ensure that rebase and other branch rewrites don’t break old commit references.
I actually thought about the problem a bit (like, for a few years) before writing that comment.
Your comment sounds almost reasonable, but its truth depends heavily on how you define things. As I’m sure you’re aware, isomorphisms between datastructure are only relevant if you define the set of operations you’re interested in.
For a good DVCS, my personal favourite set of operations includes:
If you try to convert a Pijul repo to a Git repo, you will lose information about which patch solved which conflict. You’ll only see snapshots. If you try to cherry pick and merge you’ll get odd conflicts and might even need to use
git rerere
.The other direction works better: you can convert a Git repo to a Pijul repo without losing anything meaningful for these operations. If you do it naïvely you might lose information about branches.
Betteridge’s law of headlines strikes again.
Not really, Betteridge’s Law is better applied to headlines like Will there every be a better VCS than Git?
By assuming the answer to the headline in question is the default “No”, you’re basically assuming Git will never be surpassed.
That makes me sad. :-(
Honestly I’m of the opinion that git’s underlying data model is actually pretty solid; it’s just the user interface that’s dogshit. Luckily that’s the easiest part to replace, and it doesn’t have any of the unfortunate network effect problems of changing systems altogether.
I’ve been using magit for a decade and a half; if magit (or any other alternate git frontends) had never existed, I would have dumped git ages ago, but … you don’t have to use the awful parts?
For what it’s worth, I do disagree, but not in a way relevant to this article. If we’re going to discuss Git’s data model, I’d love to discuss its inability to meaningfully track rebased/edited commits, the fact that heads are not version tracked in any meaningful capacity (yeah, you’ve got the reflog locally, but that’s it), that the data formats were standardized at once too early and too late (meaning that Git’s still struggling to improve its performance on the one hand, and that tools that work with Git have to constantly handle “invalid” repositories on the other), etc. But I absolutely, unquestionably agree that Git’s UI is the first 90% of the problem with Git—and I even agree that magit fixes a lot of those issues.
The lack of ability to explicitly store file moves is also frustrating to me.
Don’t forget that fixing capitalization errors with file names is a huge PITA on Mac.
I’ve come to the conclusion that there’s something wrong with the data model in the sense that any practical use of Git with a team requires linearization of commit history to keep what’s changing when straight. I think a better data model would be able to keep track of the history branches and rebases. A squash or rebase should include some metadata that lets you get back the state before the rebase. In theory, you could just do a merge, but no one does that at scale because they make it too messy to keep track of what changed when.
I don’t think that’s a data model problem. It’s a human problem. Git can store a branching history just fine. It’s just much easier for people to read a linearized list of changes and operate on diffs on a single axis.
Kind of semantic debate whether the problem is the data model per se or not, but the thing I want Git to do—show me a linear rebased history by default but have the ability to also show me the pre-flattened history and the branch names(!) involved—can’t be done by using Git as it is. In theory you could build what I want using Git as the engine and a new UI layer on top, but it wouldn’t be interoperable with other people’s use of Git.
It already has a distinction between
git log
,git log --graph
andgit log --decorate
(if you don’t delete branches that you care about seeing). And yeah, you can add other UIs on top.BTW: I never ever want my branch names immortalized in the history. I saw Mercurial do this, and that was the last time I’ve ever used it. IMHO people confuse having record of changes and ability to roll them back precisely with indiscriminately recording how the sausage has been made. These are close, but not the same.
git merge –no-ff (imo the only correct merge for more than a single commit) does use the branch name, but the message is editable if your branch had a useless name
None of those show squashes/rebases.
They’re not supposed to! Squashing and amending are important tools for cleaning up unwanted history. This is a very important ability, because it allows committing often, even before each change is final, and then fixing it up into readable changes rather than “wip”, “wip”, “oops, typo”, “final”, “final 2”.
What I’m saying is, I want Git for Git. I want the ability to get back history that Git gives me for files, for Git itself. Git instead lets you either have one messy history (with a bunch of octopus merges) or one clean history (with rebase/linearization). But I want a clean history that I can see the history of and find out about octopuses (octopi?) behind it.
No. The user interface is one of the best parts of Git, in that it reflects the internals quite transparently. The fundamental storage doesn’t model how people work: Git reasons entirely in terms of commits/snapshots, yet any view of these is 100% of the time presented as diffs.
Git will never allow you to cherry-pick meaningfully, and you’ll always need dirty hacks like rerere to re-solve already-solved conflicts. Not because of porcelain (that would have been solved ten years ago), but because snapshots aren’t the right model for that particular problem.
How many people do all their filesystem work with CLI tools these days? Why should we do it for a content-addressable filesystem with a builtin VCS?
Never heard anyone complain that file managers abstract mv as “rename” either, why can’t git GUIs do the same in peace?
At least one. But I also prefer cables on my headphones.
Oh thank goodness, There’s two of us. I’m not alone!
The author of this is some degree of bombastic or clueless.
Have you ever looked under the hood at kernels and filesystems? O right you are running Windows, you can’t easily look under the hood. Anyhow … the “scale” of overhead in Git is remarkably low for what it accomplishes. Not that it couldn’t be better –I grant there is quite a bit of room for improvement– but if you think blob storage with a hash scheme to address it is the largest scale overkill possible then you haven’t seen the alternatives!
If you want “monotonically-ish increasing revision numbers” you have to go back to centralized version control instead of distributed. I suspect the author of this screed wasn’t around for CVS or the systems that came before it and has lost sight of what gains DVCS in general and Git in specific brought to the scene.
In one paragraph they mention that they mostly work solo. In such case, a centralised VCS could be just enough. But then all generalisations are invalidated and that should be acknowledged. Like “why I would like a simpler git”. To be honest though, I wouldn’t like to go back to SVN or something even for personal throwaway projects.
You can get monotonic revision numbers in Git by pushing to a centralized Gerrit.
…and force linear history with no branching, forking, rebasing, or basically any fun in life. If I ate that many rocks for breakfast every day I could just go back to RCS.
What a crappy writeup… the amount of time given to fossil does it no justice. I’ve been using it locally for a few months now and hosting multiple repos and I’ve had such a good experience. So easy to run from a jail on my TrueNAS and even add offsite backups to because all the projects sit in the same directory with a single file each. For open source I think you could easily do some sort of “fossil localdev to public git” flow. The focus on windows/WSL is also annoying but I suppose it allows the whole post to be dismissed for folks who use neither. Hopefully the mention of all the different projects sparks folks’ interest. I think it’s fun to tinker with using different VCS tools.
Windows compatibility is really interesting: it’s important for a lot of users but not something a lot of developers have the computers, interest, or even awareness to match. Anything that wants to seriously compete with git would need to run natively on windows without wsl.
But Fossil does (it’s a single drop-in executable via either
winget
orscoop
), and Git not only runs fine on Windows; it’s the default SCM that Microsoft internally uses these days. This would be like evaluating Subversion on Linux by running TortoiseSVN on WINE.Git runs on Windows but it’s not “fine” - it’s painfully slow and a little finicky to setup.
Personally it doesn’t bother me enough to run through WSL, but I’ve heard people suggest it.
It’s slow enough that for big operations I’ll occasionally switch over to the shell and manually run git commands instead of using Magit, because Magit will often run multiple git commands to get all of the information it needs, and it just slows down too much.
Context for this response: I did Windows dev professionally from 2005 to 2014, and as a hobbyist since then. Half the professional time was on an SCM that supported both Mercurial and Git on Windows.
Setup is literally
winget git
(orscoop git
, if you’re weird like me), aaaand you’re done–or at least in the samegit config --global
hell everyone on Linux is in. Performance has been solid for roughly four years if you’re on an up-to-date Git. It’s not up to Linux standards, because Git relies on certain key aspects of Unix file and directory semantics, but there are even official Microsoft tools to handle that (largely through the Windows equivalent of FUSE).Running anything through WSL on files will perform atrociously: WSL1 is slower than native, but mostly okay, but WSL2 is running on p9, so you’re doing loopback network requests for any file ops. I do run Git in WSL2, but only when working on Linux software, where it’s running natively on Btrfs. You’re trying to lick a live propeller if you use WSL2 Git on Windows files.
I have zero experience with magit on Windows because Emacs on Windows is, in my opinion, way too painful to deal with. I love Emacs on *nix systems! Keep it! It’s awesome! This is just about Windows. And in that context, things like e.g. Emacs assuming it’s cheap to fork a new process–which it is on Linux, but not on Windows–can make a lot of Emacs stuff slow that doesn’t need to be. That said: if you’re using native Git, and not e.g. Cygwin or WSL1 Git, it should perform well out-of-the-box.
To clarify, most of the finicky setup on Windows was related to SSH keys, because Windows doesn’t support SSH well. Eventually I ended up getting it working with Putty, IIRC.
I have the opposite experience with Emacs on Windows. It more or less “just works” for me, and it’s really the only way I can tolerate using Windows for development. Somethings are slower (basically anything that uses a lot fork/exec, like find-grep), but for the most part it’s the same as on Linux and OSX, but a version or two behind :-/
I suspect we just have different expectations as far as Git performance, though. I’m using the latest version (as of a couple months ago) from https://gitforwindows.org/, have “core.fscache” turned on, and other “tricks” I found via StackOverflow (a lot of people think it’s slow on Windows) to speed things up, and it’s still noticeably slower than on Linux - especially for large commits with big diffs.
As a reminder, this article was about Git versus other SCMs. That said:
SSH and
ssh-agent
are built in since at least Windows 10. It’s directly from Microsoft, requires no third-party dependencies, and integrates directly with the Windows crypt store and Windows Services manager.Git on Windows does perform meaningfully worse than on Linux. Two reasons are generic (sort of) to Windows, one to Git. On the Windows front: the virus scanner (Windows defender) slows things down by a factor of 4- to 10x, so I would disable it on your source directories; and second, NTFS stores the file list directly in the directory files. This hurts any SCM-style edit operation, but it’s particularly bad with Git, which assumes it’s cheap. That last one is the one that’s partially Git-specific.
In the context of this article, though, Git should be performing on par with the other SCMs for local ops. That’s a separate issue from the (legitimate!) issues Git has on Windows.
That’s a tiny bit misleading. Windows 10 now includes them but it certainly did not include them when it shipped in 2015.
Eh, that’s fair; Microsoft’s decision to call over half a decade of Windows updates “Windows 10” leads to a lot of confusion. But in this case, the SSH bits I’m talking about were added in 2018—five years ago. That’s before React Hooks were public, or three Ubuntu LTS versions ago, if you want a fencepost.
That’s definitely a bit older than I thought. If I had to answer when it shipped in mainstream builds without looking it up, I’d have said it was a 20H1 feature. At any rate, I wasn’t calling it new so much as saying that “at least Windows 10” reads as “2015” to me.
Same. Emacs on Windows is good. I use it for most of my C# development. If you want to not be a version or two behind, let me point out these unofficial trunk builds: https://github.com/kiennq/emacs-build/releases
I’d say that setup is not finicky if you use the official installer — these days it sets up the options you absolutely need. It’s still painfully slow, though, even with the recently-ish-improved file watcher. It’s generally OK using from the command line, but it’s not fast enough to make magit pleasant, and it’s slow to have git status in your PowerShell prompt.
thanks for pointing out the package managers for windows. I saw
brew
is supposed to work as well but have no context other than a cursory search.Her usage of the WSL1 would be curious even in 2021, I just don’t get why one would do that.
TLDR
Makes fossil and Pijul interesting. Makes the fair point that git isn’t the be all and end all, but also currently unsurpassed overall.
Fossil is a ton of fun. Highly recommend playing around with it.
It’s so easy to be sarcastic and bash what took thousands of mostly free hours of work of some of the busiest and competent developers.
The author couldn’t take their time to even install things properly.
Imagine you spend years working on a project to see people telling what you build sucked.
Anyone who has ever built anything doesn’t have to imagine :)
I have a hard time imagining a potential Git replacement actually reaching critical mass and replacing Git, at least in the next 5-10 years. It’s not perfect by a long shot but it seems to be good enough, and the associated costs of replacing it are enormous. At this point I think it’d be like trying to replace Imperial units in the U.S. or convincing the countries that drive on the wrong side of the road to drive on the other side… are there good arguments to do things differently? Yes. Can they overcome inertia, habit, and the costs of switching? No.
I agree, the reason git got so popular so fast is because any vcs is going to be miles and miles better than no vcs.
But git didn’t replace no VCS. It replaced cvs and svn mostly, and then displaced mercurial.
I disagree. While git did replace those tools for some people, git (and GitHub) mostly replaced a complete lack of version control.
I guess the timing of Git simply matched the wider spread introduction of doing VCS at all. But before the popularity of git, there was GForge (and of course Sourceforge, its main user), which was initially CVS-only. For example, Ruby gems were typically developed on Rubyforge, there was gnu.org for GNU projects etc. I think when the Pragmatic Programmer book came out, that was a big influence on people to start using version control.
People really were using version control before Git became popular, and as it became popular, doing VCS became popular as well. Then, Ruby on Rails’ massive hype train also boosted Git (and GitHub) usage. But that might just be my perspective, as I was doing Ruby development at the time (although GitHub being one of the first big commercial softwares written in Rails may have had something to do with its rise to fame).
Yeah. It definitely popularized the idea of version control in a way that I hadn’t observed before then.
It doesn’t seem that far fetched to me, but then again I watched Git mostly replace Subversion, Mercurial, CVS, and the rest.
On the other hand, it didn’t take much to convince people Git was better than the other systems because they all had big limitations and weren’t nearly as flexible. Mercurial was closest, but it doesn’t handle things like branching and forking as well as Git (IMO, I guess).
All that said, articles like this are kind of silly. It’s not all or nothing. If the author doesn’t like Git, they don’t have to use it. But everybody else can choose for themselves, too, and nowadays they mostly choose Git.
but then again I watched Git mostly replace Subversion, Mercurial, CVS, and the rest.
Me too! Which is why I don’t see anything supplanting Git anytime soon. People largely unified behind a single solution and it’s reached a point where it’s ubiquitous and just part of the landscape. It’s hard for me to picture something that’s either Git++ as a drop-in replacement with additional goodness (why not just add to Git?), or that’s so good that projects would tolerate the friction of adopting something that’s not part of the standard toolset. Git has a few holdouts, sure, but the friction for startup efforts would be enormous.
Mmm the author says
Actually that’s listed under Development requirements if you take a quick pick at https://www.mercurial-scm.org/downloads you actually see that the installers for Windows bundle Python 3.
Inside https://www.mercurial-scm.org/wiki/SupportedPythonVersions you can read
So probably it’s just that part being outdated in the page. Mercurial 6.2 was released so that’s outdated too.
EDIT: I just read the post’s date
22 Feb 2021
so the author was right when it was posted. (the title is now updated to reflect this)Edit2: Removed pronoun to avoid any trouble
Use “She” at least, please.
“Development Repositories” are on the same heading level as “Requirements”. There’s also no “Development requirements” section. I’d be my reading too to assume py 2.7 is a hard requirement, the year notwithstanding.
If you’re going to throw rocks about pronouns, why not go the whole 9 and use the pronouns boringcactus prefers?
It’s poorly worded on the download page, but if you click through to “Supported Python Versions” it’s plenty clear that 2.7 is a minimum version for the stable release. That was true even in mid-2020, when it was still clear that hg supported new python releases.
Thanks for the heads up I didn’t check boring cactus’s profile before posting.
This reminds me of the excellent discussion from this thread on my earlier article. Some of the comments were really great and, as the author, I appreciated how candid folks were.
I hope the author will check out Gitless: https://gitless.com/
The objective there was actually to apply Alloy to reduce the number of ways of releasing the ghosts and make a friendlier experience. Fulfills the objective of being able to natively import git repos too.
May I ask what the “Alloy” here refers to?
http://alloytools.org/
Alloy is a joy to use. The papers at the end of the page omit the Alloy model though.
Has anyone here tried Plastic SCM?
Yes, it was built in a startup in the city I live. It’s probably the best VCS out there if you’re a GUI person or work with big binary files, however, the setup was a bit complicated at the time (it is both distributed and centralized VCS, but to accomplish that, you should run several components at the same time). They’re now focused on videogames use cases and never wanted to replicate the famous free and social aspects of GitHub or GitLab on their hosted services.
Perforce has also been relegated to the gamedev niche too. Surprised it’s big enough for multiple players, and that LFS hasn’t eaten it yet.
LFS (and Mercurial’s equivalent) are painful compared to Perforce, Plastic, or even Subversion: the gap between what’s in the repository, and what the repository means, is a problem unique to that style of “fix”. Narrow and shallow cloning combined get pretty close to matching the quality of Plastic/Perforce/Subversion/etc., but it’s still half-baked when present in the FOSS DVCSes.
Dismissing hg because their download page says “Python 2.7” seems excessive and lazy. Their “Supported Python Versions” page linked from that very download offers a much more detailed explanation of their python support, and it addresses all of our succulent friend’s complaints.
(I understand the point ze is making, but it really amounts to “you can’t be better than git if your webpage sucks” in my opinion. And if you’re writing things off on that basis, it seems like maybe git isn’t that bad.)
Yeah, honestly dismissing mercurial because they can’t even keep basic info on their web site up to date is understandable if you ask me.
i was hoping to see a comparison of the data models and the contrast in their workflows, but this post just describes the author’s inability to install packages. it writes off brilliant software with weak arguments.
Personally I am really interested in Pijul. Cherry-picking in Git and maintaining a downstream patchset is very painful and it sounds like Pijul may be the solution to managing changes (which us how I think if VCS) more natively instead of just versions.
Sure, go for it. What does this have to do with us?
Did you read the article?
Yes, in in the author doesn’t like git for their solo projects.
I did. It uses words like “is bad” and “not a fan” and “I like” and not much else of substance. If they’re not a fan, and more power to them I guess, they’re welcome to do something else. They don’t need us to agree to it.
The only one of those phrases in the article is “is bad”, and it immediately leads into talking about other VCS systems. About 9/10ths of the article is about the basic failings of other VCS systems and what they’d need to do to be able to compete with git.