
Reinventing the Git Interface (2014) - macmac
http://tonsky.me/blog/reinventing-git-interface/
======
shabbyrobe
This is especially funny considering the huge discussion recently about
rewriting curl and then the entire world in Rust, but imagine you lived in a
world where the magical "better tool" already existed and all you had to do
was discover it.

Leaving fantasy-land aside for a moment, this morning you woke up in the real
world. In the real world, that tool _does_ already exist, and it's called
Mercurial.

If you try command-line Mercurial for long enough to get past the initial "oh
no Windows/macOS/Linux got updates and moved all my icons" muscle-memory-
refresh phase (and especially if you last long enough to get into revsets and
templates), you'll find it extraordinarily difficult to go back to using
command-line git. Your power grows with Mercurial as you learn more about it
because you aren't constantly fighting the complete absence of idioms and
opaque "man-page" style of documentation that puts a slab of inscrutable text
front and centre and neglects to provide simple examples for common problems
(apparently we have a perfectly good Stack Overflow for that).

The git boosters will respond to this by saying, as they always do, "yes, but
the _real_ power of git is in the model of the information under the hood. The
CLI is just an interface, if you don't like it you should spend months
studying the internals and build your own workflow on top of git". Again, back
in the real world, who has time for that? Or the interest? Especially when, as
I already mentioned, that tool does already exist and it's called Mercurial
and you can get started with it right now.

Both tools can do close to exactly the same things under the hood with
differences that won't make a lick of difference to the vast majority of
users. The user-facing differences are where it really matters: one tool has
an excellent CLI which is clear, concise and discoverable; the other has
github. Damn. Lousy network effects.

~~~
theamk
The team I am on uses git because we want clean and linear commit history.

This means "master" and private branches are very different:

\- private branches have lots of random commits which no one will care about
once feature is done: "start on feature", "fix typo", "add test", "fix
feature", "add interface to foobar", "fix a bug", "fix it for real", "add
another function to foobar interface".. and so on

\- "master" has a nice, clean history. The corresponding commits would be :
"add interfaces to foobar", "add feature"

This means the developers are actually expected to squash/merge/reword their
commits before submitting to master. The submit scripts also enforce ff-only
merges, so the master is fully linear.

We like this workflow because it has advantages of both SVN -- linear, easy-
to-read history, and of git -- you can commit as often as you want and you can
share your work easily.

Now, we have users struggle with git periodically, but it looks that trying to
use Mercurial in our workflow will be even worse -- most of the Mercurial
references seem to disapprove of rebasing in general. Example:
[http://stackoverflow.com/questions/2672351/hg-how-to-do-a-
re...](http://stackoverflow.com/questions/2672351/hg-how-to-do-a-rebase-like-
gits-rebase)

I understand that this is somewhat unusual workflow; but it illustrates the
power of git. You can have a huge variety of the workflows, while Mercurial
(and many others) push people towards a single preferred one. And sure, modern
hg has "rebase" and "histedit", but they just seem like second-class citizens,
and they are much less polished than git's (for example, histedit's man page
says " If you drop a change, it's gone forever". Scary! I think I will just
use git instead)

~~~
marcinkuzminski
Our team uses Mercurial for exactly the same thing, a clean linear history,
with features like phases, and histedit it's very easy to achieve and works
great.

We use RhodeCode to manage pull requests for Mercurial. This has also a
feature to rebase commits on merge.

------
ursus_bonum
This is such a classic example of not thinking things through.

The graphical manipulation stuff sounds cool until you think about what
happens when it causes merge conflicts. I mean the graph stuff is still cool
but it does very little for the hard problems.

The automatic committing for WIP and "magic" pushing/fetching sounds cool
until someone switches branches and accidentally commits 3.1TB of junk files
they left lying around and it automatically syncs to EVERYONE else on the
project.

People complain now that Git is "too complex" just wait until it's
automagically doing shit like that.

~~~
notgood
Strongly disagree, the software should always list/show the files being
commited in a little pop-up, if you see it is comitting a lot of files or
something very big you should be able to press a "cancel" button; you know,
like a regular OS file-copying dialog works.

~~~
stouset
Having worked with people who use these types of magic GUI tools that "hide
the complexity" of $VCS, this shit happens _all_ _the_ _time_.

When they exist, popups are clicked through and ignored just as they are in
every other computing context. And in the end, these tools are just a
shorthand for "I don't have the time, desire, and/or motivation to understand
how to operate the tools I rely on for work."

Not to argue that that perspective is bad or wrong, it just is what it is. And
when someone doesn't understand a tool that operates an inherently complex
system, it will inevitably lead to misuse.

------
hosh
This is a great UX rethink along actual user needs. It's unusual to see
someone with more-than-superficial knowledge of git that also has enough
product sense to come up with something like this.

My team has varying levels of git skill, including product owners and testers.
I am usually called in to do the git black magic -- and I only know a fraction
of what is available on git. My git magic doesn't scale. Further, because we
are using our dev environment in a VM, a remote client is harder to work with.
Making this web-based would work out very well for us. (And power users can
still use the command line tool instead).

I hope this comes to fruition. My team can sure use it.

------
telekid
magit[0] solves many of the issues identified here. It's the first tool I've
used that makes git feel like a paint brush rather than a camera.

[0] [https://magit.vc/](https://magit.vc/)

~~~
jwr
I've been waiting for someone to mention magit. It is the only UI I know of
that is more than just a git shell. Real thought went into it and it shows. It
is faster and more convenient than the command line, which says a lot.

~~~
cygned
It's still not as fast as vim-fugitive for example. I know magit does more in
nicer ways but the delay when staging, for example, is noticeable and can be
annoying over time.

~~~
dota_fanatic
I'm not sure I follow. I hit s on my file in the Magit buffer and it's staged
instantly; what delay are you referring to?

~~~
cygned
On my machine it takes like 400ms until it's staged. When working in vim,
staging really instant.

------
xenadu02
>You may think auto-sync will completely ruin your familiar “commit now,
restructure later” workflow. It will not. As you’re working in your branch,
you can still reorganise, restructure, reorder and rename commits in your
branch. These changes will be incrementally synced to all other peoples’
machines as you go. They’ll initially see your mess, but then they’ll see all
the changes you’re doing to make your branch look pretty. All happening
without any manual button clicking/remotes selections/any other decisions from
them. As this branch is yours, it’s a perfectly safe and does not require any
human intervention.

One of the biggest missed opportunities with git is metadata about rebase and
history-rewrite operations. If git stuck that information into the log it
would be trivial for clients to understand that these commits appear to have
different hashes only due to a rebase. The client could even compute the
deltas from both tress to compare the supposedly "common" commits, validating
that they really are the same (or maybe allow slightly differences to account
for rebasing). If the commits claim to have the same ancestry but different
deltas it would be up to you to accept your peer's work or to go review/merge.

No more "2 down / 5 up" commits because of a rebase; instead you'd see "3 new
(2 rebased)".

~~~
jcranmer
> One of the biggest missed opportunities with git is metadata about rebase
> and history-rewrite operations. If git stuck that information into the log
> it would be trivial for clients to understand that these commits appear to
> have different hashes only due to a rebase. The client could even compute
> the deltas from both tress to compare the supposedly "common" commits,
> validating that they really are the same (or maybe allow slightly
> differences to account for rebasing). If the commits claim to have the same
> ancestry but different deltas it would be up to you to accept your peer's
> work or to go review/merge.

This is ripe for flaming, but this is how mercurial handles rebasing under
changeset evolution, and it's pretty much the biggest area where hg gets
something right that git got wrong. Basically, it keeps around the old
changeset of the rebase and adds a new kind of edge to indicate the update of
the rebase, as well as keeping the obsolete changesets from being seen by most
users while maintaining them internally. This means that normal rebase
operations can see the old and new versions of a changeset as if they were
regular changesets. Combined with phases, it's also easy to set up your
repositories so that you can never accidentally rebase your master branch.

------
Ajedi32
I'm sure this has been posted before, but regardless it's still extremely
relevant.

It's been almost 3 years now since this article was written, and I've still
yet to see a git UI which is anywhere near as good as the one proposed here in
terms of functionality and UX.

If a GUI like this is ever implemented, I might finally be able to use
something besides the CLI for my git client.

~~~
inetknght
Git has `git log --gra.....` actually no nevermind that's far too obscure and
useless. Just use `tig`. TUIs are generally more useful than GUIs in my
experience anyway.

~~~
Ajedi32
> Git has `git log --gra.....`

I have an alias `git lg` which does basically that. The only problem is that
once I run that command and have that nice, pretty DAG, I can't manipulate any
of those commits directly; I'm stuck manipulating the commit graph indirectly
by typing out commands and copy-pasting commit hashes into the terminal. A
decent GUI like the one described in this article would fix that.

~~~
hdhzy
Ha, I also use that alias. Simple operations can be done directly in gitk
(moving branches etc.) but a real solution that'd make `git lg` editable would
be an incredible boon.

------
rjmunro
I recently discovered the magical incantation:

    
    
        gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )
    

