←back to thread

1062 points mixto | 7 comments | | HN request time: 0.001s | source | bottom
Show context
scrapcode ◴[] No.42942555[source]
I can't help but feel that Git has completely missed the forest through the trees that you can make a 30+ part guide explaining how to use it.
replies(6): >>42942641 #>>42942672 #>>42942768 #>>42943372 #>>42950299 #>>42954886 #
ajross ◴[] No.42942768[source]
My sense, bluntly, is that if people spent half the effort learning git that they do whining about it, no one would bother making a 30+ part guide just explaining stuff you could find in a man page.

Commits are snapshots of a tree. They have a list of ancestors (usually, but not always, just one). Tags are named pointers to a commit that don't change. Branches are named pointers to a commit that do change. The index is a tiny proto-commit still in progress that you "add" to before committing.

There. That's git. Want to know more? Don't read the guide, just google "how to I switch to a specific git commit without affecting my tree?", or "how do I commit only some of my changed files?", or "how to I copy this commit from another place into my current tree?".

The base abstractions are minimalist and easy. The things you want to do with them are elaborate and complicated. Learn the former, google the latter. Don't read guides.

replies(7): >>42942804 #>>42942870 #>>42943548 #>>42944155 #>>42944541 #>>42946116 #>>42946888 #
wruza ◴[] No.42944541[source]
This doesn’t work. Look:

Commits are sets of files. They form a tree. A branch is a named location in this tree. The index aka staging area is a pre-commit that has no message. Workdir is just workdir, it doesn’t go in the repo unless you stage it. HEAD is whereafter commit will put new changes.

Do I understand git? Seems like yes. Let’s run a quiz then! Q? A.

How to make a branch? Git branch -a? Git checkout -b --new? Idk.

How to switch to a branch? Git switch <name>, but not sure what happens to a non-clean workdir. Better make a copy, probably. Also make sure the branch was fetched, or you may create a local branch with the same name.

How to revert a file in a workdir to HEAD? Oh, I know that, git restore <path>! Earlier it was something git reset -hard, but dangerous wrt workdir if you miss a filename, so you just download it from git{hub,lab} and replace it in a workdir.

How to revert a file to what was staged? No idea.

How to return to a few commits back? Hmmm… git checkout <hash>, but then HEAD gets detached, I guess. So you can’t just commit further, you have to… idfk, honestly. Probably move main branch “pointer” to there, no idea how.

If you have b:main with some file and b:br1 with it, and b:br2 with it, and git doesn’t store patches, only files, then when you change b:main/file, then change and merge+resolve b:br1/file, then merge that into b:br2 to make it up-to-date, will these changes, when merged back to already changed b:main become conflicted? Iow, where does git keep track of 3-way diff base for back-and-forth reactualization merges? How does rebase know that? Does it? I have no idea. Better make a copy and /usr/bin/diff [—ignore-pattern] the trees afterwards to make sure the changes were correct.

As demonstrated, knowing the base abstractions doesn’t make you know how to do things in git.

I don’t even disagree, just wanted to say fuck git, I guess. Read guides or not, google or reason, you’re screwed either way.

