Ask HN: Do we need an easier Git?

75 points by raghavtoshniwal ↗ HN
Git is amazing and essential for my work. However, a vast majority of developers just use the clone-commit-push workflow and can get by. I've also taught CS to younger kids and seen students struggle to internalize the mental model of Git. The learning curve is steep for early devs. Is there merit in having a VCS that has a less steep learning curve or are the benefits of knowing a universal VCS too great (even if you end up using a small subset of the features)

95 comments

[ 2.3 ms ] story [ 83.4 ms ] thread
I do think git isn't user friendly. I came from perforce and also had a hard time building the mental model. Eventually I read the article about git's internals, and finally got the idea. What's most useful for me was the diagram of the three states (https://stackoverflow.com/questions/3689838/whats-the-differ...).

some of the git's naming was also not intuitive for me, For example, calling the scratch area "index". I didn't seem to have to learn perforce, cvs or svn's internals to use them fluently.

but I guess it's a bit difficult to change the current situation. git has become the most common choice. And once the mental model has built, it's not that difficult to use, admittedly I only use a few very common commands.

you know the challenge won't be building the version control. for mass adoption, you need a github-like platform.

> some of the git's naming was also not intuitive for me

For me this was (and is) the main source of "what is this and how do I use it" problems. Git is supposed to be an advanced tool to make snapshots of a folder, save them in a tree structure with multiple leaves, combine or even modify them, keep a copy remotely, etc.

So, you are probably expecting to find a "save" command, an "upload/download", maybe a "combine snapshots", and for more advance tools an "edit history". But instead you have "commit", "push/pull", "merge" and "rebase". Those are less intuitive (specially for non English speakers) so you end using only the few ones someone told you to use.

Once I realized what "fixup" was and how to use it I can't stop using it.

Git model is no so complex, the naming is, so it's like learning a whole new language and it takes time.

I think it is also true that many of us use github or similar with a PR workflow rather than the way Torvalds and the Linux core maintainers use git.
I don't think I know any other workflow but the PR based one.
> some of the git's naming was also not intuitive for me, For example, calling the scratch area "index".

I think this is the real problem. Git is actually really simple. The mental model is not even difficult - you can describe it in a sentence or two.

* Each commit is a snapshot of your code at a certain point. Like making a copy of your project and renaming the folder (but stored more efficiently). Commits also include metadata to say which previous commit(s) they are based on.

That's it.

All the difficulty comes from figuring out what the hell all the badly named and confusing commands do. As you mentioned I think "the index" is probably the worst - why not "draft commit" or just "draft"? That's what it actually is. It's so bad people even invented an unofficial name for it ("staging area").

It's not the only one. "Commit" is a pretty bad name in itself. It's not even a noun - "snapshot" would have been better.

And there's the commands... Look up how many different things `git checkout` does, or `git rev-parse`. And don't ask me how many times I've googled "git delete remote branch".

They did add `git switch` so I'm mildly hopeful that at least some people care.

Weird naming is definitely part of the problem. I think the other part that makes git painful for beginners is that it does not mandate a workflow (do you have a central authoritative server? where is it? Do you merge master into working branches? Rebase all the time or never at all? Squash commits, or not? Etc). That means that as a newcomer you have to decide for yourself what workflow to use (at a point in time when you have no experience to help you in making that choice) and when you read tutorials or advice online you have to be able to spot whether the author of the advice is using the same workflow you are or whether their suggestions and command line options will not work in your situation. Earlier version control systems tended to be more dogmatic about how they were used, which is less flexible but easier to get to grips with.
I think the other part that makes git painful for beginners is that it does not mandate a workflow

That's a very good point. Every company I worked at that used SVN back in the day used it in basically the same way, making it very easy to get started. With git different projects even within the same company can have completely different workflows.

> that it does not mandate a workflow

that's the only reason it gain adoption among other projects, which already had (different!) well-established workflows and let to it being where it is now.

> The mental model is not even difficult - you can describe it in a sentence or two.

> * Each commit is a snapshot of your code at a certain point. > That's it.

Unfortunately, it's a bit more nuanced than that. What you described is only git's storage format. Git operations and UI unfortunately isn't consistent with that model. Take for example, interactive rebasing. By your definition, if we delete a commit, the subsequent commits should remain unchanged - because commits are only snapshots after all. But that isn't what happens. The change introduced by that commit gets deleted from all subsequent commit. Commits are treated as diffs here.

