Hacker News new | past | comments | ask | show | jobs | submit login
What’s wrong with Git? A conceptual design analysis (acolyer.org)
92 points by colinprince on Oct 25, 2016 | hide | past | favorite | 109 comments

The issue here is that git is:

1) A tool for managing collaborative work through a beautiful distributed graph theory tree model[1]...

2) ...with a very, very difficult to use UI. Unfortunately:

3) A good, intuitive UI for manipulating the underlying model without ignoring edge cases or removing functionality is extremely difficult, and indeed, nobody has done it yet.

So you periodically see these articles pop up decrying the UI, but nobody ever makes a great UI that wraps the underlying tools. This article talks positively about gitless, and it's a great tool, but it gets a good UX only be hiding/disabling large chunks of functionality. And like most tools...

4) Git suffers heavily from the 80/20 rule[2].

I'd say 95% of the time, I'm using maybe 5% of git's features. But the other 5% of the time, I'm using another 1% of git's features but it's always a different 1%. I might go weeks without needing to cherry pick a commit, but when I need to, I really need to...and gitless doesn't support it (or most other "complicated" features). But the reason git beat out the competition isn't git's excellent UI or large marketing budget, it's that those features actually provide significant value.

And so we get a slow drip of articles like this. "Man, it would be nice if there was a better git UI that had all its features!" It would indeed.

[1]: https://xkcd.com/1597/

[2]: http://www.joelonsoftware.com/items/2006/12/09.html

This article isn't complaining about the UI. They are very specifically attacking the /concepts/ that git uses – see the quote I posted further down in this thread.

It appears as if the complexity of git has created a sort of Stockholm-Syndrome, where people mistake the flaws of the system for symptoms of its magnificent power, and dismissing all criticism with an attitude of "let the hobbyists have something with a shiny GUI, this a tool for professionals".

But what people are asking for is /not/ a shiny veneer hiding the complexity, but a rethinking of the concepts that git uses. "Concept" here means mostly the mental model people form of how git operates, but that is often linked to the terms used and the internal structure.

As an easy-to-grasp example, filesystems generally operate with the "tree" concept. Note that there's nothing mandating such a structure – you could create a fs that's based on tags instead. Or weaken the tree metaphor by allowing cross-connections (i.e. linking). But given the choice of one concept, it creates certain assumptions about how to operate the system. And when those break down, people rm -rf and start over. Way to often.

True that they focus on concepts. The thing is, the overview diagram of git concepts on that page (which is in turn taken from the gitless paper) doesn't even mention commits as a separate concept even though they are one of the most important concepts of git (and the ability to quickly juggle commits is crucial to the original git workflow).

That makes me a bit sceptical about whether the authors really thought through all the various use cases of git, i.e. those 5% that the GP comment talks about, and about their conclusions.

The article points to a specific feature that once removed...

> “the elimination of the staging area was enthusiastically received as a major reduction in complexity.”

But I'm using it regularly. This is the feature that makes git stand out, even for casual users who typically edit things then commit (and have to sort things out to make sensible, semantic commits instead of "whatevs"). Every single tutorial glosses over it, but it's the single most important feature that hinges on what git is and how it operates at its core.

Every time I teach git, I take great care explaining why and how the staging area (the index and git objects, really) works. Every single time I explain that you're preparing a transaction that you end up committing (with all relevant — but obviously wrong — database or journalling filesystem analogies). And every single time, it just clicks.

The staging area is incredibly useful. It's not the functionality that's the problem, it's the interface.

To design a great interface, first you have to come up with a good metaphor and a great name. That's the first obvious fail, because the staging area has at least three different names in common use. As you said yourself, once you use a metaphor to explain the staging area, it just clicks. With a good name, the metaphor should be obvious.

And then you have to supply a consistent, non-surprising interface. What's the staging area? It's essentially a commit-in-progress. So why does it have a different interface than git commit --amend?

Grumpy me is really disappointed that git itself subsumed the porcelain. There were some really good ideas floating out there that fell by the wayside as git became usable by itself.

