back

by guytv·3y ago·view on hn ↗
Just the ergonomics of git are sometimes mind-boggling. for instance: "git checkout" is used for 3 different things: “switch”, “create branch”, and “revert a file”. Deleting a remote tag is “git push” but a deleting a local one is “git tag -d”. There are many such examples
5 comments
It's just git's UI is based on operations on the underlying storage instead of workflow intent. From that perspective branch switching and reverting a file are actually similar operations.

For many cases this would be a wrong approach. But git's storage model is quite simple and elegant, and both gives unlimited freedom in adapting it to your needs and could be dangerous if you don't understand it.

When coaching junior devs on git usage I always start with merkle trees, not with a list of commands to remember. This detour takes 20 minutes, but actually gives intuition to fix even worst mistakes without my help when they happen. I can't imagine the same with any other VCS.

yet one often has to google a command, to make sure what is the correct command, even if they know all about the mechanics of the underlying blob storage.
Honestly, the examples you gave seem to make sense when you understand how git works and the philosophy.

It seems most (all?) interaction with the remote is via sync commands: push/pull/fetch. So why bake it into a different command. Commands like "git tag" interact with your local.

Given the abstract concept of a checkout, as it works in git, none of that is surprising (save for maybe that you could create a branch); however, that seems like a desirable feature. Why would you want to do a branch create, then checkout after, when you just want it done right away?

EDIT/P.S. Regarding the git "abstract concept of checkout" that I mentioned, but forgot to define. This is a pretty simple concept: switch working copy to on pointed to by branch reference, and new commits will go on that branch (appended to the end of the branch), create new branch if it doesn't exist (but doesn't this require a flag?)... can't you still create with branch if you really want to?

IMO push is quite coherent since it consistently updates remote refs. The variation in checkout is pretty bad though.
The perfect command for deleting remote tag would be "tag -d(elete) -r(emote) <tag>" The existence of "remote refs" is an implementation detail, and git bothers you with it unnecessarily. And if you really need a command to update all remote refs at once why not call it "git sync-refs"? The fact that you use "push" command to delete something is confusing as hell.
Right. The git porcelain is baffling, but the actual git data model doesn't need fixing; it's complex but necessarily so. I'd be more interested in an alternative porcelain than a totally different VCS like FB's Sapling.
> "git checkout" can is used for 3 different things: “switch”, “create branch”, and “revert a file”

Git v2.23 (released in August 2019) added "git switch" and "git restore" commands to straighten this up.