Git UI switches between snapshot and diff model quite often. Merges and rebases are all patch operations. Novice users can get away with being oblivious to this change for most operations till merges. But rebases require you to be aware of it. Even for experienced git users, large multi-commit interactive rebases are hard because git simply hides all the nuances of patching (you are better off rebasing in small chunks). This becomes immediately clear when you use a tool like quilt or stgit. In my opinion, this is something that prevents beginners from going beyond clone-commit-merge workflow and being able to create beautiful commit history like that of the kernel.

> By your definition, if we delete a commit, the subsequent commits should remain unchanged

And that's exactly what happens. On a rebase, the original commits are not deleted, but the command creates new ones that matches the same diffs (unless there is a problem like an empty commit or a conflict).

Normally those unused commits are 'lost' because no branch/pointer are now pointing to it, unless you have another branch which does. Later the gc removes those orphaned commits (although I think you do can restore them before that happens).

> if we delete a commit, the subsequent commits should remain unchanged

They are. You can get to them using the reflog.

> Commits are treated as diffs here.

Not exactly. For the rebase operation Git calculates the diff between subsequent commits and then reapplies them to make new commits, but the commits themselves are never treated as diffs.

> Git UI switches between snapshot and diff model quite often.

It doesn't. It allows you to perform operations that result in or consume diffs, but of course it does! They're useful things to do. How else would it work? It never treats commits themselves as diffs because that doesn't make any sense. Only the differences between two commits are treated as diffs (hence the name!)

> I think this is the real problem. Git is actually really simple. The mental model is not even difficult - you can describe it in a sentence or two.

Being simple and being easy to use are two different things. Brainfuck is simple, but writing a hello world is hard. Python is superficially easy at the beginning, but I wouldn't call it simple. There is a balance to find between simple and easy, and git is on the simple side, at the cost of the easy.

Maybe just an optional second cli for git that improves usability? If it takes off, switch it to default. Are there any examples of a cli tool with multiple, user selectable cli interfaces?

Edit: to answer your question, there’s a lot of value to learning the standard industry scm tool.

Yes there is. But there would be a tremendeous value to make the standard industry scm tool as user-friendly as possible. There are few tools where you would want to prevent user-errors more.
I used the GIT GUI, and it seems easy enough for me, though I haven't pulled things out of repositories yet, just stage/commit | push to github

What's needed is better documentation, nothing more.

Basic git flow operations are straightforward. I taught a few graduates who had no prior vcs experience and they had no problem with day to day stuff. Because git is truly a powerful tool its ux becomes complicated once you need to do something beyond the simple operations.
Have you used any other DVCS other than git? Bitkeeper ux us vastly better. Git ux is rough.
this always makes me laugh: https://youtu.be/3mOVK0oSH2M

edit: start at 3:00 mins in

395K commands only needed for daily use, lol
When he entered the command and it started scrolling I was like "oh, I didn't know git had so many commands".

Then it kept going, and going, and I started to feel fear.

I think I'm going to use this when someone tells me "git is easy"

Edit: I think the video was a joke, I don't find that list anywhere. Very funny anyways.

First 40 minutes are pure gold. He kept a straight face all through it, and made sure to not overdo it. An unsuspecting Git student would have no clue.

Makes it very difficult to trust anything he says or does in the following segment.

(comment deleted)
No matter how many times I do it, i have troubke squashing.

Maybe I am just dumb .

git reset <parent> —soft; git commit -m squash

The first command sets your current comment to parent, with any changes staged, the second commits it.

I don’t mess with the interactive rebase. There’s a magic combination of this and the reflog that can preserve commit history, too.

Respectfully, version control is not necessarily easy, and even with other versioning tools (they already exist, and some purport to be easier than git), you still have to think about what you're trying to do. I see this attitude a lot with new developers, and it's troubling. Of course git is hard; what part of computing _isn't_ hard? Git is a hell of a lot easier than, say, debugging a kernel panic, or solving a tricky race condition. If the vast majority of developers can't get by without learning anything beyond clone-commit-push, then I truly fear for our industry, because I am thoroughly average, and I have a pretty good idea of what git is up to when I run commands.

Git might not have the best interface, and you could argue for different models, but some of this stuff just takes time and effort to learn. This is an important lesson for new developers to learn: some of this stuff is not, in fact, easy, and I don't where this expectation that it is comes from. It reflects a disturbing trend of learned helplessness I've noticed from newer developers. Computers are hard, but if you want to be the expert, you're going to have to figure it out. I don't think we need easier version control, I think we need developers who are willing to learn hard things.

