
GUM: A better CLI for Git - edave
http://www.saintsjd.com/2012/01/a-better-ui-for-git/
======
acabal
This is such a great idea. I'm using Git for my own repositories and I find
myself doing searches for things like "how to undo a stage" or "how to revert
a file" so often that it almost takes as much time to use Git as it does to do
my programming.

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.

~~~
dasil003
Not that the git UI doesn't leave a lot to be desired, but git has a nice
security blanket:

git reflog

Now you can feel free rebase with abandon.

~~~
barrybe
If you start depending on reflog just remember that changes in there are
subject to garbage collection. Commits can be permanently deleted after they
are 2 weeks old (by the default settings), so that's how long you can depend
on them staying alive in the reflog.

Of course you can always give a branch name or tag to any commit to keep it
alive too.

~~~
angelbob
Two weeks isn't bad for an undo feature.

------
enobrev
This is probably going to be a fairly unpopular opinion, since it seems git
has won the popularity contest, but this is why I've always preferred bzr.
Sure, it's a bit slower, but the interface is consistent. There aren't as many
commands and they generally do the same thing every time. There aren't many
switches on those commands either, besides the necessities, like defining
revision numbers to apply the commands to.

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.

~~~
StavrosK
I used to use bzr too, then I switched to git because of the speed, and then
to hg because git is impenetrable. Still, I miss bzr's ease of use and
features (like any kind of branch you want).

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.

~~~
enobrev
I started out with bzr-git a long time ago for small one-off projects where I
wasn't getting too deep into the process. Well, that's not true, when I First
dug into DVCS, I tried all three, and since I was on windows back then (all-
linux, now), git failed early, as since it didn't have a native windows
version. Later on, when I didn't necessarily have time to learn git due to
short deadlines, I tried bzr-git a few times.

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

~~~
StavrosK
Well, I prefer to work in vim, so the speed with which my VCS does things is
pretty important. Other than that, screw it, I just switched back to bzr. Both
hg and bzr have very good git interoperability, so now I can use whichever of
the three VCSes I like, even for the same working tree (I can have .git, .hg
and .bzr in the same working tree, all updated, and push whichever I like).

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.

------
eridius
Most of this stuff can be done with aliases.

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.

~~~
jamesgeck0
>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)

You'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?

~~~
eridius
Because it will completely screw with anyone who actually wants it in the per-
repo config file. If I'm new to git, and my first usage is on a sample
project, and git prompts me then I'll put in my personal contact information.
But then if I go and start working on my company's git project, it will never
prompt me again and I'll accidentally be committing company code under my
personal email address. And I would be perfectly justified in blaming git's
faulty user interface for letting that happen. At least if I set the config
myself I _know_ I'm placing it in the global config file.

~~~
jamesgeck0
Your use case makes sense, but

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.

~~~
eridius
In the common case, a lack of username/email actually indicates a
configuration error. Blindly offering to set username/email may cause people
to "fix" their config by re-setting username/email when in fact the lack of
this is indicative of some other issue. Sure, _everybody_ sets up git once,
but on the other hand, everybody sets up git _once_. The common use case is,
by far, running with git already configured.

~~~
jamesgeck0
In the absence of a ~/.gitconf file, how is offering to set username/email
more damaging than instructing the user to set them manually?

If the user doesn't think something is odd when the program wants initial
setup info again, there's no helping them either way.

~~~
eridius
If the user needs the prompt to be able to set up user/email, then they're
probably not qualified to diagnose what went wrong with their setup if
something does go wrong. This way they can get help and fix whatever actually
went wrong, rather than just re-setting their username/email and then
discovering later that they lost all of their other configuration too.

Users that are capable of diagnosing what went wrong with their repo are also
comfortable setting username/email in the config.

~~~
Zev
This sounds horribly elitist. You absolutely must use the command line and an
editor in order to use git? Sure, I guess. If you get to spend all day working
with neckbeards.

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.

~~~
eridius
You seem confused. If you want a pretty UI, what the hell are you doing on the
command line? Go grab one of the half-dozen Git GUI apps out there. There's a
few decent ones out these days, and they'll handle things like setting up your
name/email.

~~~
Zev
Where's this rule that just because it is text based means that it has to be
ugly? I seem to have missed the memo on it.

~~~
eridius
You're arguing in favor of having a "pretty UI" _at the expense_ of
functionality. That's absolutely inappropriate for a command-line tool,
especially one that was originally designed for use by hard-core computer
programmers. If you want a pretty UI, go use a tool that wraps Git and
provides one, like I just suggested. Sure, if you want to suggest that Git's
error upon not having a username/email is made a bit friendlier, that's a
reasonable suggestion. But you're suggesting something which would actually be
a negative change for a lot of people (i.e. changing a hard error into a
potential data loss situation).

~~~
sanderjd
Here is how I read this thread - someone links to a tool that wraps git with a
prettier command line UI, you say that you don't need that, here's some
magical aliases, others say but those aren't pretty like the tool we were
originally discussing, you say "if you want a pretty UI, go use a tool that
wraps Git and provides one" ...like the one from the original link? I don't
get your argument, is there a reasonable place for prettier UIs wrapping
common Git commands, or do we all just need to be more hardcore and learn to
write good aliases?

~~~
eridius
Did you even read the OP? There is no tool. It's a blog post with a wish list
for a magical tool that the author wants someone to create. Try reading the
article next time before you go argue in the comments.

------
blumentopf
Why this is needed:

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...

------
Groxx
I quite like the idea, primarily because it would keep actions 'sounding like'
what they affect. stage and unstage being the primary examples. Yeah, 'add'
and 'reset' work, and fit other semantics, but when everything else refers to
something you've added as something you've staged? Unnecessary cognitive
friction. Add is largely useful for migrating from CVS/SVN/etc, but why not
both with some porcelains?

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.

------
davvid
While this may be a nice idea, I don't know if it improves the situation.
Improving the situation means tackling the entire problem, top-to-bottom.

[http://thread.gmane.org/gmane.comp.version-
control.git/18582...](http://thread.gmane.org/gmane.comp.version-
control.git/185825/focus=185863)

[http://thread.gmane.org/gmane.comp.version-
control.git/17506...](http://thread.gmane.org/gmane.comp.version-
control.git/175061)

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
--'`.

~~~
falling
_> While this may be a nice idea, I don't know if it improves the situation.
Improving the situation means tackling the entire problem, top-to-bottom._

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.

~~~
nknight
> _To me, git feels like building blocks that you use to create your own
> versioning system and workflow_

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.

------
alwillis
Such a good idea. I mostly use Mercurial, which has a clean, logical and
consistent CLI which I like a lot. And while I like the _concept_ of Git,
using it makes my head hurt.

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>.

------
skrebbel
I expected much more from this, off the title.

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/>]

------
chocolateboy
This already exists. It's called EasyGit:

<http://people.gnome.org/~newren/eg/>

~~~
hp
Elijah has a nice detailed breakdown of the EasyGit UI rationale as well:
<http://people.gnome.org/~newren/eg/git-eg-differences.html>

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.

------
beggi
This is pretty nice. I totally concur with the post, and I think logical
commands is the biggest (only?) benefit of Mercurial over Git... been using
Legit by Kenneth Reitz lately... I recommend it highly
<https://github.com/kennethreitz/legit>

------
dave_sullivan
I've seen a few "better CLI for X" applications lately, I think there might be
something there. Personally, I almost prefer cli at this point for lots of
stuff, but a lot of it is still just so cryptic. It doesn't need to be.

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?

------
moe
I think "git undo" would be even nicer if it was a generic undo and simply
undid the last operation (only when possible of course; unpush might be
slightly problematic).

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...

~~~
akg
Agreed! Treating submodules as their own git repositories is a neat and
powerful idea, but the UI really does breakdown. Especially when adding a
trailing "/" to the submodule name like: 'git add submodule_name/' will assume
you are deleting it and adding the files recursively in the parent project.

------
zmanji
Is it possible for all of these to be implemented as git command aliases?

~~~
DrCatbox
Yes, this is what alias is for. You want a git unstage but cant remember what
it was? Alias.

------
DrCatbox
Where is this GUM or better cli for git? All I see is a README file containing
the same thing as the webpost. Not to be a complainer, but there may be a
reason the commands are the way they are and you cant simply change them
without changing the implementation, perhaps you should look at alias to solve
your memory problems.

~~~
dholowiski
Is there a reason, or was this just the way the commands evolved? If there is
a reason, this would be the perfect time to point it out. Otherwise, what's
wrong with improving the UI for everone?

[edit] but yeah, where's the code?

------
matthewsnyder
.gitconfig is your friend: <https://gist.github.com/1706237>

~~~
literalusername
That looks useful, but some comments would be nice. What do u, ud, and prep
do?

~~~
matthewsnyder
`git u $branch` checks out $branch, updates it against whatever remote it's
synced to, and then attempts to rebase the current branch against it. `git ud
$branch` does the same think, except it also performs the merge of the current
branch onto $branch.

`git prep` Simply greps the commit for use of Python/JS print debugging
statements, things that shouldn't make it into the codebase.

------
akkartik
I recently discovered that creating a script called git_command somewhere in
your path makes this work:

    
    
      $ git command
    

Now these recommendations are easy to implement.

~~~
JadeNB
Some experimentation suggests that it's actually `git-command` (with a hyphen,
not an underscore). This is consistent with the man pages, where, for example,
one asks for `man git-add`.

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.

~~~
akkartik
Oops, that was a typo.

------
jmccaffrey
I'm not sure I agree that it's necessarily bad if the interface is a side-
effect of the implementation. It seems very worse-is-better to me.

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.

~~~
hp
That said, I'm not sure UI matching the implementation is the problem with
git's UI; it's more that git's UI is inconsistent, has poorly-chosen names for
commands/options, and has bad default behaviors.

------
phzbOx
One problem of that thought it that it will make git commands even more
obscure. I.e. when a user will have to use the real git cli, they will be
totally lost. I'm not saying it's a bad idea, just something to think about
when designing the new cli. Maybe try to stay consistent with the commands
while still making them easier to remember and understand. For instance:

    
    
      git diff STAGE HEAD 
    

seems a bit unconventional to me.

------
jsmcgd
Can I suggest that 'select' is used instead of 'stage'? After all, one is just
selecting the files to be committed. Staging, although a legitimate use of the
word, is a bit abstract I feel. I can't imagine anyone failing to understand
the concept of selecting something.

------
freshlog
Make this even more intuitive by wrapping git (or gum) in a REPL:

<https://github.com/defunkt/repl>

I use this on a daily basis to avoid having to type "git" repetitively.

------
reinhardt
Cool, I might try this to give Git a second chance, for now I am resorting to
hg-git whenever I have to touch a git project. Sometimes it gets confused when
I'm rewriting history on the hg side and pull from the git upstream but
overall having a sane UI I feel confident about without googling before every
command (or worse, limiting myself to a "safe" subset and using it almost like
Subversion, as some of my coworkers) outweighs the occasional snafu.

~~~
jrockway
Two things to remember about git: Once you commit something, you can always
get it back via the reflog no matter what git commands you type. The second
thing, you should expect to have to Google before every command if you want to
understand _any_ software in detail. It's like saying, "I refuse to learn to
play the piano because I don't already know how to do it." Well, yes. Listen
to the radio then, but don't whine about how the piano has a terrible design.

------
pjscott
This is similar to what I get with magit-mode in emacs. It's pretty slick.

<http://philjackson.github.com/magit/>

~~~
pbiggar
I came to post that. Magit has a very similar way of thinking about things,
with commands being 'stage' and 'unstage' and a very simple revert, and nearly
all commands work on chunks as well as on entire files. Nearly as much of a
step up as using git was in the first place.

------
DannoHung
All I want for git is a "git motd" command that teaches you a little bit of
the plumbing every time you run it.

And I will set it to execute when I login on a shell.

------
bryanp
I've noticed that making the mental switch from writing code to committing it
costs quite of bit of time throughout a day of development. A more intuitive
interface would remove the need to make the mental switch. This interface
feels much more intuitive to me -- great job.

------
cleverjake
There is no code on github

<https://github.com/saintsjd/gum>

but the idea sounds great!

------
meemo
I like the instructions in git status. I usually follow them when I'm not sure
of what to do.

------
ww520
git status usually has a help command to unstage the change.

------
alinajaf
I'm going to put my grumpy old man hat on for a second and say that if you
don't understand how git works, then you shouldn't be using it. Go use svn or
hg or something that has a simpler internal model, and good luck to you.

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.

~~~
rcthompson
I can appreciate the sentiment that Git's internal model is straightforward
enough that the UI is justified in exposing it. However, you also have to
consider the perspective of someone who sees a cool project, decides to
contribute code, sees that that the project code is in a git repo, and says,
"Ok, I'll learn the basics of git so I can contribute to this cool project."
It's not fair to expect such a person to learn the whole data model of git and
how all the commands map to it just so they can contribute a 5-line patch in
the project's native VCS. So I think there's definitely a strong argument in
favor of providing a porcelain for Git that is independent of its plumbing,
even if that porcelain is only capable of some basic operations.

~~~
alinajaf
In that particular case, I'd be inclined to send over the patch as a diff
file, though I can see the point your making.

~~~
rcthompson
Even if you just want to send a patch, in order to get the patch you need to
run diff on the original file and the changed one. If you've already edited
your copy, then in order to get a copy of the original you're back to either
figuring out basic git usage or hoping that the source repo provides a web
interface from which you can download it. Either way, without knowing how to
use git the prospective contributor could easily get discouraged and give up.