Stacked Git, for instance: http://www.procode.org/stgit/

We should have had a bunch of porcelains that evolved to a nice shine. You should have been able to switch back and forth between porcelains.

> What's the staging area? It's essentially a commit-in-progress

Aha, that's where the typical view of VCSes shows through the cracks of our old habits: here commit is not an object, it's an action. So there's no "commit-in-progress" because either you commit or you don't, and the operation is virtually atomic. The fact that object with badcafe sha1 records the history of that action and is called "commit badcafe" in the log is incidental, and we're being abusive when we're literally saying the commit is the object.

So when you say git commit --amend, it's really no different than git commit, because you're just telling it to do the very same thing, only with a git reset HEAD^ before that.

That said, I'll readily admit the UI is poor, mostly because it's grown, not designed.

In my view of git, commit is very definitely an object, the action is 'creating a commit object'.

I don't think either of us is wrong, we just use different names, making communication very difficult. Which just underscores my original point. Names matter.

> We should have had a bunch of porcelains that evolved to a nice shine. You should have been able to switch back and forth between porcelains.

That's basically what Magit is, a porcelain for git. It actually adds operations beyond what git's own porcelain allows, and makes easier the ones it does allow. Using Magit is like being a git ninja compared to using the CLI.

True, I love magit. Most people here in the office use magit or one of the available GUI's. But none of them change the underlying metaphor in the way that stacked git did.

> But the reason git beat out the competition isn't git's excellent UI or large marketing budget, it's that those features actually provide significant value.

I tend to think that the reason git beat out the competition is github. It was the first VCS hosting service that actually provided a sane UI that enabled non-vcs-experts to at least observe what's happening. github doesn't provide an interface to a lot of gits features and so do the github-provided native clients, but they are sufficient for at least 50% of the population that I know. Many people don't know and/or don't care about all the other power_features that git provides.

Relatedly, how awful is Launchpad? I can never get anything done there. It's as if they got the most brilliant UI designers and told them to make something completely unusable. I cannot believe a UI this confusing and opaque was made by mistake. I regularly end up navigating around in circles looking for the thing everyone wants most in a repo: The code.

Are they really so brilliant then? Seriously though, I think Launchpad was designed less for managing code and more for managing a bureaucratic project. While individuals and projects can use it, it's primarily only useful for Ubuntu and their particular workflows.

> But the reason git beat out the competition isn't git's excellent UI or large marketing budget, it's that those features actually provide significant value.

I don't know if it's true for everyone, but this is at least true for me. The reason I started to work on a git remote helper to talk to mercurial servers is that I grew frustrated that mercurial didn't have some of those features (and that the existing git remote helpers were not working well at the scale of mozilla-central, or required a local mercurial clone under the hood)

And funnily enough mercurial is today the most scalable of the two. As an example Facebook uses it for it's monorepository. Not sure about the scalability of of git-helpers though.

What features were you missing, by the way? Mercurial has had rebase, squash and light branches (bookmarks) for many years now. I personally don't miss staging if I use it.

Not to knock Mercurial, but didn't Facebook have to apply a lot of custom changes to get it to scale up? Not sure if those were committed back.

https://bitbucket.org/facebook/ not for these at least

> Not sure if those were committed back.

Some were for sure: [1]

1: https://selenic.com/hg/log?rev=fb.com

> the reason git beat out the competition isn't git's excellent UI or large marketing budget

I'm most inclined to believe that it certainly was git's large marketing budget that got it to where it is today. Not a monetary budget, but its reputational budget: "Written by Linus" so it must be good.

And github's $100 million in venture capital didn't hurt.

So Git needs its LaTeX?

I think it already does: Magit. :)

> the elimination of staged versions;

So you can't selectively stage hunks and discard others? Or stash them after making a commit of the ones you staged?

> the elimination of the concept of Stash, and stashed versions;

This eliminates the possibility of quickly putting away work in progress to do an impromptu demo at your desk, or answer a co-worker's question about the current master, or (for git newbies) working effectively with git-svn (in companies where SVN is used) without needing to learn about local branching or rebasing.

