I haven’t touched mercurial in like 15 years, and from what I remember its UX was superior to what Git provides today. It had an extension system which I don’t remember the full capabilities of so I don’t know if Git has even now matched up to that.
Mercurial is more monolithic, and is based on python, writing an extension means writing a bit of python and telling Mercurial to integrate it.
Git is more like a loosely connected collection of commands working on the filesystem. It means that extending git is just creating an executable with a particular name in a particular directory. The executable can in turn call other commands, in particular the low level "plumbing", or even work directly with the files in .git.
They way they are similar is that they follow the same model: a decentralized system based on a DAG. And speaking of a "skeleton team", git was famously Linus Torvalds 2-week side project, and even though so much development has happened, providing tooling, convenience, performance, portability, etc... at its core, it never changed.
Git is far worse simply because of "staging". "Staging" may be necessary (I do not concede this) in big projects, but in small projects it's an absolute disaster to the mental model. Most people on small projects just want "checkpoint the current code in my directory and put a comment on it".
In addition, Git's UX is hot garbage. I would constantly be doing rsync on git repos before any operation that is slightly weird knowing that I may put the repo in some state that I cannot easily unwind. I never did that for Subversion. I never did that for Mercurial. I don't do that for Jujutsu. Those are all sane UX.
Side note: Thankfully AI is REALLY good at telling you how to un-wedge your git repo. That should tell you everything you need to know about Git UX and why you should avoid Git.
I stopped using it the first time I committed something I didn’t want to, over a decade ago, haven’t used it again since so I forget the exact invocation, but I think it was just “-a” or something.
Before it bit me though yeah, that did seem like a default I’d have preferred. Not any more.
`git add -p` FTW
Interesting, that's definitely not how I use git. My current code is rarely in a shape that can be fully committed. It often contains additional stuff I did on the way (small bug fixes, TODO comments, debug printf statements, etc.) that I don't want in the commit. Very rarely do I type `git add .` Am I the exception?
Supposedly, Meta has the data to support the claim that you (and I) are the outliers here. Staging is confusing to users, especially new ones, which is why jujitsu explicitly doesn't have staging.
My own setup differs in slight ways from what those scripts expect, and even where they match I like to do my own customizations. I don't want to commit those changes, and staging makes it easy to not do that MOST of the time. The rest of the time, it's a `git stash` dance, which I sometimes screw up and lose the customizations.
I've tried to manage the configurations a different way, such as by having a private branch with my own settings checked in, but that doesn't usually work out. I'm aware that the REAL problem is that my coworkers have checked in those settings to begin with, but I would counter-argue that the REAL REAL problem is that those tools don't have a good way to combine "settings that I override or that only I care about" and "settings that have project-wide defaults but are safe for me to override." (Visual Studio gets it close to right with its .xyzproj and .xyzproj.user files, but VS Code's single .vscode/ folder breaks down in shared repos.)
https://git-scm.com/docs/git-update-index#Documentation/git-...
(If you're not interested, feel free to skip the rest of this).
I have each in process workstream in a commit that is merged at the top level, then I have a new wip commit off of that where stuff I'm typing right now sits.
It's easy to split/squash/absorb parts of that commit into the right destination, but also to introduce parents of the megamerge that will never get merged.
(This is a better/longer writeup of this concept)
https://isaaccorbrey.com/notes/jujutsu-megamerges-for-fun-an...
Oh, and I use git add ---patch almost exclusively. It's rare that I just do a "git add". I'm building up my stage, I'm checking it, I'm fixing it (if I accidentally stage something which doesn't belong), then I commit.
Having done it like this for a great many years I'm benefitting from it all the time. I can look at all my hobby projects (looking at the commits), and I'm back in where I left off, and I see excactly what I was doing back then (which, obviously, I wouldn't be able to rembember otherwise).
CVS though.. that was harder to do right. So a lot of stuff became just snapshots. You had to plan much more carefully. And then there was SCCS before that.. and before that again, well. Manual "keep two versions" svc.
So yes, your usecase does not make sense to me.
There was another comment that said similar thing...
https://news.ycombinator.com/item?id=48175289
>So you're just constantly committing untested versions of you work?
But it is "dead" for some reason...
2. Why should comments or printf statements affect the build? When it compiles with them, why shouldn't it compile without them?
3. the commits might be temporary and get squashed anyway
2. Because people make mistakes. You might think you are only excluding a comment, but might be excluding something that is required by mistake.
1. git stash
2. build + test
3. commit
4. git stash pop
> Some projects might not have a CI at all.
Well, then you have bigger problems. Without CI, how would you even know if your projects compiles on other platforms?
This way I remove the overhead of doing a staging before every damn commit and still retain the ability to pull in debugging changes whenever I want them.
>Without CI, how would you even know if your projects compiles on other platforms?
Not everything need to be cross platform! And not everything need CI..
As I said, I like to work on several things in parallel and I don't want to switch branches back and forth. That's just my workflow for my own projects and apparently I'm not alone.
But there are also other extensions that can achieve similar behavior.
In fact, often partial commits are necessary for builds.
As an example (and to be fair, this was a transitional project), I once worked on a project where the local dev directly acquired packages from different parts of the application, but the actual CI was broken up into different pipelines which required some parts to be built first, its outputs packaged and added to the registry, and downstream parts to be built after.
Committing everything at once would literally break the CI.
For example, if you are working on something, but it requires adding an API to some module, then the first commit 1 is to add the new API (+ tests), and the second commit is the new code that uses that API.
Unfortunately many developers I have worked with would just combine these (and more) into a single commit (because they are part of the same work task). However this makes review, bisect, blame and revert harder (if you need to revert commit 2, you don't want to also revert the API you added if that was tested and bug-free).
It’s a pointless addition. Making commits easier to modify and undo would eliminate any need for git add.
But git can’t really do that since it’s so fundamentally based on the idea that commits are immutable. Any modifications r does allow are workarounds, and dangerous ones at that.
On the off chance that you haven't already had this suggested to you on HN, I would suggest taking a look at JJ.
I use it in all my Git-underneath repos with `jj git init --colocate` (You can run that in a git repo and it will hybridize, or in a new folder and it will init and hybridize).
It doesn't have the staging concept, treating the working copy as just another commit (@), and to boot it snapshots the state of the tree into @ when you run any jj command, so you can use `jj op log` to see every intermediate state of your working copy at any time.
Commit is just `jj commit` with no staging mechanics, or `jj split` to 'split the working copy commits' (commit some, keep the rest in @).
not to mention the early "just clone it into a new dir" answer before lightweight branching ...
Try doing the same in any other source control system…
Git is extremely predictable, but only after you thoroughly understand it. Until then, it seems to surprise you often and every time it happens you think you've lost data. Many times I've had collaborators who said "git ate my files" and I can usually get their files back in a few minutes. This makes them hate git because they cannot use it without having me on call, and they cannot be bothered to learn git thoroughly themselves because it's too damn hard.
Honestly this is one area I really like AI - so I can focus on the things I really need to focus on and not spend a bunch of time becoming an expert in things I don't want to be an expert in.
I guess it'd take one day of your life to read it, but I think it pays back a lot.
Using rsync on git is like hammering a nail with a hammer, but then use a 10 pound stone to hammer the hammer.
A good way of thinking about it is that every commit is itself version-controlled, allowing unlimited edits. This even allows two people in an evolve-enabled repo to make changes to history at the same time, and Mercurial will resolve any conflicts. It makes it trivial to commit (and even share) a "WIP" commit which you can later amend/split/whatever. It's different from git where you basically can't edit history after pushing (in Mercurial this only becomes true if you push to a non-evolvution or "publishing" repo, where everything then gets squashed for public consumption).