Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Am I the only one who thinks that Git's UX is fine, and maybe even rather enjoyable? It has taken time to learn, and I am by no means a power user, but its model is now in my brain so, for better or worse, it's how I think and work now too (interactive rebasing for the win, all the time, and lots of shell aliases to shorten things). I do wish I had an easier way to split up a commit that accidentally included several unrelated changes though.

What's the lesson, that you can learn anything eventually, or that familiarity means you will lose the ability to accurately evaluate something?



The checkout command is severely overloaded; I'd hardly remember the functions if it wasn't for aliases.

The reset operations are also very inconvenient, due to the mix of: different types of reset (soft/hard); overlapping with the checkout command; different states of the files.

Pushing is also overloaded, due to handling both branches and tags (this is probably due to the fact that both have refs).

There are strange warts (e.g. adding with --patch doesn't include files not in the index; displaying the content a given stash entry requires typing the whole - unnecessarily complex - entry name), which I don't doubt make sense technically, but from a user perspective, they're odd.

There's probably a lot of stuff that one can find, depending on how wide their usage is. For example, I actually didn't realize how convenient patched (--patch) unstaging would be, since I typically perform a reset, then add (--patch) again.

I've personally never got past the feeeling that, not frequently but still with some frequence, git operations have a byzantine UX.

edit: find the merge commit of a given commit is something also very missed; it requires a non-trivial alias.


I was learning git around the time `switch` and `restore` were introduced to tackle the problem of checkout being overloaded. I started using the new commands and it instantly made more sense and began to click. I very rarely use checkout at all.

Something to be aware of when training junior devs. Do them a favour and learn switch/restore first!


I think this is the first time I've heard of switch and restore. Before I moved to magit I always used git checkout and git reset.


Git switch and git restore were introduced in Git v2.23, way back in August 2019. So... they're not brand new in the last few months, but... like you (and another poster) I'm not aware of them, as I had ... 8-10 years of muscle memory before without them around. I'm actually trying to think back to when I first used git... I don't think I learned about it at all until around 2007 - company I was at had a lot of SVN and a couple of the folks on the team were exploring other options. And... IIRC, around mid-to-late 2008, someone at a local Ruby group demonstrated github. But... I'm not sure I actually started using git 'for real' until 2010 or so.

So... there was 9+ years of learning certain commands/styles and... switch/restore weren't part of that.

And I've mostly switched to GUIs for day to day stuff - the Tower Mac client and sometimes the JetBrains git tools. They might even now be using 'switch' and 'restore' for some basic operations behind the scenes.


I've been using git since 2009, first for me too


> The checkout command is severely overloaded

I guess that's why they split git checkout into git switch and git restore


> The checkout command is severely overloaded;

I've been using git since 2008. I just learned a few weeks ago that I had the opposite understanding of what --theirs and --ours does on git-checkout during a rebase operation. (briefly: --ours is the branch you are rebasing onto, --theirs is the changes from the branch with the changes you are repeatedly cherry-picking into the new branch. see this answer for more detail [0])

I shudder to think how much I've screwed things up over my career as a result...

[0] https://stackoverflow.com/a/34260242/2492058


It kind-of makes sense when you think of rebase as a composite command that does a checkout of the branch/newbase and cherry-picks the commits from previous branch.


Yes, it actually totally makes sense, but the issue is that if one draws the mental picture the wrong way the first time (and is left uncorrected), it's equally easy to draw the mental picture (i.e. of commits "flying around" from one branch to another) in the other direction too. That's what bit me

I don't even know how to check for mistakes here with my current employer (god speed to the code I wrote at my previous jobs). Unlike a merge, a rebase leaves no trace except in the reflog :(


Push makes sense to me actually, branches and tags are both aliases to a particular commit. What makes them different is that the branch pointer gets updated on commit, while the tag pointer is (meant to be) static.

But I do in general agree that the cli leaves much to be desired. I really have to give credit to magit for making a git ui that is simultaneously easy to use, powerful, and has actually made me more proficient at using the regular cli (the commands that underlie the operations are echoed so whenever I do something new I take a peek at how it's done).


I think there is definitely a technical reason, but I'll explain the UX problem with an example: what does, intuitively, `push --force --tags` do?

1. force push both the branch and the tags

2. force push only the tags

It's very ambiguous - both answers make sense. And that's a big UX problem!


if instead of checkout you had a bunch of separate functions you think you would remember those?

Someone could probably make an argument that commands should be overloaded even more - clone, pull, and checkout could be merged for most of their common operations - as an example. Note: I am not necessarily for this but I'm not necessarily against it either.

agree --patch is weird.


> if instead of checkout you had a bunch of separate functions you think you would remember those?

It does (switch/restore) and I do.


If clone push and pull were overloaded into a

   git sync --from <local or remote ref, or .> --target <local or remote ref, or .>
It would not change much.

The problematic kind of overloading are like how

    git push origin master
and

    git push origin master:master
push master to origin while

    git push origin :master
deletes master from origin.


Check out pacman, the Arch Linux package manager, to see an extreme case of command overloading. It probably makes lots of sense from a conceptual point of view, but for users that simply use a very small subset of the tool, it can get a bit messy.


Anything can become "fine" with enough practice and muscle memory. I'm a fairly advanced git user and manage to use it mostly painlessly even for relatively advanced tasks but I still think it's pretty crap overall. Not as crap as it was 15 years ago mind you, but not great.

I was a big proponent of Mercurial for a long time because I thought (and still think) that the UI and defaults were vastly superior for most projects which don't have the needs and workflow of the Linux kernel. I gave up a few years ago when it became clear that git was VHS to Hg's Betamax.


It's fine. It works. But it's not intuitive.

A decade of near daily use of it, as the 'git guy' on most teams I'm in, and I'm still spending time searching how to do specific things. To use a UX term, there's very few affordances telling me what I should expect, guiding my intuition.

Imagine a VCS where it was obvious and easy to figure out how to do anything that is possible. Along with all the power that git brings today.


Seems like that's been done pretty well with all the wrappers, tui and gui's available.. what else is needed?


All the things built on top are limited to the things their creators decided were needed. They'll never be as powerful as git itself.

I want a successor to git that provides as much or more power but with the intuitive usability.

Is that so much to ask? (I joke)


My main complaint is it's leaking abstractions. You basically need a PhD in git's internal data structures to use git. Well not the 5% of git you typically need in your day-to-day, but the other 95%, which you need when the 5% you do need somehow goes wrong, through one of the many foot-guns git offers.

A concrete example: Accidentally pushing a merge you didn't want to push and now you're stuck staring git-revert(1) which has the sentence below, scratching your head like "uh, what's a parent number?"

       -m parent-number, --mainline parent-number
           Usually you cannot revert a merge because you do
           not know which side of the merge should be
           considered the mainline. This option specifies
           the parent number (starting from 1) of the
           mainline and allows revert to reverse the change
           relative to the specified parent.
Maybe you google a bit, and find this: https://www.christianengvall.se/undo-pushed-merge-git/ ... which explains a bit, but is still confusing as all hell. The rabbit hole continues to this: https://opensource.apple.com/source/Git/Git-26/src/git-htmld... which is also... not really clear.

But you still can't find information about what a "parent number" is. It turns out, the parent number is the order they show up in within 'git show HASH'. Combining that clue with Linus Torvalds email above may let you undo the merge, if you can make sense of his Feynman diagrams. Maybe.


> Am I the only one who thinks that Git's UX is fine [...]

No, I think most people that use it are fine with it. But those are usually not the ones you hear :)


Are you really sure that is the case here? I think everyone that starts working with git is a bit hung up by its complexity at least for a year, if not more.

It seems to me that, as it should be, every professional SW dev has managed to work with git at some point in their life, then. Because git is simply what you will most likely use nowadays.

But still, everyone remembers how hard it was to start out. Which is why, I think, these blog posts about git are so popular all the time.


Come on, getting comfortable with a couple of incantations takes people a whole _year_? Because you don't need much more when you're starting out.


Not always, but if you only do some of those incantations a few times per year, and what you remember is that you tended to get them wrong... it's a bit of a pain. This is partially why I switched to GUI clients for day to day. Tower (and maybe others) have an 'undo' which gives me a bit more confidence to try/test out things, because I know if it's wrong I can hit 'cmd-z' and be back where I was (at least until I push!).


> But still, everyone remembers how hard it was to start out

I sure don't. I learned the commands I needed (branch, checkout, clone, push, pull and commit) and didn't step out of those bounds until much later. It's really no different than learning any other skill or platform. Nobody starts out a master, but that's no excuse to never start.


> I think everyone that starts working with git is a bit hung up by its complexity at least for a year, if not more.

I had enough SVN merging issues so when git appeared I forced transition to git in a 3 month-period including writing Git-plugin for Hudson (Jenkins).


For you to enjoy using this tool you had to change the model your brain use, and you call that good UX? And using aliases means that your git is now different from you co-workers git. And when teaching the new guys you throw all these aliases at them that they have no idea what is or how work?


Is it really so hard to imagine a tool that takes some thought to use?

I didn't know how to use a welder just by looking at it, but the UX is fine once you know the concepts behind welding.

I honestly can't see how git could be easier given the requirments of the tool. If you want to reduce its capabilities because it's too hard then go ahead, but please fork it or make something new instead of ruining a perfectly good developer tool.

I do find the division between git seems to be really concise. Either people don't get what the fuss is about or they think git is just the worst.


> I honestly can't see how git could be easier given the requirments of the tool.

If you're curious how it can be done (IMO), take a look at https://github.com/martinvonz/jj. It's its own VCS but also compatible with Git so individual developers on a team can migrate to it.


Knowledge of git has become a sort of status signifier. It "makes you a developer".

I think for this reason there's a lot less pushback on its bad UX than there would be for any other program. It would render knowledge of its arcane guts less...special. The juniors will be forced to deal.

It makes me wonder though, if needlessly arcane knowledge is and always was a part of other apprentice relationships.


How do you improve the ux though?

I see a lot of complaints about it, and agree that for all the porcelain, you do have to become familiar with the plumbing to solve issues.

But noones shown me a good alternate ux story, just different porcelain/fittings. I still have to reach under the sink because said new porcelain didn't stop/avoid a case sensitivity clash, or it barfed on a merge and left the repo still to merge.


Make it use Hg's CLI.

Mercurial and Git have, for most purposes, functionally identical capabilities. Atlassian at one point allowed you to checkout a project as either a git or a mercurial repo painlessly.

Mercurial's porcelain makes sense: the command is exactly what you think it is, usually without any funky modifying flags. If there are flags, they're often obvious, and if they're not, hg help <command> will clear that right up.

Contrast to git, which is a mishmash of commands and esoteric flags, and the help isn't even inlined.

The underlying concepts are easy enough, but how you access them requires memorization of arbitrary command sets that are inconsistent and overloaded.

Fix the porcelain and IMO you fix most of the problems with Git.


Making the CLI self-consistent would be a big improvement.


>"to use a tool the way it was intended you had to adjust to use the tool as it was intended to be used"

I sure wouldn't call that a _bad_ UX. As with any tool you have to adjust to the tool or make your own unless by some miracle someone shares your particular idiosyncrasies.

>"modifying tool makes it different from your co-workers tool"

Yes, but that is a big plus instead of a minus. If your co-workers asks how to do something you can just give them the content of the alias. I also alias `git` as `g` in my terminal. Is that going to cause problems for my co-workers? No.

Unless you are training a complete-fresh-out-of-school-junior the "new guy" should already know how git works and in either case that sounds like homework for them more than anything else.


That’s a complete non sequitur. Everything we learn changes the way we view the world. You cannot make version control software without a data model that needs to be learned. Git’s model is very easy to visualize.


Depends what you mean by "change the model your brain [uses]". In terms of the fundamental model of how Git works, it perfectly describes what users actually want (get me the repo at revision X), but not what they expect (get me file A, revision 5, and file B, revision 7, and pray it builds).

In terms of the metaphors for the actual commands, I would agree. Reset and checkout basically make no sense for what they're actually used for. Switch makes things a bit better, but yeah, it would be nice if the entire Git CLI could be redesigned from scratch.


> For you to enjoy using this tool you had to change the model your brain use, and you call that good UX?

Every tool has its modus operandi, incl. but not limited to every programming language. Extending our understanding is hardly a bad thing.

Git proposes a model for handling stuff, and I prefer it very much.

And yes, the UX is fine.


I've never understood the argument that you should not optimize your own working environment (IDE/editor customization, alternate keyboard layouts, shell aliases, custom hotkeys, scripts, etc.) because it could be unfamiliar to someone else. I've also heard it in the context of, you shouldn't stray too far from the defaults because if you sit down to use a colleagues' computer, you will be out of your element. Unless your job is to pair program full time, or perhaps you're creating educational screencasts, maybe? If you slowly build out your own personal setup over time, presumably you should still always be able to explain what it is that you're doing at each step.


Counterpoint: for me to enjoy using the bicycle tool I had to change models my brain used … and, yes, I think the bicycle has a good UX.


Same here. I am totally fine with git as it is. If I weren't I maybe would just try one of the hundreds git plugins / clients to see if it better fits my needs.


I'm seeing a number of points in the post that aren't so much about Git, but online collaboration software / websites or dependency / package management, too; I don't think git should fix those.


Yep I think you might be the only one!

Actually I think you might be misunderstanding what people think is bad. Nobody dislikes the model of Git. It's great. That's partly why it's so popular.

It's the CLI and terminology that are the issue. Some things are very badly named (e.g. the "index"; anyone sane would call that the "draft") and the CLI is a complete mess. Remind me how you list submodules? Or delete a remote branch?


I do hear reasonable complaints here and there, such as the overuse of "checkout", but the majority of complaints I hear from new users fall into one of two categories. The first is complaining that git doesn't enforce a server/client model. The second is that git doesn't enforce a linear history. Both of these seem incredibly odd to me, as they are complaints about git accurately representing the development process.


To split a commit...

1. Make a new commit to revert what you to come last

2. Make a new commit to revert what you want to come first

3. Make a new commit to restore/revert line 2 above

4. Make a new commit to restore/revert line 1 above

5. Squash original into lines 1 & 2 above

Alternatively you can use interactive rebase, 1. set edit on the commit you want to split

2. When the rebase stops, `git reset --soft HEAD~1` (I think)

3. `git add` and commit as necessary then follow up with git rebase --continue


For as little time I end up needing to use the actual UI i really don't see the issue. This isn't the first time someone has complained about it either.

Reminds me of the slightly facetious anecdote that UI/UX has actually already been perfected so the complaints and problems you hear are just UI/UX people making work for themselves.


Interactive rebases are what I use as well. They're such a terribly broken way to use Git. You can't even start an interactive rebase (to go back and update earlier commits in the stack) in the middle of another one.


Git's UX sucks, but git is built on like four simple concepts (blobs, trees, commits, refs) and I feel that's almost impossible to improve on.


> I do wish I had an easier way to split up a commit that accidentally included several unrelated changes though.

Perhaps it's what you want something easier than, but I have `uncommit` aliased to `reset HEAD^`, and use it often as `git uncommit -p` (then amend, then the 'uncommitted' changes are unstaged ready to go in a different commit if they were wanted just elsewhere, or removed if not).


Thank you, I think that is exactly what I was looking for, and just what I had secretly hoped someone might suggest in response to my comment. Thanks again!


I think a git CLI is an elegant and orthogonal and maps pretty much semantically to basic commit graph operations. It clicked when I started to think in terms of graph transformations and what graph state I want at the end.

> I do wish I had an easier way to split up a commit that accidentally included several unrelated changes though.

IMHO this one of the cases when GUI is better. I use `tig`.


Got another here with what seems to be a unique anecdote: In the early 2010s, with only svn knowledge, I tried out both git and mercurial. I don't remember the details from back then, so I couldn't explain why, but I do remember thinking mercurial was confusing and git was easy to understand.


The model's basically a directed acyclic graph (not a tree), with each edge being the diff between the two nodes it connects. I think the UX could be improved if it built on the language of graphs to make that model more apparent - node, edge, etc.

(I also believe the same thing about SQL and sets).


It stores a full copy of every node, not the diff. The diff is just something that's rendered on-demand, and "gc"/"repack" compaction and it being content-addressable makes sure that the storage space doesn't balloon as a result of everything being a full snapshot.

This distinction makes a difference in some cases, there are other VCSs that store diffs as a fundamental property.

About your naming suggestion: I'm not saying you're wrong, but consider that git is used by a very wide audience, and even a lot of the programmer crowd isn't familiar with the graph theory terms you're using.

So "branch", "tip" etc. is by no means perfect, but I think it's probably better.


There are a lot of people, even in this comment section, whose internal model of git is "it's a tree". Langauge like "branch" reinforces that model, and I don't think it does beginners any favours in the long run. Something something leaky abstractions maybe?

(Maybe you're right and I'm being a bit ivory tower here).


Even if you suppose that Git had some extreme UX overhaul to the point of renaming builtins like "branch", the existing names would still survive in the popular zeitgeist, as they predated Git.

So, I think it's an interesting thought experiment, but practically speaking a non-starter.

You'd never be able to fully migrate over, instead it would be another case of that xkcd about N standards.


I agree with you. Adding new well-thought commands while keeping the old more arcane syntax would be enough for me (like git switch, git restore, git create-branch instead of git checkout -b, etc.).

This way new users will find it better to learn and people familiar with it don't need to change it.


`git switch --create` (or `-c`) is the new `git checkout -b`.

There is also `git branch --create`, although that doesn't switch you.


I made it up as an example of a future command `git create-branch` :)

Thanks for the commands. They are useful.


My favorite thing about git ux is the clarity. People often criticize saying I don't understand what to do and how. I do not agree. I think it is quite fun to use when you are aware that there is a history that you manage at the top, no matter what you are working on.


My complaint is that the names of commands in Git are not intuitive. Otherwise, I think the UX lf Git is near perfect because it's possible to write things like Git graphical wrappers.


> Am I the only one who thinks that Git's UX is fine, and maybe even rather enjoyable?

Same here. Have been using git for over 10 years now though, so this might be an "experts view" kind of thing.


Even if you get over the bad commands, the internal model of snapshots (and eg the need for rerere) can still be unintuitive and not always line up with the behaviour one would expect


fwiw, and surely anecdotal, but i don’t know anybody who knows the dark arts of the git cli and uses some client (magit, lazygit, etc) who prefers to use the former




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: