I wonder how much time and money has been wasted trying to operate Git's confusing UI. The repository format itself seems fine, but I'm surprised we're not all using a better frontend by now.
The basics (stage, commit, merge, branch, push, pull, log, diff, bisect) aren’t confusing. (The rest isn’t that confusing either, but…) If you prefer GUIs, feel free to use them, but that’s certainly not everyone.
I disagree, the basics are confusing, because there is too much state. I think gitless (http://gitless.com/#vs) shows how a less confusing version looks.
Reminds me of hg patch queues, which I've always found to be drastically more error prone than git's staging feature when trying to commit some but not all of the changes you've made, but I haven't tried gitless and it may do it better.
I had a recent epiphany about staging, which is that it really starts making sense if you stage as you go.
Let's say you want to write small feature X, and it truly makes sense for X to be a single commit. But doing X involves changing around both Y and Z. Git makes the following workflow easy:
* Fiddle around until you get Y working how you want it
* Stage it
* Fiddle around trying to get Z to work. Try something experimental. Nope, that's not you want it. `git checkout .` Try again.
You don't have to worry about only blasting away the failed Z attempt while preserving Y—since Y is staged, it's easy to keep around.
Technically the same metaphor can be used for "commit" if we assume you stage the one thing and commit that one thing. Now look through the same workflow again but replace "stage" with "stage it and commit it."
If you don't have `stage` how are you going to generate a commit which has only some of the changes you've done (potentially including partial commits from files)?
`stage` is unnecessary if you have a really simple workflow, but it provides a lot of flexibility at very little cognitive cost.
By specifying the parts you want to include when you commit. I think it's unnecessary for any reasonable work flow, and doesn't manage to break even on its benefit vs. cognitive cost.
"git add -p" generally negates the need for incremental staging, unless you have made two unrelated changes to the same diff hunks that need to be untangled.
I think you should read back to yourself what you wrote -- you are essentially saying git is complex. Anything complex with enough time and understanding can become easy, but do you need the complexity in the first place? Most developers usually want a simple workflow where they don't want to deal with too many idiosyncrasies of the tool they use. You want to checkin and checkout mostly, but instead one needs to understand a lot of details or you keep tripping up.
You have a widely adopted tool with some real or perceived flaws. Everybody knows them and wants to fix them.
But unless you somehow get mass adoption from the start, the project flounders because everyone will be pointing out that you can't install & use the new tool in restricted environments or on very old environments.
So we're left with the lowest common denominator.
At this point, to break the cycle, either the original developers come with the 2.0 interface and push it hard (which might cause backlash: https://xkcd.com/1172/) or someone with a ton of pull and resources does it from outside (which could trigger a fork or other unpleasantness).
Except we all knew how to write better UIs back in 2008 when Git was first written. It's not some brand-new research that only came to light a few years ago. We knew how to do usability tests in 2008. We knew what patterns worked and what didn't. We knew how to build discoverable software.
Why the heck wasn't the UI improved back then, before the thing was even released?
I mean, while your explanation is correct, it doesn't explain or excuse the pure incompetence of the original developers when it comes to usability issues. Their laziness or ignorance back then has confused and irritated thousands or millions of developers now, and continues to, and will continue to for the foreseeable future.
Make sure the shit you're going to set in stone is good before you grab the chisel, guys. You're professional software developers, not clowns.
One can argue semantics whether you call it a UI or a CLI, but hey. There's a number of GUI clients out there that depending on your criteria could be considered better. They're usually not as powerful as the CLI client though, and if they are, features like accessing the reflog are hard to find and use. There's also a few alternative CLIs out there, I've just done a quick googling and came across http://www.saintsjd.com/2012/01/a-better-ui-for-git/ and http://www.kennethreitz.org/essays/legit-the-sexy-git-cli.
Personally I prefer the CLI, it's the only tool that I can rely on to do what I tell it to do and to know what's happening. But it takes time and effort to get used to it.
I prefer git CLI mostly, except for merge conflicts. Exclusively for git merge conficts I use IDEA IDE resources. Otherwise CLI is my friend because I feel safe (git push and git commit have the best color-coded messages in most OSes)
The problem with Git (well, one of many many problems with Git) is that it conflates its user interface with machine interfaces-- which means tools that have to work with Git (like those GUI clients) have to use the CLI to do so. They don't have a more powerful option, like an officially-supported API or a shared library they could call into. This is terrible software design.
In fact, there exist many alternative 'frontends' to Git. There are even protocol translators like Hg-Git [2], and many importers that typically use the fast-import format to ingest Git-impl primitives [3]
libgit2 is not official, not in-sync with the main Git tool development, and doesn't support many of the features Git supports. So no, it isn't a solution to the problem.
Separating the UI and machine interface is something that should have been done from day one. In fact, I've been told Git's codebase actually already does that (it just doesn't expose the machine interface to the outside world.) Human beings are not machines. They have entirely different needs.
Once you understand Git's data model, the UI is perfectly intuitive and very efficient. When you want to do something in git, it generally requires just a single command - you just have to know what you actually want to do.
Attempts at different UIs fail because they're all trying to put an abstraction over top of git that doesn't actually reflect the underlying data. As a result, they're limited to the set of git functionality that overlaps their abstraction, and the tools are less powerful.
> Once you understand Git's data model, the UI is perfectly intuitive
So it's not intuitive at all.
Not to mention that every damn command is inconsistent with every other command! To remove a file, git rm. To remove a branch, git branch -D. To remove a commit, git reset --hard HEAD^. How is this intuitive, consistent, or even sane?
"I understand git" and "git is easily understandable" are completely different. Git is not easily understandable, at all.
`git reset` doesn't simply remove commits. Depending upon what you reset to it could result in `git log` showing additional commits, or an entirely different set of commits. Conversely, there's no invocation of `git rm` which creates files. In this case, the commands look different because they do totally different things.
You'd have a better argument with `git rm`, `git branch -D` and `git remote remove`. :)
I mean, I'll agree, if you insist on trying to create an abstraction to understand git, you can beat your head against the wall for days trying to figure out how it works. On the other hand, if you just take a couple hours to really try to understand what it's doing and why it's not that hard, and it's way more effective and powerful than any other tool out there. Personally I like tools that are powerful and efficient once learned over tools that I can use without any learning.
Note that I never said git is easy to learn, just that once you take the time to understand it, it's actually quite natural and intuitive.
That article you linked is clearly from someone who liked how simple subversion was and is annoyed that git requires more than 15 minutes to learn. But there's a reason almost no one is using subversion anymore.
> Personally I like tools that are powerful and efficient once learned over tools that I can use without any learning.
I prefer powerful and efficient tools that I can use without any learning, since the two aren't mutually exclusive.
> if you just take a couple hours to really try to understand what it's doing and why it's not that hard,
What is it in git's architecture and design that mandates that a file should be removed with "rm", a branch with "branch -D" and a remote with "remote remove"? What about its fundamental architecture makes it so that the commands can't be "git rm", "git branch rm", "git remote rm"?
Nothing, and this is the crux of the argument. Git's porcelain is inconsistent, unintuitive and poorly designed.
> Note that I never said git is easy to learn, just that once you take the time to understand it, it's actually quite natural and intuitive.
What does "intuitive" mean if not "easy to learn"?
> That article you linked is clearly from someone who liked how simple subversion was
Maybe so, but that doesn't invalidate its arguments.
> prefer powerful and efficient tools that I can use without any learning, since the two aren't mutually exclusive.
They're not necessarily mutually exclusive, but in my experience there's often a trade off. I would argue that git is about as simple to as it can be without taking power away from the user by forcing an abstraction on him.
> What is it in git's architecture and design that mandates that a file should be removed with "rm", a branch with "branch -D" and a remote with "remote remove"?
Yeah... I have to agree that the choice of command line arguments is the weakest element of git.
> What does "intuitive" mean if not "easy to learn"?
The two often go together, but aren't necessarily the same thing. Something is "intuitive" if the correct thing to do is natural and obvious without a whole lot of thought. Git isn't intuitive before you understand the data model, but once you do, you don't have to spend a lot of time figuring out how to accomplish things, so it becomes intuitive. I would argue that by contrast, subversion is intuitive out of the box, but as soon as you want to do more sophisticated things it becomes rapidly counter-intuitive and very difficult to work with.
I agree with you there. It doesn't mean that things are as bad as "weak tools or hard-to-learn tools", but there's a tradeoff.
> I have to agree that the choice of command line arguments is the weakest element of git.
I think there's a fundamental misunderstanding here. Git's conceptual model is hard to learn, but there's no way around that. If you want to be proficient in Git, you have to understand the conceptual model, and people find it hard and mostly give up, and say that git's core is badly designed (which it's not).
This muddies the waters for people who claim that git's porcelain is badly designed (which it is), because then other people mistake that for the former argument, and we end up talking at cross-purposes.
I think we can both agree that git's core/architecture is great, and the porcelain is quite bad.
> Git isn't intuitive before you understand the data model
I think this meshes with my previous paragraph, but I think git could be much more intuitive (and require much less mandatory learning of the internals for someone to be productive with it) if the porcelain were better designed.