GUM: A better CLI for Git
saintsjd.com
saintsjd.com
No doubt Git gods who have every nuance of the system memorized can take advantage of the flexibility of the (IMHO) complicated and obtuse CLI. But for schmucks like me who just want to get work done and not worry about it, something like this would be a godsend.
I've more than once thought about switching away from Git just because I'm scared I'll do the wrong command and mess something up--and I've been programming for 15 years.
git reflog
Now you can feel free rebase with abandon.
Of course you can always give a branch name or tag to any commit to keep it alive too.
From what I understand, it's not even that. It's learning the plumbing.
If you check the videos and presentations of the Github guys (mostly schacon), 90% of what he talks about are the implementation details of Git as an object store and the plumbing (the plumbing is the low-level commands dealing pretty directly with the repository's storage formats, porcelain is the set higher-level commands implemented in terms of plumbing).
Why does he do that? Because the porcelain, git's high-level CLI, makes no sense in and of itself. It's inconsistent and weird and ugly and fraught with peril.
But it makes sense in terms of the plumbing, if you know what happens "under the hood" you can make sense of porcelain commands: it remains dreadful, but now it's just a bunch of shortcuts for the sequences of low-level operations you know about.
(as far as I'm concerned, I don't have the patience or the care for git's plumbing, so I just use hg and hg-git to interact with git repos)
There are no git gods. They are just mere mortals who read the manual and look divine in the eyes of fools.
I started using git about 6 months ago, primarily for github, and it's obviously a very powerful tool. Unfortunately, all that time that is generally saved by git's speed gets sunk into browsing around trying to understand how to use it. I have about 15 git projects right now and I still have no idea how to do some of the simplest things with git.
Maybe it's just because I came from years of svn, but I pretty much had bzr's interface figured out within a week. That whole week, I searched around for commands and whatnot and since then, it's been Incredibly rare for me to wonder what commands do what.
I'm not saying you should switch, as git is certainly an incredible tool. But if you live your life in the CLI, I would recommend trying bzr out. The simple interface is a dream in comparison.
Personally, if it weren't for github, I probably wouldn't use git at all for my own projects. That said, I may end up switching to git Because of github. And that's pretty much the only reason. Git's won the popularity contest an hence has a far larger ecosystem. But if I do make that switch, and that's a huge "if", I would miss bzr's CLI about as much as I miss childhood.
I don't know why it's not as popular, it certainly deserves to be. I've had more frustrations in my short stints with git and hg than I ever had with bzr, and I don't think it's just because I know it better. For example, hg just pops up a vimdiff window for updating and then just leaves me stranded in a place I still don't know when I :q it in fear. bzr just gave me three files, .base, .mine, .other and left me to do whatever I wanted with it and commit whenever I'm comfortable.
I might just switch back to bzr again, I'm certainly losing more time now than I used to lose waiting for bzr to do its thing, and maybe it got faster now.
About git, why not use bzr-git? It worked wonderfully when I was using it.
I don't have _real_ answer, besides that it doesn't "feel right" to use another tool on a git repo. I _want_ to know git better. It's just not very easy to learn without fully committing to it.
As for bzr, there have definitely been speed improvements in the past couple years. I can't say how much faster, as I'm used to it. The Only times I notice things running slowly are when branching a large remote repo for the first time and when my system is completely maxed (currently working on a dynamic video-generation project). Otherwise, I barely notice. And besides, how often does one actually wait for a return prompt when checking in? `bzr ci -m "whatever"` and alt-tab back to whatever I'm working on.
* editing for clarification
I'm already enjoying bzr again, though. I also would like to learn git, but I have a startup to launch, and I don't think git is worth the (pretty big) effort at this stage.
git stage
git config alias.stage '!f () { if (( $# > 0 )); then git add -- "$@"; else git add -u; fi }; f'
git unstage git config alias.unstage 'reset --'
git undo is too ill-defind to actually implement. Sounds like the author wants it to be `git reset --hard HEAD`, but it's far more dangerous doing that while termed `git undo` than it is while termed `git reset --hard HEAD`, because people will have unrealistic expectations of what it does.What's wrong with `git rm`? Here's a hint: you don't need to use it. Most people I know just delete the files however they want, and then run something like `git add -u` to pick up the deletions. That's exactly what the author is suggesting, but that's what people do today, so I don't see the issue.
As for git status, there's already a --short (or -s) flag that gives a very terse output. I personally use that all the time with an alias `git config alias.st 'status -sb'`.
Automatic setup? Put that info in the global config file. If git had to prompt for it, it would naturally place that info in the per-repo config file (absolutely would not make sense to automatically modify the global one), and it would be more confusing to users to be constantly re-prompted for name/email (because they switched repos). I don't see the problem with just telling new users to set up name/email globally, which every git tutorial I've seen does.
git switch
git config alias.switch checkout
For git diff confusion, just use aliases for different commands. Do not make me type STAGE, that's no friendlier to users. I personally run with the following two aliases: git config alias.staged 'diff --cached'
git config alias.unstaged 'diff'
though I rarely use the `git unstaged` command. I also have git config alias.both 'diff HEAD'
though I never use this one. Perhaps other names can be chosen that the author likes better.The bit about deleting branches is misguided. `git remote` is a command that has sub-commands. `git branch` isn't. I understand that the author thinks having two styles of commands is weird, but there's not really a good alternative. Commands like `git remote` that have sub-commands would not work very well at all in the switch model (for a pathalogical example try to imagine what `git svn` would look like this way), and switch-based commands, which is most commands in git (and most commands in UNIX in general) would not do well in the sub-command model.
git rewind
git rewind FILE
git rewind --revision=REVISION
git rewind FILE --revision=REVISION
We already have the "fast forward" metaphor. git config alias.rewind resetYou're thinking of implementation details, but prompting for and placing the info into ~/.gitconfig is what a newbie git user almost always wants. What's wrong with doing this?
1) Git's current initial setup UI would not prevent the user from making that mistake. It might make them feel stupid when they remember, but that's not the same thing as usability. The commit interface displays your identity and might throw up a red light.
2) Having made this mistake, a new user isn't going to remember the "git config" or "git commit --amend" commands they copied when prompted (if they remember entering them at all; I didn't remember exactly how initial setup worked). They're going to have to go look them up anyway.
3) Every user of Git will have a global username/email. Not every user will set them on a per-repo basis.
I guess I'm wondering why Git inconveniences everyone in deference to the less common use case.
If the user doesn't think something is odd when the program wants initial setup info again, there's no helping them either way.
Users that are capable of diagnosing what went wrong with their repo are also comfortable setting username/email in the config.
For the rest of us, having a pretty UI helps. And I don't see how is being user friendly and offering to just do it can ever be a bad thing. Especially when the alternative is forcing people to figure out how a config file works. Should it be in ~/.gitconfiguration? ~/.gitconfig? Whats that . mean? That ~? A typo'd and it gets made it in ~/.gticonfig..
I have some stuff in my gitconfig that I like having, but, would never be able to figure it out if someone didn't A. tell me what to do or B. make a script that did it for me. And no, I didn't enjoy reading dozens of git manpages to try and find what I wanted. It really sucked.
Your posts remind me of typical Linux-on-the-desktop-defending posts that claim Linux's usability is just fine. Making X.org work isn't difficult, just run these 4 incomprehensible commands, edit this configuration file and insert this snippet for which you have to read a 50 page manual to understand. It's easy! What, can't do it? Then you're not deserving to use Linux, but Linux is oh so user friendly! (disclaimer: I love Linux, I want it to succeed on the desktop, but this kind of attitude is helping neither Linux nor Git)
What's more, most users are going to end up setting user/email as instructed via a tutorial before they even try to make their first commit. The case of someone trying to make a commit with zero configuration while not following a tutorial is a relatively exceptional case.
And you know what? The entire premise of the argument is flawed. I just tested. If user/email is not set up, git will infer your name and email from your username and hostname. It's almost certainly going to be wrong, but it'll let you continue on your merry way without giving the obscure error that was suggested.
1. You edited it by hand and fucked up the syntax. In this case git could print an error instead if offering to add the username/email.
2. You deleted itself. When git asks you for the username/email again it'll actually tell you that that file was for storing the username/email.
3. Filesystem error. A faulty gitconfig with be the last thing the user is worrying about.
All in all I don't see how all of this would imply that prompting a username/email isn't a good idea.
Latest blog article over at progit.org: "Reset demystified" http://progit.org/2011/07/11/reset.html
Scott Chacon, author of the the Pro Git book, admits there that he didn't cover the "reset" command in depth in the book because he didn't fully understand it. Go figure...
That said, take the time and learn what git does and how it works and it makes a ton of sense. It's remarkably simple, and then the commands map directly to what you're doing to your history, which is utterly fantastic.
http://thread.gmane.org/gmane.comp.version-control.git/18582...
http://thread.gmane.org/gmane.comp.version-control.git/17506...
Quoting Junio, the git maintainer:
"""Rc or not rc, just repeating a fuzzy and uncooked "idea" around phoney ref-looking names that will end up confusing the users, and selling that as if it is a logical conclusion to "we want to give an easier to understand UI", without presenting a solid user experience design that is convincing enough that the "idea" will reduce confusion will not get us anywhere"""
Here's the first example from the blog post:
# Why not replace things like: git reset HEAD -- file with:
> git unstage
What the author fails to realize is that you could have just said, "git reset file", which makes this `unstage` example much less convincing.We actually do not recommend `git reset --hard` very often these days. `git checkout -f` is nicer alternative and is semantically related to `git checkout file`.
The 'stage' alias that adds and also understands deletions is a nice addition. It can be implemented as an alias. `git config --global alias.stage 'add -u --'`.
First you have to define the problem.
To me, git feels like building blocks that you use to create your own versioning system and workflow: you learn the tool, you discover which features are useful to you and you use only those. Another person (or group) will use a different process and a different set of features, effectively creating a different version control system.
So, in my opinion, git tackles the problem of being the foundation to a wide range of different VCSs, and does a pretty good job at that.
Something like this is tackling a similar problem to git-flow. Tools like this, with less features but that define or suggest a workflow are very useful, because they remove the confusion while you learn the tool and try to create your workflow at the same time, without knowing what the tool can do for you.
That's because it is almost exactly that. It helps to go back and read the earliest discussions of it.
Linus didn't build a version control system. He never really intended to. He built "gitfs" and equivalents of mkfs, fsck, cd, rm, mv, cp, and a thousand other tools for manipulating it.
Unfortunately, they were also built rather specifically to Linus's mental model and the kernel's workflow, so they look pretty funny to everyone else.
It's getting better. The git of 2012 is a lot friendlier than the git of 2005. But the impedance mismatch between what Linus was building and what the rest of the world expects is a long way from being eliminated.
I'm reminded of the article that compares the two: Git is Wesley Snipes; Mercurial is Denzel Washington: http://www.ericsink.com/entries/hg_denzel.html.
Look, Git is a major pain in the ass because it's designed to support every possibly imaginable workflow. The only way to do this is to just expose Git's internals, i.e. make users think like Git, instead of making Git think like its users. This fits the minds of kernel hackers perfectly (they think like computers do all the time), so there's your history-of-Git in a one-liner as a free bonus.
The only way to make Git more usable is to make a frontend that carefully and in a well thought out way enforces a certain workflow. It'll be more usable for people who use that workflow, then (and, obviously, less usable once you want to step outside that workflow)
git-flow [1] is a nice example of this. I'd love to see more examples for additional workflows. I'm also very curious whether it's possible to do this without leaky abstractions, i.e. to really have a team up and running that doesn't understand anything about Git, and only understands the workflow. Did anyone using git flow manage that? (i.e. have devs never touch 'bare' git)
[1][http://nvie.com/posts/a-successful-git-branching-model/]
I've been using EasyGit for years, it's very good and addresses exactly the complaint made in this article. Plus it's a one-file script so it's simple to drop it onto whatever computer you're using.
Thinking about usability doesn't have to be limited to web apps, and it's refreshing to see some people starting to agree.
Edit: definitely not sure where a business would be for a product like that, such a niche market, and a market that doesn't like paying for things. But who knows?
Also I'm really tired of messing with ~/.gitmodules and unwieldy *submodule-commands that demand to be executed in the project-root all the time. Why can't we simply "git add" sub-repositories, perhaps bailing with a warning by default and an extra-flag to really do it...
[edit] but yeah, where's the code?
`git prep` Simply greps the commit for use of Python/JS print debugging statements, things that shouldn't make it into the codebase.
$ git command
Now these recommendations are easy to implement.EDIT: Not to take away from this handy tip, which I didn't know. I guess one can view it as a sort of souped-up alias.
I feel like when the interface is a side-effect of implementation, you get a more gradual sliding scale from user to developer (like being able to experiment with web apis by curling at them).
In git's case, I appreciate that I can trawl around through my .git directory and not get lost because it pretty closely matches the interface.
git diff STAGE HEAD
seems a bit unconventional to me.https://github.com/defunkt/repl
I use this on a daily basis to avoid having to type "git" repetitively.
And I will set it to execute when I login on a shell.
https://github.com/saintsjd/gum
but the idea sounds great!
For me, gits internal model is simply not that hard, and I'm a run of the mill twenty-something year old developer who feels vaguely guilty about not knowing how fundamental data structures and algorithms work. It's a directed acyclic graph that points to items in a content addressable database. Between the progit book and the man pages, I had a pretty good conceptual model of it in an afternoon. I encourage anyone who actually wants to learn it to spend a little time with TFM and get it out of the way.
Otherwise, seriously, quit your whining. The CLI makes intuitive sense to me and I can manipulate the DAG without much mental effort. The worst case scenario is that you rebase public history, and `git help rebase` will tell you how to get yourself out of that mess.
Similarly, you don't program C just so you have to learn assembler and how a CPU works. Yes, if you do you can do awesome things, but that's not the point, that's a bonus.