

Git needs a new interface - r11t
http://blog.reverberate.org/2009/07/30/gits-needs-a-new-interface/

======
dlsspy
> You can’t merge upstream changes into your local, uncommitted modifications

No, you can't, and I'd be horrified if I ever worked in a system that did that
again.

First, there's never an excuse to not commit. What you commit is not
necessarily what you publish. rebase -i to clean up artifacts of the junk
you've done if you're worried about it (I always do it that way).

But more importantly, when I pull code and what ends up is _worse_ than what I
had before, I'd like to go back to where I was.

~~~
Oxryly
Agreed. I avoid merging (potentially extensive) outside changes/commits into
my modified local files. It always seemed like a risky and unwise procedure in
CVS and Perforce.

I think Git's alternative of stash, pull, pop is an improvement. That way I
can fix conflicts properly at each stage, and handle big changes before
reapplying my hacked up stuff.

------
stevejohnson
While I agree that git's error messages can be unhelpful, I still think that
this guy is using git improperly when he tries to "merge upstream changes into
your local, uncommitted modifications."

A huge motivation for using a DVCS is that you can commit as many times as you
want without worrying that your in-progress, hacky changes will affect someone
else's work. Combined with git's powerful branching, you should _never_ have
an excuse not to commit a change set before a merge.

Also, he whines about not being able to merge with uncommitted changes, and
then gives an example of how to do it! Ridiculous. It's three intuitive
commands. That's what stashing is for.

I do agree with his points about git reset. The args are very confusing.
Reverting to the most recent commit should be more intuitive. However, these
arguments do not in any way point toward a need for an entirely new interface.

~~~
moe
_However, these arguments do not in any way point toward a need for an
entirely new interface._

No, but the sum of the arguments does.

I'd wager that most git users feel that the UI is more complex than it should
be and outright hostile in many situations. The problem is that not many
people are deep enough into all the concepts to make a coherent proposal for
something better. And those who _could_ often don't see the problems anymore
because it's just the way it is for them (can we coin the term VCS-blindness
right here?).

It's sort of a chicken/egg problem and hard one.

I, for example, am not exactly happy that my standard procedure for pushing
changes upstream has to involve 7 commands and two rebases. But so far I've
had neither the time nor the insight or motivation to come up with something
better. My general feeling is that git is still exposing itself at too low a
level. That's also the reason why so many people are using it "wrong" (wanna
make a bet on how many projects on github consist of only a master-branch
where everything happens?).

Consequently my best stab would be that git could perhaps use a bit syntactic
sugar for the most common workflows. There are not so many of them after all -
why does almost everybody have to repeat the same 7 commands every day?

------
davepeck
I often refer to Git as "software of cruelty." I use it daily and sometimes
still end up shocked by its behavior.

The concepts underlying git -- a content-addressible filesystem, trees,
commits, etc -- are elegant. They're nearly pure. The "front end" exposure on
the command line? Not so much.

~~~
aaronblohowiak
You can write your own porcelain, if you please. It seems a lot of people
would like it, actually.

~~~
davepeck
Yes, it might be a good project. Are you aware of any other porcelains that
have traction these days?

~~~
aaronblohowiak
sadly, no

------
jrockway
This article had a lot of potential, but misses the key points.

What this article should say is:

1\. Git needs a shared-library interface, so that interfaces to git can be
built without quoting and parsing (the two most error-prone operations in
computing).

2\. Git's default scripts are a mix of shell, perl, and C that all parse
command-line options in their own unique way. Eventually you find what works,
but it's by random experimentation rather than by noticing patterns.

3\. Git's default scripts are bloated. Quick, how many different ways are
there to rebase ("git rebase", "git pull --rebase", ...) or fetch ("git
fetch", "git remote update", ...)? Since the code is not necessarily shared,
these operations may not even be exactly the same... just mostly the same.

Basically, git is the best version control system available -- but that
doesn't mean it's not a software engineering nightmare. It is.

("So why don't you fix this?", you ask? Easy: git works so well that this
theoretical annoyance is very low on my list of things to fix. In a perfect
world, all software would be beautiful snowflakes. In the real world, there's
always something that needs even more fixing.)

~~~
dlsspy
> 1\. Git needs a shared-library interface, so that interfaces to git can be
> built without quoting and parsing (the two most error-prone operations in
> computing).

Every special tool I've ever wanted to create in git I've been able to do with
pipes in either shell scripts or python scripts using data export options
generally used by the porcelain.

People have built good APIs on top of this, and in a few cases built direct
object access interfaces, but I stopped thinking library access was important
when I started actually writing tools.

------
ErrantX
Without wanting to add fuel to the fire (really), I always think Git tries to
do far too much. I think SCM should just gracefully version your code in as
simple a way as possible.

I went from SVN to Git a while ago and it was a great improvement. Then a
friend pointed me at mercurial and I just felt it was a revolution. Finally my
code felt portable.

With all that said Git has some great tools for large and complex projects
with many contributors.

The one thing that sells HG to me though is it's insistence on non-
destructiveness. If you made changes to files it always reminds me to merge
changes properly without overwrites. I cant recall how many times that has
saved me a n hours work :)