replies(3): >>42946246 #>>42947164 #>>42948715 #
1. ajross ◴[] No.42947164[source]
Literally every one of those questions can be trivially googled. (In previous generations and fora, this is where you'd be mocked with LMGTFY links). You just, to continue to embrace the frame, don't want to do the work.

If you insist on memorizing commands for all these tasks (of which there are many), indeed, you're going to struggle and decide you need a 30 section guide. But you don't, and want to whine about it.

> I don’t even disagree, just wanted to say fuck git, I guess.

Pretty much.

replies(3): >>42947650 #>>42947810 #>>42948729 #
2. delta_p_delta_x ◴[] No.42947650[source]
Not the parent commenter. Git the version control system is superb, fast, robust, well-thought out. Git the CLI tool is by far one of the worst CLIs I have ever had the misfortune of using. I think the one-dimensional, string-y command-line massively complicates mental and reasoning models for a tool with a fundamental data structure—a tree—that is multi-dimensional.

A powerful Git GUI makes even moderately-complicated actions like cherry-picking, interactive rebasing, and even ref-logging absolutely trivial. In fact it was precisely said GUI tool that allowed me to develop an intuition for how Git worked internally; the CLI does no such thing.

3. MrJohz ◴[] No.42947810[source]
> Literally every one of those questions can be trivially googled. (In previous generations and fora, this is where you'd be mocked with LMGTFY links). You just, to continue to embrace the frame, don't want to do the work.

I find this an odd statement. I mean, no, I don't want to do the work! Not if it isn't necessary in the first place.

Take staging (or the index, because another of Git's foibles is poor naming conventions that stick around and confuse newcomers). It's kind of a commit, right? In the sense that it's a snapshot of work that represents a change to the code. Except we can't really make it behave like a commit, we have to interact with it using special commands until we turn it into a commit. Are these special commands really doing much differently than we might do with another commit? Not really.

Or take stashes. Stashes are more like commits — they even appear in the reflog! But they also aren't real commits either, in the sense that you can't check them out, or rebase them, or manipulate them directly. Again, you need a bunch of extra commands for working with the stash, when really they're just free-standing anonymous commits.

Or take branches. Branches are, as everyone knows, pointers to commits. So why is it important whether I'm checking out a branch or a commit? Why is one of these normal, but the other produces hideous warnings and looks like it loses me data if I haven't learned what a reflog is yet? And if a branch is just a pointer, why can't I move it around freely? I can push it forwards, but I can't move it to another arbitrary commit without fiddling around a lot. Why?

Or take tags, which are like branches, but they don't move. Is "moves" and "doesn't move" such a deeply important distinction that Git needs branches and two different kinds of tag?

---

To be clear, I think Git is a good tool, and I agree that once you've started to familiarise yourself with it, it's not so complicated in day-to-day usage. Yes, you'll probably need to Google a few specific commands every so often, but the general UX of the tool has significantly improved since the early days, and it is getting better.

That said, I also don't like the idea of settling with Git just because it's good. If there are alternatives out there that can do everything that Git can do, but with a simpler conceptual model, then I want to try them! (And, spoiler alert, I think there are better alternatives out there — in particular, I think Jujutsu is just as powerful as Git, if not more so, while simplifying and removing unnecessarily duplicated concepts.)

replies(2): >>42948918 #>>42953987 #
4. wruza ◴[] No.42948729[source]
First I didn’t understand git, now I don’t want to do the work. Then I do the work but it doesn’t work. Feel free to LMGTFY me on the last question. Do you know the answer? Is there an answer? Can you do the work?

What a stupid series of sentences this is for a piece of software we have to use daily. Even talking about it feels cringe.

5. wruza ◴[] No.42948918[source]
Jujutsu

Whew, just from the intro this feels like a breath of fresh air. Probably gonna migrate to it right after finishing the tutorial. Thanks for mentioning!

https://github.com/jj-vcs/jj

6. MatthiasPortzel ◴[] No.42953987[source]
> Stashes are more like commits — they even appear in the reflog! But they also aren't real commits either, in the sense that you can't check them out, or rebase them, or manipulate them directly.

They are real commits, you can check them out (it detaches your HEAD, the syntax to reference them is `stash{N}`). Although I think this furthers, rather than undermining, your point that there are an unnecessary number of other commands to work with the stash.

I think this is a failure of the git CLI as much as the internal data-structures. I think the idea of a commit tree is very good and a lot of people recognize that. The commands that git exposes to work with that tree can sometimes be miserable.

replies(1): >>42954870 #
7. MrJohz ◴[] No.42954870{3}[source]
I did not know you could check them out! But yeah, that really emphasises what I'm saying: there are too many things that are mostly commits but handled in a different way.

And I completely agree that this is about the CLI more than the internal data structures. I pointed at Jujutsu earlier, and that uses Git as the underlying data store (at least in its default configuration). It's an effective strategy in large part because Git-as-a-data-structure works really well already, and the distributed aspect means you can interop very effectively with existing tools like Github just by speaking the right protocol.

But while it keeps much of the same data structures, Jujutsu exposes a very different interface to those data structures, and one that I think is significantly simpler in large part because there aren't so many special cases (such as commits vs staging vs stashes vs ...). You end up with a smaller set of commands, but those commands are more consistent and can be applied in more cases. And you still have staging and stashes, it's just that you can build those yourself more naturally out of the tools that Jujutsu gives you.