which show's all the git commits in the repository, even those that are not on
any branches any more.

It's perfect if you need to find an old commit to undo a rebase, or if you
accidentally deleted a branch. It really should be a button in GUIs called
"show all commits" or something". I even posted a bug in gitx suggesting they
add the feature:
[https://github.com/gitx/gitx/issues/78](https://github.com/gitx/gitx/issues/78)

Source:
[http://stackoverflow.com/a/91795/3408](http://stackoverflow.com/a/91795/3408)

~~~
mdns33
have u heard about tig? try it

------
falsedan
> _You may have noticed that Git warns you a lot. Rebase is dangerous,
> headless state is dangerous, don’t do push -f, are you sure, think twice,
> you’re not supposed to do that, stuff like that_

Hmmm…

> _Remove warnings as Git repo is immutable and cannot lose data_

Ok this is a great response!

There's also this wishlist/proposals for git log[0], which are extremely
exciting to think about; it's from 2012, so even older than the article…

[0]:
[https://gist.github.com/datagrok/4221767](https://gist.github.com/datagrok/4221767)

~~~
xyzzyz
It's not completely true, you can easily lose data in Git by accident. Here's
an example. Suppose we have a single "master" branch, pointing to commit A.
You create a new "feature" branch, making commits B, and then C. You realize
that B and C are actually unrelated, so you want each of them to have separate
branches. You git rebase --interactive onto master, picking only commit C.
This way feature branch has commit C with parent A. Now, you git checkout
commit B, which should put you into detached HEAD state, from which you plan
to create a second feature branch. Alas, something has triggered git gc in the
meantime, and commit B has been garbage collected, as it was no longer pointed
to by anything.

Something like this happened to me, breaking the whole Chromium repo for half
an hour. Definitely not fun.

~~~
dota_fanatic
> _You git rebase --interactive onto master, picking only commit C._

So during an interactive rebase you drop one commit, and pick the other, then
are upset at git for dropping your commit? It did exactly what you asked of
it.

This would have easily been avoided if you had branched off your feature
branch into a new one and did the interactive rebase there. Your old feature
branch is still present, which you could rebase interactively, or drop HEAD so
you only have the other commit, or whatever other thing to meet its needs.

~~~
xyzzyz
Sure, I know now exactly what happened, and what I should have done in order
to avoid it. My point here is that "Git repo is immutable and cannot lose
data" is a lie, and people who believe it (like I did at the time -- hey, if
anything breaks on rebase, I can always git reflog and reset to good state,
right?) will have a bad time at some point down the line, so it's better to
stop this lie from spreading.

------
Djabx
Hi, Have you given a try to: [http://gitup.co/](http://gitup.co/) There not
everything you wanted, but maybe...

~~~
macmac
gitup looks neat, but unfortunately macOS only.

~~~
donarb
It is Mac only, but it is open source (Obj-C). Some enterprising developer
could port it to Windows or Linux.

[https://github.com/git-up/GitUp](https://github.com/git-up/GitUp)

------
gibbitz
meh. I'm starting to hate using GUIs reaching out for the mouse is almost as
irritating as clicking it. Since my hands are already on the keyboard, I may
as well type... Maybe that's why this is unimplemented. Maybe I'm not alone.

~~~
Ajedi32
The way I see it, the git DAG is fundamentally a graphical data structure, so
it makes perfect sense to be able to manipulate it using a graphical
interface. The only problem is there aren't really any UIs that take full
advantage of git's nature as a DAG yet (at least, AFAIK).

While I've yet to find a git GUI which approaches the same level of
functionality the git CLI possesses, I think something like the UI proposed
here might be good enough to finally get me to switch.

------
rwbt
That's why I switched to Fossil and now spend more time writing code than
trying to deal with Git CLI weirdness.

~~~
2muchcoffeeman
How is fossil? I've really wanted to use that.

~~~
jaccarmac
Not OP, but I really like fossil. There are some rough edges, but the simple
workflow is at least as simple as Git's and comes with QoL like the web
interface.

------
aequitas
Some of the points mentioned are covered by the Ungit tool:
[https://github.com/FredrikNoren/ungit](https://github.com/FredrikNoren/ungit)
In terms of how your intended changes are visualized in the DAG model.

I stopped using this tool after getting a beter understanding of Git core and
how the commands manipulate the database. But I do still think the changes
suggested in the post are valuable. I'm not inline with the whole GUI idea.
But I like the concept of 'everything is a commit' and reducing the 'delta
algebra' to their basic forms. As my biggest struggle with Git is always to
make the translation of my intended change to the database into an abstract
Git command.

------
ilovecomputers
Now I'm wishing GitUp had this selection tool. Sadly you can only do
operations one commit/branch at a time.

------
glandium
> This brings very important addition to the table — ability to explicitly
> checkout STAGED version. Git’s index won’t allow you that.

Of course it will. In fact, that's very much what `git checkout` does if you
don't give a revision but give a path, e.g. `git checkout .`. (but then you
lose any unstaged changes)

------
marcrosoft
I use CLI for almost everything except git after discovering gitup.

------
donatj
> Everything is a commit. Treat working copy and staging area as commits,
> allow regular commit operations to be applied to them

That… silly. No. That doesn't make any sense at all.

~~~
Ajedi32
Why not?

A commit is essentially just a snapshot of the state of files in the
repository, so IMO it makes perfect sense to treat the staging area and
working copy the same as commits.

~~~
LyndsySimon
For one, I try to keep my commits as "atomic units of functionality", not just
state snapshots. I often have three or four commits' worth of changes in my
working copy, and sort through them carefully when one is complete to create a
commit of only that small piece of functionality.

~~~
infogulch
Right... now your working copy is just a commit named WIP that sits at the top
of the branch and is updated (--amend style) in real time. Wait! let me
finish:

So now you decide you want to move a part of the delta from WIP into a real
commit. So split it and move some of the delta from WIP into the split and
rename the split. It's the same workflow!

~~~
JadeNB
But surely "your workflow can be re-implemented in this different interface"
is merely an argument that the different interface has not lost power, rather
than necessarily that it is as good as (or even better than) the existing
interface?

~~~
infogulch
I'd prefer to phrase it as "this different interface _also_ supports your
workflow".

Whether the different interface is better or not is completely independent
from when it was developed in relation to an existing interface. For example,
I find debit cards a much preferable interface to the "pay for things from
your bank account" workflow over writing checks, and checks were developed
much earlier. :)

An interface is only as good as the power it gives you. Recall that power is
work/time, so you can increase power by increasing work _or decreasing time_
[1]. It's better if it's easier or faster to use and you can overcome the
transition/initial learning costs. I'd guess that the vast majority of typical
users of git have to pull up the git man pages (or stackoverflow) to do most
of the actions shown in this article, hinting that such an interface may
_both_ save time _and_ increase work (users often just not do stuff that they
have to research to accomplish).

[1]: Ok, I might be stretching the physics analogy a bit. :P

------
sbzoom
Just stop using Git. Jeez. I don't get it. It is a fundamentally broken tool.
Why do people insist on using it? I have been confused about this for years.
Just use something else. ANYTHING else.

I understand the usefulness (and popularity) of GitHub. It is a great tool for
collaboration. Its just too bad that it uses git as the underlying vcs. I wish
there was a decent competitor to GitHub with a different vcs so we could see
if people would make the switch. Oh well. Maybe someday.

~~~
dijit
Usually when giving out criticism it is wise to be specific.

In this case, git can be awkward to use, but the underlying architecture is
sound and it's a welcome change to centralised version control systems
(CVS/SVN/Perforce).

Not saying you're wrong of course, but as far as I currently understand it's
objectively better on all fronts except UX for DVCS. Perforce is undoubtedly
better but it relies on a constant connection to a server.

~~~
hinkley
Don't play coy. The ergonomic shortcomings of git 'porcelain' are discussed
here and elsewhere so often that if you don't know what people are talking
about you either have a vested interest in deflecting, or you have actually
been living under a rock.

If the latter, save yourself, don't read the newspaper. It's too late for the
rest of us.

------
david-given
Sadly, 2014.

~~~
lucb1e
Yet no less relevant for it.

------
milesrout
This is the first time I've read a complaint/discussion/review/whatever of
git's UI and thought 'wow yeah I actually agree this would be useful'.

I would still use the command line, a lot, but the times that I open `gitk
--all --date-order` and a terminal side by side and refresh the gitk whenever
I do a command to see what happens? THOSE are the times I would use this.