~~~
masklinn
FWIW, if you want simple (as far as concept & interface go anyway) check out
darcs. It probably has the simplest, sanest and sexiest (CL) interface of all
modern DVCS (Git, Mercurial, Bazaar, Darcs, …).

Plus because of the concepts behind it, cherrypicking is Simply Trivial.

Of course, the downside is that those concepts generate other issues.

~~~
ErrantX
thanks, I'll look into that.

------
kinghajj
1\. "checkout" is a destructive command

Yeah, so? "checkout <branch>" changes the working dir's files to match those
of <branch>, and "checkout <file>" reverts <file>'s contents to its original.
It's documented and does what it says.

2\. You can’t merge upstream changes into your local, uncommitted
modifications

Why not just commit your "hacky" modifications onto a local branch? The great
thing about Git is that your commits/checkins don't have to be perfect, since
no-one else can see them until pushed/pulled/merged anyways.

3\. Git’s merge conflict resolution workflow is unintuitive

If you've used Git at all, you should be comfortable with the fact that you
need to "git add" files before you "git commit" them. Resolving changes is no
different. "git add" each conflicting file and then "git commit".

4\. Interface for working with the index almost universally confusing

Maybe you have a point there.

I'm actually using Git GUI a lot more than the command-line now. The only time
I've used the command-line recently is for pruning, which the GUI has no way
to do (it can only compress). Git GUI is pretty friendly.

~~~
mr_dbr
The git checkout [filename] behaviour always confused me..

Yes, it's documented, but git seems to really try and make it difficult to
lose any work.. but has a command that makes it simple to irreversibly lose
your upstaged changes, without so much as a warning?

At least "git revert" sounds like it might undo changes.. In what way does
"checkout" imply both "checking out" branches, _and_ reseting a file to it's
previously commited state?

------
steveklabnik
> …will overwrite any local modifications you may have to foo.c without
> asking.

*NIX commands do things without asking. Your computer serves you, not the other way around. If I wanted my computer to double check everything that I do, I'd run Windows.

"(y/n/a)" just leads to awkward shell scripts.

~~~
mhansen
Put a '-f' in your shell script, to force the overwrite

~~~
steveklabnik
Why don't you put a '--double-check-my-command' on yours?

