I see this type of remark against git quite often on HN and I think it's exaggerated.
I agree some of the porcelain are misleading and overloaded as convenience functions such as checkout, however a decent chunk of it is inline with the underlying data structure. Nothing is perfect, and git is pretty damn good - horribly designed? no, could do with some breaking porcelain re-writes? sure.
> git is pretty damn good
UI-wise, it really is not.
That commit object could be pointed at by a separate COMMIT_HEAD pointer. If you have a COMMIT_HEAD different from HEAD, then you have a commit brewing. Finalizing the commit means moving HEAD to be the same as COMMIT_HEAD. (At that time, there is a prompt for the log message, if one hasn't been already prepared.)
Your "staged" changes are then "git diff HEAD..COMMIT_HEAD", and not "git diff --cached".
Speaking of which, why the hell is "cached" a synonym for "in the index"? Oh, because the index holds a full snapshot of everything. But that proliferation of terminology just adds to the confusion.
I can't think of any other area of computing in which "cache" and "index" are mixed up.
git commit --patch
then interactively select the specific changes by diff hunk.It combines with --amend.
However, if the staging area is relaced by a CHEAD commit ("commit head") whose parent is HEAD, then the problem of "stashing the index" completely goes away. You don't stash staged changes because they are already committed into the staging commit CHEAD.
That said, the stash feature could work with this CHEAD. Stashing the staged changes sitting in CHEAD could propagate them into the stash somehow (such as by a reference to that commmit). Then CHEAD is reset to point to HEAD, and the changes are gone. A single stash item consisting of work tree changes and staged changes could simply be an object that references two commits: a commit of working changes committed just for the stash, and a reference to the CHEAD which existed at that time. It could be that one is the parent of the other. So that is to say, a commit is made of the working copy changes, parented at the CHEAD. The stash then points to the SHA of that commit.
Intuitively, I know this would work, because in the existing Git, I could easily implement this workflow instead of using the stash. Given a tree of local changes, I could "stage" some of them by creating a commit with "git commit --patch". Then "stash" rest of them into another commit "git commit -a". Then, create a branch or tag for that two-commit combo, and finally get rid of it with "git reset --hard HEAD^^". Later, I could easily recover the changes from that branch, either by cherry picking, or doing a hard reset to them or whatever.
Speaking of which, an example of how stashes are limiting because they aren't commits, think of how you can't do:
git reset --hard stash@{0} # wipe it all away and make it like this stash
You can't do that because a "reset --hard anything" cannot reproduce a state where you have outstanding working copy changes and/or an uncommitted index, but "stash apply" or "stash pop" are saddled with that requirement.The requirement of reproducing working changes and staged ones from a stash represented as a two-commit combo is very simple. You cherry pick one normally and make it the CHEAD (the aforementioned special head for pointing to a commit being staged). Then the other one is cherry-picked with -n, so it is applied as local changes.
Indeed, in more erudite forums with smarter users, more level-headed, less biased opinions of git circulate.
Of course the next step is unlearning `git checkout` muscle memory and moving to using `git switch` and `git restore` more regularly.
Ahem, the command for "Reset working directory/Discard changes/Revert to last commit" is "git reset --hard".
That's the one I use.
"git checkout -f" does the same thing, but only because their different functionality coincides when there are no other arguments. When given a non-HEAD commit-id or branch-id they do different things.
I didn't think at the time to bookmark it with my "hn sucks" tag, and over the past year or two, I've tried several times to find it again, for reasons similar to[1], but I've been unable to.
When I first started using UNIX/Linux after learning the DOS shell, I never said that using commands like rm or mkdir were not intuitive and that it should be like using del or md instead. I just learned the different commands by reading through documentation.
Other OSes have a concept called forgiveness that allows you to easily reverse a change you made explicitly so that you can experiment with it and figure things out for yourself. The problem is that Unix fundamentally doesn't allow you to figure things out by yourself. You absolutely need either a manual (that you will never find if you haven't already been told how to find it), or you need to have someone you can ask questions to.
Much of the complaints about checkout have been split to other commands in newer versions. Does this make Git still invalid in your opinion?
https://git-scm.com/docs/git-restore https://git-scm.com/docs/git-switch
They also fail to acknowledge that contemporary unix, aka Linux in it's many derivations and flavors, is entirely malleable at the source code level by it's users. That is a feature provided by literally no other operating system that is deployable at scale, and is, in fact, the singular feature that drives it's adoption -- not only is it 'free', you can hack it together in any fashion you damn well please, and you can use it to build peer-grade native applications, typically with little more than a tip of the hat as 'overhead'.
tl;DR: Some folks might miss the point because they are not sufficiently motivated to engage the *nix world with the degree of articulation required to tap into it's less than casually accessible capabilities.
My brain is really quite small compared to all the knowledge about computers that is out there. And my willpower too is very limited. So I would rather learn things I'd rather like to know, and be motivated to do things I'd rather get done instead of spending those precious resources of mine (and time! I will die in less than 25,000 days, that's a pretty small amount of time, you know) on something of dubious value.
Making a special snowflake that fits your brain better is good for you, but not necessarily anyone else.
Making something good for everyone will, almost inevitably, become a design-by-committee monstrosity that is as problematic as the tool being replaced.
The truth is, I am skeptical that these tools can be replaced by something that requires no effort to learn. At least, for the tools we already have, if you dont want to learn them, you can roll the dice and copy / paste from google overflow.
Yes, and that's why the parent's argument that "you can hack it together in any fashion you damn well please, and you can use it to build peer-grade native applications, typically with little more than a tip of the hat as 'overhead'" is not a convincing argument. Yes, you can learn a lot about it and tinker with it and "harness its power", as opposed to using something that's less flexible, but is already pretty damn ergonomical, and is much more accessible and easy to learn about (maybe to the point you're not even realizing you're learning).
Vs obtuse half broken shit people created out of whole cloth and refuse to fix.