6 ms·
What I dislike with git terminal UI is that commands reflect the innards of git, not what the user wants to do. It also forces a deeper understanding of the inn
by rich_sasha 5y ago
What I dislike with git terminal UI is that commands reflect the innards of git, not what the user wants to do. It also forces a deeper understanding of the innards for basic commands than ought to be necessary.
Examples where undoing an operation looks totally different to doing it:
- To stage a change you `add` it, to unstage you `reset HEAD`
- To commit you `commit`, to undo a commit you `reset --hard HEAD^`
The last example is also where you get pointed to an unsafe command for a fairly benign operation. Uncommitting is not particularly dangerous, but anything with `--hard` ought to give people a pause for thought. If you mistype it and nuke more than the last commit, that's also a bit bad - and fairly easily done.
Some other examples include shenanigans around pushing and pulling remote branches. After 10 years of using git, I still need to google it each time.
I think these commands are an accurate and reasonable representation of its inner state, but IMHO users should at least have the option of being somewhat isolated from it. Git is not a tool for algebraic manipulations on directed graphs, it is a version control software.
It has to be said, to git's credit, that although the commands are confusing to some (myself included), the tool works very well. I wanted to like mercurial more, but ended up going back to git, as much as I dislike the UI.
- leephillips 5y ago“ - To commit you `commit`, to undo a commit you `reset --hard HEAD^` The last example is also where you get pointed to an unsafe command” Who pointed you there? If I want to undo my last commit, meaning the commit itself, not the changes to my file tree, shouldn’t I say `reset --soft`?
- rich_sasha 5y agoMy bad, misgoogled. But this in fact reinforces my overall point. I don't want to be messing with `reset`, hard or soft. What is `reset`? [I now know because I had to learn, but I'd really rather not]. What I want is `uncommit`, or something like that.
- theli0nheart 5y agogit revert is probably what you want?
- leephillips 5y agoThis creates a new commit that reverses the changes of a past commit. That’s different from undoing your last commit, as in, you made a commit but then changed your mind, and want, say to make some more changes before you commit. (Explained in man git-revert.)
- theli0nheart 5y agoThat's by design; Git history is intended to be immutable when working with others. But, if you haven't pushed something up to a remote, the right command to make more changes is to use `git commit --amend`.
- rich_sasha 5y ago> Git history is intended to be immutable when working with others. That's another pet peeve (though maybe less git's fault): immutable, yes, but then rebase is pushed quite liberally. Arguably not by git itself, but by many online learning resources. It's convenient, and mostly works, but then occasionally really stings you. ...yet undoing the last commit, arguably the least aggressive of history-rewriting commands, remains awkward.
- b3morales 5y agoRebasing has a simple rule: it is perfectly fine as long as you haven't shared those commits.* Perhaps git should have a "checked rebase" command that requires a `--force` flag if there's an upstream branch set. *And even then it's kind of okay as long as no one else has made commits on top of the rebased commits.
- PaulDavisThe1st 5y ago
- brundolf 5y agoI've been using git for ~8 years and I've never heard of --soft
- leephillips 5y agoThe default for `git reset`, which is `--mixed`, may do what you want. The difference between `--mixed` and `--soft` is that the former resets the index as well as moving the HEAD pointer; the latter only moves the HEAD, so if you’ve `git add`ed any changes, they will remain staged.
- rich_sasha 5y agoWow this is a new level of Git hell I haven’t even heard about!
- leephillips 5y agoYeah, keeping track of Git’s three areas (files, staged changes, repository) can get confusing. After some thought I think my advice to you to use `git reset --soft` would be better as just `git reset`, because that’s a neater “starting over”: it’s more of an “undo” of the last commit action, I guess. I often find myself reaching for `git reset --hard` after screwing up and not feeling like tracking down how I broke things.
- 0x4d464d48 5y ago"It also forces a deeper understanding of the innards for basic commands than ought to be necessary." Glad you found something that works for you but this is definitely not true for all of us.
- johnnylambada 5y agoReset is a powerful command that happens to work for the “uncommit” use case. I use reset for a completely different use case: my CI system watches a specific branch for changes and when they occur builds it with a specific configuration. If I reset-push a branch, I get a build of that branch with that configuration.
- matheusmoreira 5y agoYeah, git is certainly a low level tool. That's actually what I like most about it. There's a few fundamental concepts I get to manipulate directly with git commands. I like dealing with innards like this because I can form a mental model of the tool. High level tools are a lot harder to understand. I think the problem with add, commit and reset is they aren't low level enough. The reset command in particular is juggling several concepts at once: HEAD, the index and the working tree. The add and commit commands work with fewer concepts: working tree to index and index to commit, respectively. I too google the commands I don't use often. There's no shame in that.
- rich_sasha 5y agoI probably pushed and pulled O(100) remote branches over the past decade (jeepers I'm getting old), so roughly once a month. It's not that rare, yet I still haven't memorised them, because I find them so unintuitive.
- spaetzleesser 5y agoOnce a month is close to my usage and it's often enough to remember things in principle but not often enough to remember the d#$%#$%^#$n syntax with all its obscure details.
- clojureyoureyes 5y ago> Yeah, git is certainly a low level tool. > I too google the commands I don't use often. So, spend more time getting the same result is fine for you?
- matheusmoreira 5y agoDepends on the result. I do interactive rebases extremely often, I don't have to look up how it works. Sometimes I have to use some command I'm not familiar with. Sometimes familiar commands gain new options. It's perfectly okay to use some reference for that. Also, "more time" is like 1 minute.
- folex 5y ago> If you mistype it and nuke more than the last commit, that's also a bit bad - and fairly easily done. If you ever run into this, you can use `git reflog` to see the history of your local actions. It's possible to revert almost any action with it. Reset a few commits that you've never pushed to remote? No worries! Just go to `git reflog`, find a point before it happened, and `git reset` to it. $ git reset --hard HEAD^^ # OOPS $ git reflog c48300f3 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^^ 527e26e0 (origin/master) HEAD@{1}: commit: air-interpreter-wasm = "=0.14.10" $ git reset --hard HEAD@{1} And you're back before "OOPS" :) It's really hard to lose changes once they've been committed.
- rich_sasha 5y agoYes, except... again, this is fighting fire with fire. If you don’t know git internals, mistype a non-obvious command and lose a bunch of commits, then “look in the reflog” advice is frankly adding insult to injury.
- gigatexal 5y agoThe age old adage applies here: know your tools.
- Osiris 5y agoAnd he knows it well enough to prefer a different tool. What's right for one isn't right for all.
- clojureyoureyes 5y agoSoftware is for people, not for software itself. I want to get things done fast and with less cognitive load, magit allows me to, git doesn't.
- sa1 5y agoIf it was that easy, https://blog.waleedkhan.name/git-undo/ https://blog.waleedkhan.name/git-undo/ wouldn't be a thing.
- lindeng 5y ago"- To commit you `commit`, to undo a commit you `reset --hard HEAD^`" You're not meant to delete commits like that. Git encourages you to stop "lying about the past", and you will run into a fair amount of trouble if you try to do so with shared history. You don't remove a commit "backwards" and change history; you add a new commit that undoes the previous one (git revert)
- hollasch 5y ago> You're not meant to delete commits like that. Couldn't disagree more. To me, one of the massive advantages of Git over other VCS tools is the support and completeness of its ability to edit time. You are the editor not just of the content under control, but over its branched evolution. Accepting this and working with time gets you to a next level of control. The first step in this process is really internalizing the tree of commits, and seeing branches not as lines of development as much as simple pointers on that tree. In many VCS systems, branching is a big deal. In Git, a branch is just a smart tag that is automatically updated by HEAD. Users new to Git need to get comfortable creating branches at a whim as the tree grows. The next step is getting comfortable with editing the tree itself. Primarily, I recommend using interactive rebasing liberally. This has multiple positive side effects: 1. It causes the author to think at a higher-level of the primary artifact they're constructing — the tree of incremental changes. 2. Authors begin to think about the repository as more than a dumb file backup system, but instead as a history with true utility, and so begin to construct "stories" in that evolution that are instructive and useful to future readers of that history. 3. It takes the author out of the flow of time, and encourages them to think about ways to change the past (within limits, of course) so that the constructed history is improved. All of this, of course, with the caveat that shared history changes must be coordinated (and frequently avoided). You can get very far thinking this way just about your un-pushed topic branch. There's a very real philosophical difference between those who see VCS as a secure audit trail (where changing history is "lying about the past"), and those who see a repository as a whole constructed artifact of intrinsic value, wholly editable as its contents. In this latter view, editing a line of source isn't "lying" about that line's contents, and neither is editing time.
- 5y ago