~~~
mey
There is such a thing are reasonable defaults. This is an issue of command
lines as interfaces and as tool integration points. You have reasonable
defaults for both audiences. (My preference is the err on the side of the
human interaction because CPU's are cheap)

~~~
jwhite
Git is unashamedly a power tool, for power users. Git checkout seems so
natural to me in the way it functions, and I use it so often, that it would
annoy the hell out of me if I had to force it or answer a y/n prompt every
time I used it.

What you think of as intuitive is not universal. Your reasonable defaults are
unreasonable to me. This seems to be a problem of audience. Git can be
challenging to learn, but it's not aimed at learners. It's aimed at power
users.

As others have pointed out, there are other front-ends to git. You don't have
to use the default porcelain.

~~~
mey
Fair enough

------
mjgoins
The title is a wild exaggeration. The article itself points out many UI gripes
that every user of git runs into. Fixing those gripes would absolutely not
constitute the creation of a new UI.

------
senthilnayagam
git porcelain is not ready for newbies, use tortoisegit or other gui
interfaces.

I dont understand why people should have uncommitted changes for days

Branching is cheap and local, commits are local, no need to expose private
work until it is ready to be merged with master, team accessible branches.

------
technomancy
I use git every day via Magit (<http://zagadka.vm.bytemark.co.uk/magit/>),
which is a joy to use. But every time I have to fall back to the shell for
something nontrivial it just feels so awkward.

------
etherael
> You can’t merge upstream changes into your local, uncommitted modifications

If you're just hacking around, shouldn't the procedure be to have a branch
specifically for that and keep master clean for urgent work?

Confused.

~~~
jwhite
Agreed. Local topic branch for experimental hacks. Rebase it when you want to
integrate upstream changes.

~~~
moe
I have sympathy for the author insofar as some people (myself included) don't
plan ahead that way. Hacking just happens. We try this and that, something
works and gets committed, something else doesn't and gets reverted.

My working copy is littered with uncommited files nearly constantly, simply
because I work and play on many things in parallel and committing _every_ time
I save a file would be a noticable overhead, just as merging between topic
branches all day.

I'm not complaining, we get along, my working copy and I, but I agree in some
situations git could be more helpful than "xxx needs update" - and that's
really just one symptom of many.

I've been playing with mercurial a bit recently (yes, heresy) and can see why
the git guys despise it, it's just not as pure. The main thing that stuck with
me though, is that even though it's roughly comparable to git in terms of
features, it is mindboggingly much more intuitive to use.

Git could take a lesson from that and would not even have to give up much of
the purity. Yes, "everything" should still be possible - but they damn sure
could make the beaten paths a bit less spikey.

~~~
dlsspy
> I have sympathy for the author insofar as some people (myself included)
> don't plan ahead that way.

I don't either. I pretty much always work on master. If I find myself down a
deep path that should've been a topic branch, I make one _then_ and reset my
master back to origin.

> I've been playing with mercurial a bit recently (yes, heresy) and can see
> why the git guys despise it, it's just not as pure. The main thing that
> stuck with me though, is that even though it's roughly comparable to git in
> terms of features

I used hg heavily for a long time before ever touching git. I did a bit of
work on an older project that used hg recently and found myself unable to
figure out how to do something I often easily do in git.

I don't remember the exact details, but I ended up committing and tagging
after doing a "trivial" change that ended up being wrong (I noticed before
pushing). Rather than pollute my public history with garbage, I just wanted to
undo the mess and go back and fix the brokenness and retag.

When I used hg heavily, I was very well-versed with the ins and outs of
mercurial queues for doing simple fixups like this. Not having used it
recently, I had to go to the manual because I couldn't remember which
combination of q-commands would do a simple effective rebase.

I was especially sensitive here because the last time I was a heavy hg user, I
did lose changes to queues because hg doesn't have anything like the wonderful
safety net of reflog to allow me to just put my tree back in a prior stat and
let me try a complicated merge/rebase again.

~~~
moe
_I don't either. I pretty much always work on master. If I find myself down a
deep path that should've been a topic branch, I make one then and reset my
master back to origin._

Well, yes, I also kludge my way through it like that. It just always leaves
that old sour taste of "it should be easier than that".

You know how it goes, the next pull comes along and you better remember to
merge it to all your branches...

 _I did lose changes to queues because hg doesn't have anything like the
wonderful safety net of reflog_

This is an absolutely wonderful example, thanks for coming up with that. Yes,
I know the reflog exists and you can do magic things with it. It involves
commands like 'git reflog show --date=relative HEAD' and refs like 'HEAD@{1}'
(I admit I had to look them up).

So, do you know that stuff from the top of your head? Or how much man-page
wrestling did you have to do before the safety net actually caught you?

My wet dream of a git porcelaine would be different. It would include commands
like "undo" and "redo" and they would do exactly what one expects and warn
explicitly when their little world is not consistent anymore (e.g. an undo
can't be performed because an affected file was modified). So to be clear:
Undo would undo absolutely any operation (within git's ability) and same for
redo.

Ofcourse there are many horrible corner cases to be worked out for such an
truly intuitive command-set to survive reality - but imho a porcelaine grown
in such a spirit would eventually do better justice to the elegance of git
than the "raw API" interface we have now. Oh and while I'm in dreamland, my
dream-porcelaine would ofcourse also max out at 10-12 commands.

~~~
dlsspy
> It just always leaves that old sour taste of "it should be easier than
> that".
    
    
        git branch branch-i-should-have-made
        git reset --hard origin/master
    

How would you make it easier? Why is that kludgy?

> So, do you know that stuff from the top of your head? Or how much man-page
> wrestling did you have to do before the safety net actually caught you?

Uh, no. I type "git reflog" and look for the thing I want. Then I copy the
hash and do whatever I was going to do with it -- the same thing I do in hg
went I look at its logs and want to reference something older.

You are contriving a complex use case of a rarely used safety-net command,
when in reality, it's just not that hard to use. I was listening to an SE at
work introducing another guy to it earlier today when the guy needed to
recover from a mistake he made.

~~~
moe
_How would you make it easier? Why is that kludgy?_

That is not the kludgy part. The kludgy part begins when you have created a
few branches that way and start bringing in changes from upstream, or when the
branches begin to conflict with each other. Suddenly there is housekeeping
involved, merging stuff back and forward.

I just don't understand why git lets me comfortably stage individual hunks (a
feature that I love and use extensively) but refuses to deal with uncommitted
changes as intelligently as with everything else.

I don't _want_ to commit the three spurious lines I just typed into the editor
before going to the bathroom. Yet I'd like to do a quick pull from my co-
worker when I come back, before continuing on those lines and without
commiting my 3 lines first. This is rather contrived again, but it shows the
underlying problem of git not staying out of the way as it should but instead
forcing me to do something completely unrelated to my actual goal - a sure
sign of a bad UI.

 _You are contriving a complex use case of a rarely used safety-net command_

Well, I agree it was rather contrived.

Yet I still wonder how many git users, when asked, could quickly type out the
command to undo their last rebase and how many know, without looking, how to
weasel out of the various follow-up errors that may appear ("Interactive
rebase already started" anyone?).

------
MarkPNeyer
github.com is great for use with git. Disclaimer: I went to high school with
(and am an arch rival of) the founder.

~~~
m0th87
How does it improve on git's interface, besides providing a UI for browsing
the trunk and visualizing merges? I've just started using github, and while I
see the value of git (especially in its branch-oriented philosophy), I always
have to look up how to do even the basics. While I understand git is far more
powerful, I like svn because it 'just works'.

~~~
gecko
You might give Mercurial a shot. It's the speed of Git with a much saner user
experience. Plus, all the power of Git's there; it's just hidden under the
covers until you need it.

Speaking of the examples in this article:

    
    
        hg update
    

allows you to fast-forward without making a commit. The equivalent of

    
    
        git checkout
    

in Mercurial is (roughly)

    
    
        hg update -c
    

which will refuse to update if you have changes. (You can override that with
"hg update -C".)

In the case of merge output, when you've fixed a file, you simply run

    
    
        hg resolve filename
    

You can at any point see what's not merged by running

    
    
        hg resolve --list
    

Notably, if you have a three-way merge tool set up properly, you'll never do
this, because Mercurial will walk you through doing the merge properly as part
of the...well, merge.

~~~
stevejohnson
"It's the speed of Git..."

No it's not. Speaking from experience here.

Edit: Okay, here's some real data: <http://git.or.cz/gitwiki/GitBenchmarks>
<http://whygitisbetterthanx.com/#git-is-fast>

It shows that git wins by most metrics, with a few exceptions. Mercurial's
push/pull format is particularly good.

~~~
davidw
What sort of hit? Is it just a bit pokier or does it get really bad for
anything in particular? Anyone got any actual data?

~~~
axod
>> "Anyone got any actual data?"

Is the _SPEED_ of any revision control system ever an issue? To anyone? Surely
it's 'fast enough that it doesn't matter' vs 'fast enough that it doesn't
matter'

~~~
dlsspy
Yes, when a command takes a couple seconds to perform, you don't consider
doing it unless you have a really good reason.

Classic hg branching came into different forms: 1) a tree clone and 2) the hg
"branch" commands.

1 can be _very_ slow on a large tree and can often require you reconfigure
your tools to go look in a new place.

2 is permanent. Your code now forever references the name of a branch so you
have to stop and think about whether it's really the right thing to do.

In either case, anything that requires me to stop and consider the cost of an
operation makes the operation less valuable. Where that cost kicks in varies
for people. Is it minutes? Seconds?

As a former perforce user, there were _definitely_ plenty of things I wouldn't
do there because they weren't instant. In git, I tend to make decisions based
solely on my desired outcome.

------
superjared
No it doesn't.

~~~
davidw
Why don't you try refuting some of his points? Or else he might come back with
"does too!"...

I'm not overly impressed with git in terms of it doing the right thing by
default. The best options are often sort of hidden away under some option that
you have to remember. svn is much simpler and nicer from this point of view in
that I don't often have to use flags with it to do the basics.

Perhaps the title could be rephrased as something like: "if git hopes to grow
outside the world of early adopters, it probably needs a better interface",
although that's not nearly as snappy...

While we're at it... can anyone:

* Comment on mercurial and bzr from this point of view?

* Comment on TortoiseGit?

~~~
jjames
* "checkout" is a destructive command

Most VCSs have a destructive command. If one doesn't expect the destruction
from the command, they will no doubt be perturbed.

* You can’t merge upstream changes into your local, uncommitted modifications

Commit.

* Git’s merge conflict resolution workflow is unintuitive

Subjective but I'm curious which VCS has an intuitive merge conflict
resolution workflow. I assume this means that without previous experience with
the VCS a developer can (immediately?) intuit the workflow.

* Interface for working with the index almost universally confusing

Three switches for a single command. If you want to operate in a business as
usual DWIM manner you can just remember --hard.

All that said, I do believe git reuses some commands in a semantically elastic
way, sometimes to the confusion of new users.

~~~
davidw
> Most VCSs have a destructive command.

And the name tips you off that you're about to do something destructive. Like
svn's "revert". On the other hand, 'checkout' sounds fairly innocent to me.

> intuitive merge conflict resolution workflow.

IIRC, recent versions of svn walk you through it, asking which one you want to
keep or letting you edit the file(s).

I actually use git (the branches are really nice for some things), but I'm
considering VC systems for office use, and I'm not quite so sure I'd stick my
neck out and recommend git.

~~~
masklinn
> I actually use git (the branches are really nice for some things)

FWIW Mercurial now has git-style branches (called bookmarks, hg's branches are
different beasts)