> Thus, it is as if there are multiple working directories (one for each branch),

So...like Subversion? Ew.

Does git have sharp edges? Absolutely. It's a tool meant to be used by professionals (or skilled hobbyists) to do work and build things.

I'm all for making things simpler to use, but putting training wheels (or guardrails) on a product meant for an expert user seems...counter-productive to me. To me it's like saying "Gee that cockpit has an awful lot of dials and instruments and things, we could probably take out a lot of the complexity if we assume that pilots will never have to deal with a stall" (I know nothing about planes)

I am also willing to admit that perhaps I'm too wedded to the time investment I've put into learning git and therefore assume that anything that attempts to make git simpler is flawed in some way. Maybe gitless really is the future of git.

So you can't selectively stage hunks and discard others?

As other people have pointed out, most new version control tools can do this without a staging area.

This eliminates the possibility of quickly putting away work in progress to do an impromptu demo at your desk,

No it doesn't, and they explain how. With combined branches + stashes, you'd do a checkout of a new branch from the commit before your stashed changes.

So...like Subversion? ... putting training wheels (or guardrails) on a product meant for an expert user seems...counter-productive to me.

Did you even read the article or the original paper?

The latests iteration of hg crecord which is an interactive selection tool for chunks (see it in action here: http://g.recordit.co/BfbSa7cMXn.gif) Is far far better than git staging area. Intuitive to use, i can submit hours of code in few nice selective chunks really easy.

This sole function built in is a game-changer in mercurial for me.

You can get very similar functionality for git with "magit", which is an emacs package for managing git.

That said: Partially commiting files is indeed very handy and it would be great if it was available to more people.

It strikes me there's nothing inherently mercurial specific to this tool. This could very well be ported as a UI for git add -p.

I think GIT staging area wouldn't make it so nice to use in the end. Unless the whole thing is abstracted more, but then we get into the gitless discussion again.

I think it already exists as a graphical tool for Git, check out `git gui`.

If you don't have a stage then you don't get to edit/stage/edit/stage/fix/commit, right? I use that workflow a lot. I generally like incrementally building and refining my next commit. The stage/index is one of Git's most innovative features IMHO.

The same workflow can be accomplished by amending commits in git, without a whole new set of semantics needed for managing the staging area (or needing to stash changes when switching branches).

Your gif results in a 403, so I can't compare directly, but I get the impression that more people need to learn about `git gui` ;)

> As other people have pointed out, most new version control tools can do this without a staging area.

Fair enough.

> No it doesn't, and they explain how. With combined branches + stashes, you'd do a checkout of a new branch from the commit before your stashed changes.

Ah, OK. However, I still maintain that I have other uses for stash that don't easily conform to git stash --all; git co new-branch.

I read the article (though it appears not closely enough). I will admit to not reading the original paper (until now), but I did skim gitless's documentation a few weeks back when it appeared on HN. Even then I was struck with a touch of "What is all this new s&%# I like how my git is right now stop messing with it"

Like I said, I'm willing to admit that because I already know all of git's sharp edges, gitless may simply not appeal to me. However, it's totally possible that gitless really does make git simpler for new users and it's the future of git.

Stashing gets done the way we did it in the bzr days:

scm stash <filename> # Stash a whole file

scm stash -p <filename> # Stash a part of a file

scm stash -p # Stash parts of the whole project

Works as well as a staging area (because it's just the complementary operation) without needing a staging area, and without all the cognitive burden. Saying "you can put changes aside for later" is much easier than explaining the different states of a file in the staging area.

The interesting thing about git is, that while it is heavily criticised for begin difficult, it is such a huge success.

Most of the time, criticism of git can be summarized as "Bad user experience", which is often blamed on git exposing its implementation details. I.e. most git criticism proposes that the backend of the VCS should be "private" and the user should see a carefully designed UI, that is optimized for workflows.

I think we don't need to redesign git in such a way, for the mere fact, that we already have a mature, distributed version control system that has a carefully designed UI and has a core that is opaque to the user: mercurial

In fact, given mercurial's age, the availability of github-like hosting services (bitbucket offered mercurial hosting for years) raise a very important question, that I would like "git-reformists" to answer as part of their critique: Why has git won more market share than mercurial?

My feeling is, that part of what makes git hard to new users is a "killer feature" for intermediate and advanced users. I.e. having a basic understanding of how git manages its data makes hardly leaves me with situations and repository states that I cannot resolve. Whereas in mercurial, I feel pretty much lost when I want to do something that has not been an implemented workflow.

Maybe, now that we know a lot more about DVCS workflows than we did at the time when mercurial and git were young, a new workflow-oriented VCS might make better workflow choices. Until then, I happily stay with git.

> Why has git won more market share than mercurial?

Because Git is used by Linux and was designed by Linus.

Those facts alone are good enough for most people to choose git over something else, not the technical ones.

Just like UNIX and JavaScript, technically better is not always what wins.

It's all because of this. Before git there was also monotone, which was fast and my personal favorite. But Linus tried it once and that specific version happened to have a performance regression so he decided to rebuild the whole toolchain from scratch.

Honestly it's a good story about the power of marketing and I feel a bit sorry for the monotone developers because they did it first and well, but get almost no recognition.

> Before git there was also monotone, which was fast


I played with OpenEmbedded (for OpenMoko) a while ago, which used monotone. From what I recall, it was slow. IIRC, slow enough that they had to use the trick of downloading a "pre-cloned" snapshot and updating it, instead of cloning from scratch.

We are talking about 12 years ago and since then monotone hasn't gotten much love, while the others have.

I did find some benchmarks from 2009 and by then monotone shows consistent by often 5x slower performance than git:


UNIX and JavaScript?

They're (counter)examples. Bad things that won.

"Worse is better" etc.

Genuinely curious: which OS ought to have beaten UNIX?

The Unix team created Plan 9 to supercede it, so that's the logical choice. BeOS had a lot of fans, too.

(Completely unrelated, I just discovered that the Plan 9 logo bears a striking resemblance to the Go logo [see the Wikipedia link]. Given Rob Pike's influence, I'm sure that is not a coincidence.)

[1] https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs

I'm also wondering this. I have not seen an OS superior to *NIX systems, UNIX in particular, when you add the context of era.

Any of those designed at Xerox PARC, or security minded ones designed in the 60's like Burroughs.

So am I. Maybe BSD?

Nobody asked about JS, apparently that's clear :)

Why is git so successful? It has good internals and has had those good internals for years and years, which covered up for its many flaws. Add on to that: network effect due to linux, github, and gitlab all using git.

Git is great, compared to most of the alternatives. But is it perfect? Of course not. Is it hugely flawed in parts? Of course it is. It has a UX designed by freaking engineers FFS, it's surprising it's as usable as it is.

The observation that git forces you to learn how its guts work so that when you inevitably end up in some scary situation with the potential of losing or screwing up revision history you know enough to work your way out of it is not a strong argument. It's similar to the lament about how older cars were so much easier to work on and that made them better. Better if you want to work on cars, perhaps, but a vehicle that requires constant maintenance is not superior to today's cars that can be run for 100k miles with minimal engine work and a single set of spark plugs, and are also safer, more efficient, and cleaner to boot. The same thing goes for VCSes, if you're regularly, or ever, getting into hairy revision history problems that's a sign of a weakness in your VCS and/or workflow.

> I.e. having a basic understanding of how git manages its data makes hardly leaves me with situations and repository states that I cannot resolve.

If your dvcs allows you to get to that odd situation then it's already bad. Think about it as a tool for masses, maybe someone really familiar with GIT internals can resolve all odd situations, but imagine introducing GIT into an Organization with 1000 SVN users. The costs of all the guys learning in depth git is just too big.

> _it is such a huge success_

GitHub _is_ a huge success, and git is merely comes along in a bandwagon (English isn't my native, hope I've made this clear)

> Whereas in mercurial, I feel pretty much lost when I want to do something that has not been an implemented workflow.

Interesting, could you give an example?

> GitHub _is_ a huge success, and git is merely comes along in a bandwagon (English isn't my native, hope I've made this clear)

It's the other way around. Git was such a huge success, so therefore someone decided to create a nice web-frontend and SASS for it. That SASS was Github.

IIRC git was already a huge success, i.e. most big freesoftware projects (Linux, GNOME, xorg, gstreamer and many more) ditched other VCS for it, when github was still in its early stages.

I remember quite a few (Go, SDL, Java,Google Code repositories...) using Mercurial until switching to git due to peer pressure was unavoidable.

> The interesting thing about git is, that while it is heavily criticised for begin difficult, it is such a huge success.

I think it's only difficult to use if the company/people using Git don't have good Git policy.

Most of the comments here are missing the point. The functionality and architecture of git aren't what's being criticized, but the way this functionality is presented. In fact, gitless if built on top of git's architecture.

As far as I can tell, gitless still embraces git's distributed and incremental core. It just packages it in a way that's easier to digest. If you're a veteran and know your way around native git flawlessly, gitless probably presents little value. But if you're a notice just learning the tool, gitless can probably accelerate your learning curve without sacrificing functionality—you can still bypass gitless's abstraction layer when you need it.

Som here are missing the point in the other direction – this isn't about "design" as in "please give me a shiny UI", or "fewer buttons". The paper makes this point quite explicitly:

"These weaknesses have spurred the development of com- mand line wrappers and GUIs whose primary goal is to re- move some of Git’s complexity (most notably, EasyGit [1] and GitHub’s desktop client). These make largely cosmetic changes, through more attractive user interfaces, more con- sistent terminology in commands and documentation, and a focus on more commonly used commands. But their suc- cess seems to have been fairly limited, and most people still use the command line interface distributed with Git as their primary frontend, or fall back to it for accomplishing more complex tasks.

We believe that the usability problems of Git run deeper, and can only be addressed by a more fundamental reworking that reconsiders the underlying concepts. This is not to say that such a reworking cannot be achieved in a lightweight fashion. Indeed, our own reworking hides Git behind a ve- neer just as these other tools do. The difference however, is that we are willing to completely reconsider the core con- cepts that are presented to the user."

I'm not sure that combining stashes and branches wouldn't be handy for advanced users either.

I'm not sure I'd know what name to give to my countless stashes.

Let the system provide default names for them, based on the name of the branch they came from.

Why would I commit my breaking, work in progress experiments to a branch? Isn't that what stashes are for?

New branch flagged as a "stash", named related to the branch it came from. So branch myFeature has stash myFeature-stash-1 stash branch. Hide stash branches from branch lists unless specifically requested.

Do the same with stash commits. Store them as regular commits flagged as broken and hide them when viewing history.

Hell, do the same for most history-modifying operations. The ability to flag intermediate commits as "unimportant" would let you be able to keep a clean history without rewriting it.

Maybe you want to push your work to a remote server as a way to back it up.

Maybe you want to share your work with others even though it's still in a rough state.

Maybe you have automated tests in your CI process and you want to try those tests on your side-branch.

The point is you might want to wrap workflow around your stuff, even if it's experimental and broken.

Git doesn't make these choices for you. You get to make them.

Because sometimes stashes are longer lived than we expect, and they're hard to work with if you need to do anything more complicated than popping. (Like resolving conflicts.)

I find that making a work-in-progress commit, and then resetting later ends up saving a lot of hassle overall. Having support for this beyond aliases (including putting that commit in a new branch) would be nice.

Okay, points taken. But git enables me to commit expermiments to a branch anyway if I decide to. Gitless' lack of stash would force me to commit experiments to a branch.

I personally think Git's staging concept is one of its best features. Yes it is different and increases the learning curve somewhat, but it also provides a lot of flexibility in what you commit. For anyone that thinks Git is too complicated, consider using Mercurial.

Agreed. One of the common things I use is git add --patch <file>. This allows me to commit changes in a file under different commits, by staging only the parts of the file that I consider as relevant for that commit. A lot of times I have different conceptual ideas in the same file, and I would have either forgotten to commit them during the day, and only realize it in the evening when it's time to push the code upstream; or those features would have been developed in parallel, because they are codependent, but are not necessarily the same from a conceptual point of view to the project. Either way I would want them under different commits so that my commit log is clean, and each commit can stand on it's own. This is where the --patch flag and the staging area are really useful. It might be a little trickier than just committing all tracked files with changes, but I appreciate the control. However, I do sympathize and agree with some of the points raised in the article, and I think there's definitely a scope for better interface design in git. For example, the stash is something that regularly confuses me, and the solution in the article seems like a better interface.

> A lot of times I have different conceptual ideas in the same file

Or debugging code. You're right, git add -p is a lifesaver.

The alternative could be `git stash -p`. Stash away the changes you don't want to commit, then commit everything still in the working tree.

The idea to remove the concept of the staging area to simplify git is worthwhile. I heavily use `add -p` myself, but newbies certainly struggle with it and teaching `commit -a` is not the solution.

> The alternative could be `git stash -p`

No, because I don't run `git add -p` before committing (I would run `git commit --patch` for that). I run `git add -p` during the development cycle. To emulate this with `git stash` would require a very annoying dance with stash and rebase.

> newbies certainly struggle with it

Newbies don't even know about `git add -p`. Newbies struggle with git because commands are not orthogonal (as the article mentions), and because documentation sucks. There is nothing inherently difficult about the staging area, it's just that it's not very visible what object a command would use or affect (index/tree/working directory) and it's hard to learn this.

The problem is with the implementation, not with the model.

Another problem is that in most cases people don't really want git, they want svn with local commits and better merging capabilities. Git is very popular, for some reason people use it even if it's clearly not what they want or need. To these people I suggest they should use the DVCS features of Perforce.

I never ever use commit -a these days, but as a newbie I did. These days, my go-tos are indeed add (-p) and/or commit -vp, so as far as the staging area goes, it become rather essential to me.

Not having a staging area (or using git add . && git commit -a to bypass it) has it's drawbacks too; I think most of the "garbage" files like "main.o" and ".test.py.swp", and secret API keys in public repos, can be explained that way.

To me, the answer is not abandoning the staging area, but improving the UI for handling it and/or directing users that don't want to deal with the git UI to things like GitUp. The git UI is horrible in a lot of places, admittedly. Even now, considering myself an advanced user, my workflow still is "git branch ... uhmmm... ^H^H... git checkout -b topic".

Fixing the (most annoying issues of the) UI might require some breaking changes sometimes, but so be it.

In particular, the staging area goes hand-in-hand with making small, consistent commits containing one logical semantic change each. I find it much harder to do that without the staging area. (I attempted to follow that practice all the way back to CVS and SVN, but found it challenging to do so.)

I second using Mercurial as they've also got selective commits in both simpler and more flexible way: https://www.mercurial-scm.org/wiki/CrecordExtension#For_Merc...

If my repo contains modifications I don't want to commit, I git-stash those modifications. I find it to be a lot safer: at least I can run the build + testsuite on what I'm actually going to commit, allowing the prevention of an incomplete commit (which means in practice, I nearly always use "git commit -a", and I find the index pretty annoying).

Haw can you partially stash a file?

git stash -p

It'd be nice if there was a way to run a build + test cycle on the staging tree.

You can use

  git stash -k
Which will create the stash with your changes (both staged and unstaged), but keep the staged ones in the staging area and in the working tree.


For anyone that thinks Git is too complicated, consider using Mercurial.

Anyone that wants to use TYOOL 2016 age DVCS features should also switch. Like changing history yet still keeping a record of the original one (hg evolve).

Git completely owned all other DVCS with good branching. 10 years ago. But now it's time to move on to better tools.

The usefulness of hg evolve is debatable. It can be useful locally, as much as the reflog can be useful in git, but as soon as you push to the upstream repository, you lose that precious history if you haven't pushed it priorly. Worse yet, the reference to that history is still there in what you pushed, despite being nowhere to be found except in your local clone, making it useless to others.

That's true in case you've created some changesets, played with them locally and pushed them upstream. But, say you've played with changesets already available upstream, the unmodified changesets do not go away.

At RhodeCode (https://rhodecode.com) we believe it's up to a team to decide, which version control better fits their needs and preferences.

Some companies even have Git, Mercurial, and SVN, working all together under centralized repository management.

I, personally, believe it's up to a user to decide which version control system works best for them.

Both git and mercurial can talk to "non-native" remote servers.

IIRC mercurial can talk to subversion and git (with hg-git).

Git can talk to subversion, cvs, perforce, mercurial (there are multiple tools for the latter, and I'm the author of one of them), bzr, and maybe others.

If things don't work smoothly in any of those cross-VCS configurations, my belief is that issues should be filed and fixed.

Agree. However, large enterprises usually have common compliance/access control policies, something not easily implemented across multiple VCS (unless there's a full-fledged internal development team dedicated to that).

Working in a big firm adds overhead, yet has certain benefits (resources, etc.). That's a whole different topic though.

Git only started really clicking with me when I started thinking of most of my actions as graph building and traversals. It also helps to realize that for most intents and purposes, commits in git are immutable and "destructive" actions such as rebase don't _actually_ rewrite history, but rather create a new path in the graph and moves your branch pointer to it, leaving all previous commits intact (though potentially hard to reach and subject to garbage collection).

This reminds me of a well known comic: https://xkcd.com/1597/

Thats really funny, because that's exactly how I use git. But I only blame myself for never finding time to read up a bit and understand its concepts.

recent discussion of the gitless project, which is presented as in this paper: https://news.ycombinator.com/item?id=12621837 (300+ comments)

The blog author doesn't understand Git that well:

    git add foo.rb
    // continue working in foo.rb
    git commit foo.rb
will commit the latest version of foo.rb.

That's because git commit handles its arguments by add-ing them to the index (staging area) before doing the actual committing.

I'm not so sure about the conceptual graph from the paper, either. The stash is a commit, it doesn't have anything to do with file states.

No, the author is correct. The add command adds that version of the file to staging, so subsequent changes will need to be added as well if you want them in the commit.

No, you can read the following in the man page of git commit:

3. by listing files as arguments to the commit command, in which case the commit will ignore changes staged in the index, and instead record the current content of the listed files (which must already be known to Git);

Oh indeed, you're right. This didn't occur to me because I've never had a reason to use `git commit [path]`.

And I don't know if I'd call this error evidence of the author not understanding git, as much as I'd call it further evidence of the inconsistency they're highlighting.

> That's because git commit handles its arguments by add-ing them to the index (staging area) before doing the actual committing.

That's not what it actually does. It commits all the changes from the file (staged or otherwise), and nothing else. It leaves the index/staging area in the same state, except for the committed file.

That is:

  git add foo bar baz
  git commit foo
will commit any change to foo, and leave bar and baz alone (staged and non staged parts).

This presentation of gitless makes it attractive. I'll give it a try.

One of my problem for which I didn't find a satisfying solution yet is to efficiently see the changes in commits and reshuffle and merge them.

Actually, when I do a change, I offten see and fix typos and other bugs or refactor code in the same step. So my commits tend to be a compilation of unrelated changes instead of clean atomic commits. It is a boring work to split these commits into nice and clean commits.

I know I should commit frequently (small changes), and then afterward merge related commits. But that is not easy with git and I suppose gitless too. So I tend to do big commits which is bad. Any suggestion how I could improve my commits ?

This might already be what you're using, but just case (and for other people's benefit) `git rebase -i` is very helpful for reordering and combining a bunch of small commits. (I mention it because you're referring to "merging" rather than squashing or fixups.)

It opens a text file listing your commits prefixed with a command, which you can reorder and edit to change the history in one go. It's not completely painless, and I still prefer to do operations one at a time with it in case there are any conflicts, but it's still better than the alternative. (I'm not even sure what I do instead...)

Thanks. I saw that gitless has the option -p that is documented as allowing to select parts of a file to commit. I'm curious to test that. It seam possible to reshuffle commits using `gl fuse` which is a kind of `git rebase`, but there is no interactive mode as with rebase.

Just found a limitation in gitless. I can't publish tags.

Just some git love Didn't read, but there are so many articles out there... i started working with git from console ( when i didn't use the console that much ) and still compared to tfs, subversion etc. it felt like haven. I currently have to use SourceTree at Work... damn it makes git feel so slow... Somebody experience with https://www.gitkraken.com/? Any point in trying it out? All the best

While Gitless is a positive effort to rectify some of the shortcomings of Git, I wonder why the authors found it necessary to construct a veneer over Git instead of simply forking it entirely. While the veneer is nice on a trial basis of such functionality, to continue in that fashion for production use would require constant maintenance to remain in sync with any core changes to Git and its surrounding tool chain. A fork would be cleaner, yet interoperable with Git repositories and separate.

This is a really cogent description of what I've felt about fit for a while but was unable to articulate. It's also written in an non-combative way.

I feel about git the same way I feel about emacs.

In the time it takes to master git/emacs, one could have accomplished something seriously impressive.

Of course, this analogy doesn't completely hold because the basic functionality of git is pretty easy to use (especially with gui tools).

Just my IMO - takes a bit to learn the basics but it's good enough, move on to more important problems such as privacy, security etc...

The "problem" with git, imo, is that it's designed for hackers more so than professionals. Most people simply don't grok that. As someone with a background in Linux (for which it was designed, not the trendy "hacker" OSes like OS X), as someone who's willing to dig in and understand the internals, I find it beautiful. If I made a VCS from scratch it would end up being pretty similar to git.

The problem with so-called "professionals" is that they sometimes, when their egos are running a bit dry, they feel the need to dismiss others as "hackers" or "hobbyists" or "amateurs" or "hipsters".

It's mostly a problem for them though, because it makes them an easy mark. You can get them to spend a significant chunk of their time on earth patching kernels to get their ethernet cards working, and they'll gladly do it and feel really quite manly and professional and not lonely at all, no.

I'm not dismissing anyone in the way you think. I'm not passing negative judgement on the people I'm talking about - I just don't think they're hackers. I don't think they couldn't become them, either. What I'm saying is this: git is easier to understand with the context you have from being the kind of hacker I'm talking about. People only ever written rails or node from the comfort of Atom and their four favorite shell commands simply don't have the experience to easily understand why git works the way it does. That's not an inherently bad thing, but it does make git more difficult to understand.

From a very quick read, yet another UI takedown without mention of underlying content-adressable arch.

As it turns out I do think both the porcelain and plumbing commands both suck, but I rather read a takedown by somebody who's learned all the layers.

> yet another UI takedown without mention of underlying content-adressable arch

I'm wondering how nice architecture under the hood can be an excuse to have an Boeing-747-cockpit-style UI?

I suggest using a more commercial tool, like Microsoft Visual Source Safe. There is nothing wrong with Git (at least not at conceptual design level, or it would not have become one of most successful piece of software of all times - like top3, alongside with Linux, another masterpiece of the same creator).

Microsoft Visual Source Safe

Maybe Perforce or something, but recommending VSS in 2016? Hope it works out for you!


TL;DR: author blames his lack of understanding of the git concepts rather than the git concepts themselves.

The author clearly understands the git concepts.

Most git users commenting on the other hand seem unable to grasp that partial commits and staging areas are different concepts.

The blog is called "The Morning Paper". Each article aims to summarise an academic paper, and the paper in question is linked in the first paragraph. The article content doesn't necessarily represent the author's own opinions or their understanding.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact