84 comments

[ 3.2 ms ] story [ 141 ms ] thread
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.

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.
Is it possible for all of these to be implemented as git command aliases?
Yes, this is what alias is for. You want a git unstage but cant remember what it was? Alias.
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...

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

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.

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.

git reflog is the SINGLE most undersold feature of get. It's a global, perpetual undo function (less garbage collection, which I understand to be discouraged).
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.

Two weeks isn't bad for an undo feature.
> 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.

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)

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

There are no git gods. They are just mere mortals who read the manual and look divine in the eyes of fools.

Did you read the OP? He wasn't complaining about being unable to find the right commands, he was complaining about being unable to remember the right commands after having found them, because they're so obtuse.
.gitconfig is your friend: https://gist.github.com/1706237
That looks useful, but some comments would be nice. What do u, ud, and prep do?
`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.

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

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

Per "git undo", what about something like:

    git rewind
    git rewind FILE
    
    git rewind --revision=REVISION
    git rewind FILE --revision=REVISION
We already have the "fast forward" metaphor.
Interesting idea, though I don't get the need for the --revision flag in your example. It's already pretty easy to tell the difference between revisions and files. If you want to call it unwind, why not just make that an alias for reset?

  git config alias.rewind reset
(comment deleted)
(comment deleted)
Ah, okay. Wasn't sure how well the system could differentiate the two.

You could always make aliases for things, but the point of the article seems to be addressing the problem of people new to git, who likely won't go about setting such aliases, let alone know they have that capability.

And that's a problem I can sympathize with: I'm a programmer on an FRC (http://www.usfirst.org/) team, and this year, we finally convinced everyone to make the jump from a thousand USB sticks to a git repo. We've held a workshop on it and have distributed various tutorials -- GitHub's have been particularly invaluable -- but there are still issues every now and again. Some seem to only have "push button, receive outcome" understanding of how it works, memorizing the commands for cloning, pushing, and pulling and then blindly repeating them into the console, without a full knowledge of what's going on. If some of the more "advanced" syntax was a bit more human from the get-go, then it might be helpful in softening the learning curve.

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

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

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

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.

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.

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.
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.
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).
(comment deleted)
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?
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.
Can you folks who are downvoting me please tell me _why_ you are doing this? We're not on reddit. What I posted is absolutely not deserving of downvotes. If you disagree with me, post a reply.
I'm not the guy who voted you down, but I'm guessing other people did it because your posts' attitude imply that new users are absolutely not worth accommodating for and that usability is not important. It comes over as rather elitist.

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)

You are reading things into my post that are not there. jamesgeck0 was arguing that every single user has to configure name/email, so this is clearly a "common" case. My counter-argument was that every single user has to configure this once. The common case is to be using git in its already-configured state.

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.

I dispute this claim. There are only very few ways your ~/.gitconfig can be corrupted:

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.

Then have git output a message telling the user that the setting is now global. That way you accomodate for both cases in a usable manner.
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...

(comment deleted)
This already exists. It's called EasyGit:

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

Note that the bottom of the above link also links to several other git porcelains designed for ease of use.
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.

It's criminal that more people don't know about/use EasyGit.
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?

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.

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

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.
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.
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.
But I'm not using git so I have to understand how a RCS works, I'm using git so I can keep track of my files!

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.

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

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

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

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

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

I've started using magit and I really like it; I like that I can just say "revert" on a file and magit knows what the right command is. Makes me think a whole lot less about Git and a whole lot more about my project.
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.
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.
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.

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