Git is the closest any software comes to perfection.
IMHO, that spot is reserved for sqlite.
The data model is. The choices made for naming and structuring the CLI certainly not.
you can make aliases and use extensions
Yeah. Git is great software, but there's seriously no reason I should be typing multiple CLI commands over and over again as part of my workflow in the year 2022.
So what do you want to do? Pressing the mouse button over and over again?

I don't claim the git CLI is always logical. But you seem to complain that there is one.

:) e.g. magit is keyboard focused, and a much nicer interface to git than the CLI.
Ok, so I don't know your exact workflow as it could be some weird branch hopping and squashing and reflog breaking weirdness, but:

1. Most terminals have command history, so if you're really typing the same thing over & over & over & over... just use that? 2. Even if that's not the case, bash/batch/powershell scripts to automate things? 3. Most IDEs nowadays have pretty solid git integration so if you're wanting to click things, there's that.

bash has a history search feature you can access via control-r.
Overall IMO, Git is so good that if you have a problem with usability, it's better to work on a wrapper around Git than it is to change Git itself.

Maybe a plain English tool that just lets you click through menus to dictate what you want to do. No Git lingo whatsoever. Very rough examples below:

1) "I want to save my progress". (combination of git add and git commit) 2) "I want to go back before my previous save." (`git revert` on your last commit) 3) "I want to upload my latest work." (git push) 4) "I want to pull in any new updates." (git pull)

...Et cetera. Stuff that's basic enough to satisfy some basic use cases.

Then, for anything more complicated than this basic subset, users have to whip out the terminal. The balance between basic and complicated, and too little vs too much, might take time to figure out.

I fully agree. The challenge here might be if it's not a single user repo, how does the simple frontend deal with tricky cases introduced by other users?
It probably wouldn't deal with it "well enough". Although, any errors or validation failures would point the user to use git commands to restore peace and order before using the tool again.
The CLI could be simpler without making it less powerful. For example, "the index" should not be visible to the user, IMO. The usecases it enables can be achieved with a simpler CLI (like Mercurial does).

Also, stashing could be automatic and rebase could also rebase descendant branches.

Since you should not be working in ways that create merge conflicts if you can avoid it I would say a simple distributed disk backup would be enough for 99% of programmers.
Yes, it's called Mercurial.
So the answer would be, no it's Mercurial.

I also used to like when I did not understand git well. After years of learning I mostly understand git and have mostly forgotten that Mercurial exists.

> After years of learning I mostly understand git and have mostly forgotten that Mercurial exists.

Meanwhile after years of learning I mostly understand git (and am pretty much the reference for colleagues) and I still wish more or less daily its UI wasn't so absolutely shit.

Also revsets, good god of all the awful things in git's UI gitrevisions(7) ranks so, so high.

Personally, having used it for over a decade now, once you learn how it works, git is perfect. But it's not necessarily easy, sure. But then there are a lot of easy solutions out there that aren't very good. I'd say it's worth the investment to learn it, but I've seen so, so many developers refuse on the grounds that they simply don't want to. These are the folks who think it isn't good, the ones without experience.
Git is complex, which is fine.

People take that to mean they need to learn and teach git in intricate detail, and use it in ways that are needlessly complex, which is dumb.

The different flavors of processes using git are where I see significant differences in how hard it is to use. GitHub/GHE encourages pull requests and force-pushing a candidate branch. Gerrit encourages a staged-commit via "refs/for/$dest_branch". Projects like QEMU and the Linux kernel are much more decentralized and leverage requests to pull from dev repos and email patches ('git send-email'). All of these differences have some impact on how you use git locally and how easy or difficult it is to recover when you make a misstep.

Subjectively I think that - the staging area is unnecessarily confusing (mercurial did this better imo), and the overloading of 'checkout' causes confusion too.

No. I had to use mercurial at my old job and everyone in the company saw mercurial as an easy and efficient alternative to git - something which I could not comprehend. And truthfully after using the "easier" solution, I'd rather take the code, print it out on punch cards and compare them in order to create the adequate changes by taping the holes accordingly and feed the punch cards back into the computer. Now that I'm saying it and having looked at how mercurial works underneath, it's not far off, with the exception that mercurial creates copies of all punch cards and keeps stacking them on top of each other. I've never hated any version control as much and I've had to use svn in the past. Git operates on a strict and crazy stupid model without adding unnecessary features and advertising them as "flexibility" or "ergonomics". I've worked with juniors who've never used git in the past and in all instances it took them a day at most to figure out how it works.
SVN isn't that bad at all.

