7 ms·
Two Commits and the User Experience of Git
- allan_golds 9y agoUnclosable pop-up
- dfabulich 9y ago(Author here) That's not supposed to happen! What device? (Phone or desktop?) Could you post a screenshot to imgur?
- davexunit 9y agoTech blog writers, please stop invoking the "UNIX philosophy". It's always used as a pseudo-technical argument replacement by people with subjective opinions about why software X has too many useful features.
- dfabulich 9y ago(author here) I want all those features! I just want them to be separate commands, like "eg" does. "eg switch" and "eg unstage" will never clobber the working tree.
- davexunit 9y agoI think your article is good, I just think the UNIX philosophy is a bit oversold. The Git CLI certainly leaves something to be desired!
- msla 9y agoEven the traditional Unix tools don't follow the Unix Philosophy extremely well. ls is a prime example: It has too many ways to sort and format its output. It "should", in the Unix Philosophy sense, simply list things in a directory and leave sorting and formatting to other tools. However, parsing the output of ls is generally a bad idea, as it's meant for human consumption, so ls breaks another tenet: It isn't very composable, as it is difficult to use it in a pipeline, even though it should be a prototypical source program.
- hprotagonist 9y agoand `find` has practically re-implemented half the rest of the toolchain. last week i discovered the `-delete` flag. For years, i had been doing `find <stuff> | xargs -rm` instead.
- jff 9y agoI don't even bother using 'find' to actually find files. 'du -a <path> | grep <name>' works easily enough and I don't have to remember find's weird syntax.
- sametmax 9y agoI use the ffind program instead. It's just so much easier with saner defaultq.
- eridius 9y agoA better alternative to xargs is `find <stuff> -exec rm {} +` (though of course -delete is simpler).
- barrkel 9y agoI'm not sure there's much upside in using -delete, -exec etc. from find since they're redundant and can be replaced by composition; half the time, I want to stick a grep -v in there between the found paths and the execution, so xargs is usually handier than not. (I have a tool called print0 which converts line terminators to nulls, so I can use xargs -0 along with grep etc. without needing to use -print0.)
- woliveirajr 9y agoBut there are cases where `-delete` or `-exec` aren't enough, and xargs allows better handling.
- flukus 9y agoFor that matter, why do we need xargs and not just `find <stuff? | rm`?
- 9y ago
- Ixiaus 9y agoI agree that over use of a phrase can dilute a message but I think you're not acknowledging something important. The phrase "Unix Philosophy" is a concrete, functioning example of compositionality. Git is a pretty heavyweight tool and many of its commands are not compositional or built up from many smaller functional units. Git repos also do not compose, which is a significant flaw.
- davexunit 9y agoIf we're looking for good role models of composability, UNIX is not the place to be looking.
- Ixiaus 9y agoI think there may be better role models but I have a hard time finding ones that are jargon-free (to a degree, "pipes" and other terms are jargon but generally accessible to people who work with Linux), approachable, and functional for people that do not have the mental model.
- wnoise 9y agoIt's not great -- but it is a good example because nearly everything else in wide use is far worse.
- barrkel 9y agoUnix has produced a bunch of composable tools that have stood the test of time - find, grep, sort, uniq, wc, sed, awk etc. - decades of reusability and composability, things I reuse and compose to this day. I can't honestly say that about any other computing tool I use.
- gue5t 9y agoThe Unix philosophy references some concrete properties of software (many processes performing small tasks, communicating with text streams), but these are neither desirable (serialize/copy/deserialize is wasteful and kills locality; process boundaries preclude inlining and other optimizations) nor really core to compositionality. The compositionality of processes and pipes is arguably the best thing about Unix, but doesn't even work terribly well: piping n different inputs into the same command requires hacky workarounds, and you end up writing ad-hoc parsers/text-manglers constantly. One way to cast the ideological stance of the Unix philosophy is "simplicity of implementation at all costs"; the costs include memory unsafety, poor performance (of pipelines and shell scripts), code duplication, race conditions (look at the filesystem, a vast blob of global mutable state!). It's time we start fixing these problems and abandon the mistakes of Unix. Yes, composition is important, but you don't have to sacrifice so terribly much to get it.
- CJefferson 9y agoI really agree with this, it's too late for git now, but I consider the overloading of 'checkout' to be one of the worst pieces of UI I've ever come across, and the source of confusion for many people when I try to teach them git. I didn't know that 'git reset' has a similar problem. If git gained the 'checkout-tree' and 'checkout-file' (and other) commands mentioned, I'd personally use them instead of checkout.
- sametmax 9y agoYeah as a trainer those are my pet peeve as well. And of course hard vs soft reset and so many ways to undo work. Those 2 commands would be a great idea.
- CmdrKrool 9y agoThis is my go to page for untangling the behaviour of git reset and checkout: https://git-scm.com/blog/2011/07/11/reset.html https://git-scm.com/blog/2011/07/11/reset.html . And I find myself going to it quite often because another problem with this kind of slippery design is it just doesn't stick, in your head. (Amusingly, the author begins by admitting he wrote a whole book on Git - and perhaps the most popular one - before strongly understanding this himself.)
- ajarmst 9y agoIt's not really too late for git, if there is sufficient energy around rolling back the change. The relatively standard process for API changes of (1) adding a new command that does the same thing for a major version, (2) adding a deprecation warning and description of the new way to do it (say 'Please use checkout-tree instead') for another major version or two before (3) it stops working in major version 3. That allows people to get used to a syntax change without breaking scripts for a while. The git project has already used that process for other API changes. In fact, it's pretty common practice to do that sort of thing when a given CLI option starts getting too baroque and complex.
- stephengillie 9y agoGit is really 2 tools in 1: a manual Distributed File System, and a Version Control System built on hashing. And much new vocabulary. Instead of helping to make the system simpler and easier to understand, the vocabulary actually makes the system more complex and increases the slope of the learning curve. It shouldn't be so complex to indicate you've copied files from Github, made a personal copy to work on, and have switched to that copy. But this involves finding where your Head is, having an Origin, a Master, and somewhere Remote, finding the right branch in the tree to hit with a fork, and going to a checkout counter.
- hprotagonist 9y ago>Today, Git has a reputation for being a tool that erases your working tree without warning if you use the wrong command. This is news to me.
- rpazyaquian 9y agoNot to me. This happens all the time when you're learning the tool.
- jakebasile 9y ago>> Today, $SHELL has a reputation for being a tool that erases your working tree without warning if you use the wrong command What a vacuous statement. If you use something incorrectly, it works incorrectly.
- tqkxzugoaupvwqr 9y agoIf a tool allows you to easily destroy something, the tool needs a safety switch.
- mikeash 9y agoThere's a pretty big difference between "works incorrectly" and "irreversibly erases important data."
- BlackjackCF 9y agoGit can totally screw you over if you're learning and you're not careful. But what's nice is you can also (usually) revert your Git oopsie. Still, I don't usually run into the problems described because I try to keep Git as simple as possible.
- stephengillie 9y agoBack in 2013, I was working for one of Redfin's competitors, near Redmond. We were moving the developers off VisualSourceSafe, and the DevOps expert (hired at the same time as me) was a Git pro, so we tried Git. Git lasted almost a week. The last straw was when a junior developer accidentally deleted the main line repo. We switched to TFS and never had problems like that again.
- notheguyouthink 9y agoGit wrappers are interesting things. I know a lot of people dislike them in concept.. but strangely enough, I like them in concept. I'm far from a git expert, frankly I'm just barely literate, but I firmly believe there must be a more simplified UX for Git. Again, never to prevent normal usage, but to focus on educating the various states of git, and really trying to make the commands very obvious for normal use cases. I see so many of these.. I'm wondering if it's sort of a rite of passage. Maybe I should write my own? I'm sure I'd become more proficient at Git if I did. edit: Since writing this, I think I decided on writing my own wrapper. Specifically, focused on a very small subset of straight forward commands with exceptionally obvious wording and step by step education. I really like the way http://www.git-town.com http://www.git-town.com documents their command usage, so I'll likely adopt that - but with the added feature of providing either inline or copy-paste commands to gain per-step documentation. Explaining the motive behind a command, and why it was used in that case. I also dislike how git-town layers their own UX, as I think an education wrapper's goal should be to improve education on normal git flows, not make new ones (automatic syncing, etc). Wish me luck lol.
- davexunit 9y agoI rarely ever use the Git CLI anymore. Instead, I use Magit, an Emacs extension. It is, hands down, the best Git tool available. Things that are cumbersome on the CLI become painless, like staging hunks of files, interactive rebases, viewing a blame of the file I'm currently looking at, quickly amending a commit that isn't the current HEAD, reverting parts of commits, browsing stashes, partially applying stashed changes, and much more. It is the single best tool I use every day aside from Emacs itself. https://magit.vc https://magit.vc P.S. - to those worried about what git wrappers are doing behind the scenes, in Magit you just press `$` to see the command log.
- throwanem 9y ago> quickly amending a commit that isn't the current HEAD How? I use Magit too, and my go-to method for doing this would be an interactive rebase that only modifies the target commit. I'd love to know about a quicker way!
- michael_storm 9y ago> Today, I specifically want to call attention to two commits by the lead maintainer of Git, Junio Hamano, that left the deepest scars. Why call the maintainer out by name (and continually do so throughout the essay)? What purpose does that serve? To embarrass him for volunteering his time on an open source project that you've built your business on, just because you didn't like these two features he added? There was no personal behavior of his at play; he simply made some technical choices you disagree with. Keep it technical, dude. This is ad-hominem and smug.
- GreaterFool 9y agoAgreed. I found calling out the maintainer weird and awkward.
- collinstevens 9y agoDid either of you read the section at the end entitled "You or I might have done the same thing"..?
- danso 9y agoThat empty, rhetorical cliche doesn't mitigate the way the author calls out the maintainer in such an abrupt and unneeded fashion in the first paragraphs. The author hadn't even described the problem before blaming the person; instead, were just told that git has 2 self-inflected, deep "scars", and that a single person, and by implication, that person's poor decision-making, is to blame for those scars. Naming the maintainer would make sense later on when the author purportedly tries to get into contact with Hamano but, spoiler alert, fails at it.
- my_ghola 9y agoIf anyone might have done the same thing, why call one person specifically in the first place? This just gives the wrong impression and makes that person more reluctant to make changes.
- WorldMaker 9y ago
- ajarmst 9y ago"It's like Unix!" people say. "rm doesn't warn you, either!" Reminds me of one of my common complaints about that response. The difference is that 'rm' doesn't do anything but remove stuff---it removing things isn't surprising. If a command has multiple potential effect types, and only some of them are destructive, then good UI would offer a warning.
- gsylvie 9y agoFor me the UX issue was that I came from "svn" and "svn checkout" is a VERY different command. Obviously this is not git's fault. I suspect git is much easier to learn for those untainted by svn. As for "git checkout branch" and "git checkout -- branch" doing very different things, I find the "--" works well to bump my mental model into the right state, and so in practice I'm never confused about the distinction. It also helps (a lot!) that "git status" teaches us about these modes for "git checkout --" and "git reset HEAD": On branch master Your branch is up-to-date with 'origin/master'. Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: pom.xml Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes) modified: src/main/java/com/bitbooster/FoxtrotHook.java
- CJefferson 9y agoThe problem is the `--` isn't compulsory. Quick quiz, what does: git checkout x/y do? At least: * Reset a file called x/y * Check out a branch y from a remote x * Check out a local branch called x/y
- switch007 9y agoI think a bit of perspective may be required by the author: nothing is perfect, people make mistakes, and to remember the time before Git existed. Moreover, to mention the person's name ~10 times is extremely crass.
- rootlocus 9y ago> Aside: This is when git started performing destructive actions without warning Is there anything truly destructive in git though? Unless there's a GC, you can still recover any unreferenced objects.
- gsylvie 9y agoYou cannot recover your unstaged changes if you happen to toast them with "git checkout --".
- deleted 9y ago[deleted]
- Karunamon 9y agoNot if they were never committed in the first place. It sounds like if you made changes without committing them (new files or modified committed files), and then branch switch, that content is gone with no warning.
- rootlocus 9y agoGit usually aborts any checkouts or merges that destroy the working directory. You can however use `git reset --hard HEAD` (which I aliased nuke) and it will happily oblige.
- hlieberman 9y agoOnly if it's been committed once. If it's untracked when you wipe it away, it's gone.
- deleted 9y ago[deleted]
- colordrops 9y agoWhat does it mean to check out a file from the stage to the working tree? Aren't staged files already part of the working tree?
- ekimekim 9y agoYou can (for example) modify a file, stage it, then further modify it. You now have three copies of your file - the original, the staged version, and the working tree version. A "git checkout -- file" would revert your working tree copy to your staged copy, whereas a "git checkout HEAD -- file" would revert both your staged copy and your working tree copy to the unmodified copy. There are other scenarios but this is by far the most common. The index (aka. staged files) can be thought of as a completely seperate copy of your working tree that can have arbitrary changes written to it independent of the working tree. It's just that in normal usage you're only ever copying to the index (via git add) FROM your working tree.
- whataretensors 9y agoAs a counterpoint, I like both 'checkout' and 'reset' as they are. Changing them for aesthetics would break a lot of scripts. Additionally I find the commands easy to use and remember.
- makecheck 9y agoIt would be nice for a "git 3.0" to introduce a few new commands with consistent separation of responsibilities (new terminology as needed), and deprecate the twisted ones for removal in "git 4.0". Whatever is confusing today will only be worse after more years of piling stuff on top.