Perforce on the other hand when it is set up for pessimistic locking, that was interesting when I had to use it in a team setting and trying to work from home 14 years ago.

I mean... Credit where it's due: it certainly beats mercurial for me.
We use mercurial at work. I actually like it very much (of course it might be because we follow a certain workflow).

When I try to use git for personal projects (because everyone uses it and I'd like to learn it) and I really am struggling sometimes to get even the simplest workflow working as a single person. I can't even imagine how it would work when having multiple people work together.

That's the point: you have to follow a workflow to make it even remotely usable. And even so, they are hacky workarounds at best and generally mercurial feel like the product of "that's good enough". And in a more general sense mercurial feels like(and in fact historically is) the product of unsolicited help. The concepts of having separate actions for pull and update are ridiculous. The --new-branch option is equally stupid. Many basic features are missing and you have to resort to stuff such as plugins like evolve or whatever it was called(say rename an existing branch without causing the universe to implode on itself). Back-merging in mercurial makes no sense if you live with the basic assumption that you have one default/master/main or whatever you wanna call it branch. And truthfully, storing the entire history of your work as diffs is what I'd assume Gutenberg would have come up with - great for the 15-th century but sticks and stones by 21-st century standards. And a ton of other basic features are either missing or a complete hack - stashing, rebasing, update-index, submodules and all the things which personally as a git user, I take for granted.
I don’t feel so. Beginners can learn a handful of commands to gets started. And once they started to contribute to a production project they anyway have to learn some additional advanced commands (mostly rebase on top of others changes and conflict resolution). Things beyond a rebase a rarely used by anyone, so most people can just avoid learning those or learn when necessary.
People might be interested in gitless [0], which purports to be "a Git-compatible version control system, that is easy to learn and use". It appears to be built on top of git, using a simplified conceptual model.

I read about it in one of Adrian Colyer's "the morning paper" blog posts from 2016, "What’s wrong with Git? A conceptual design analysis" [1], which summarizes the paper that critiques git and describes gitless. (The link to the paper at the beginning of the post no longer works, but a commenter suggested this [2] instead.)

I should point out that I've never used gitless, and I don't know whether it's still maintained, but if nothing else the critique itself is interesting.

[0] https://gitless.com/

[1] https://blog.acolyer.org/2016/10/24/whats-wrong-with-git-a-c...

[2] https://web.archive.org/web/20131230194321/http://people.csa...

My pain points with git are the detached head states (so puzzling) and basically everything that concern submodules (very brittle.)

Anything about undoing commits, going back to a specific version of the code is less painful but I almost always have to google for it because that are not daily operations and I can't reliably remember them. Maybe that would be easier if I used a GUI instead of the command line. Anyway, a simplified git with only basic functionality and dead simple error messages AND part of the standard git distribution would be very useful. After all git does a lot of things but I'm using only a core 1% of it. Even after 10+ years I reliably know only the basic clone, add, pull, push, checkout, branch, commit, merge, rebase, log, diff commands. I have to google everything else, even how to track a remote branch. It's checkout -b but Gould I also fetch and pull it before? You got the idea.

And it should be about files, directories and branches, the stuff developers reason about.

No, we need the power that git offers us for scaling workflows and contributions to large ecosystems. Software does not get less complex over time, but more complex - and we need a system to handle contributions to a complex system (read: large, distributed, multi-thousand developer/files codebase)!

git is as simple as possible while being as powerful as possible.

What we need is better education! Not only how git works, but also how clean and scaling development workflows work. I've seen too much "Lets just copy the code to the production environment"-workflows in my live already and I do not even have 3 full years of professional experience as a SW dev!

git is as simple as possible while being as powerful as possible

This is far from being a foregone conclusion and would need a careful analysis to justify. FWIW Fossil manages to make do without Git's (insanely named) 'index' (what everyone calls the 'staging area').

It might be useful to be able to write git commands in more descriptive way for beginners. “Git add all new files”, “Git commit all files with message ‘foo’”, “Git show history of file ‘readme.txt’”, “Git restore previous version of file ‘readme.txt’”, etc.