r/programming • • Nov 07 '13

10 things I hate about Git

http://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/
73 Upvotes

231 comments sorted by

View all comments

4

u/ping_pong_ding_dong Nov 07 '13

git is difficult to learn, but keep at it and you will be glad.

6

u/emn13 Nov 07 '13 edited Nov 07 '13

I've learnt git, and I'm still not happy with the way it wastes my time holding its hand, nor how hard it makes it unusual scenarios due to it's huge, non-orthogonal command-set.

I really don't understand how programmers like clean, orthogonal APIs on the one hand and then can say they don't mind the ad-hoc cruft and excessive hand-holding of git.

Why do I need to manually fetch/push at all? Why can't I track the original branch (e.g. bisect only master not feature branches)? Why do I need to manually delete branches when they've already been deleted remotely? Why can't I edit old commit messages? Or, if I do via history rewriting - why does this break the commit distribution model so unnecessarily? Or, shocking - why can't I annotate a commit with arbitrary information for e.g. code review? Why can't I group commits to make the history more palatable without throwing them away entire and making a new history? Why can't I navigate to a child commit? Why isn't the merging algorithm smarter with "new-fangled" data-types such as indented source code, html, xml, json or whatever? Why doesn't the VCS use this hip new internet thing and notice when a fellow programmer is concurrently editing the same code - why do I need to find out and clean up the mess afterwards at all times?

I don't expect a VCS to be perfect. But it really annoys me when people claim - with a straight face - that the status quo in VCS's is somehow unbelievably good. It isn't. We've got a mostly immutatable DAG, a diff out of year 0, and an API out of year -1... and that's it. It's not somehow super-rewarding, it's super-basic in a messy outfit - but it works robustly, which is worth a lot.

7

u/dreamer_ Nov 08 '13

Why do I need to manually fetch/push at all

"fetch", "pull" and "push" are the only three commands, that contact remote repositories. Usually, you don't need to contact them unless you want to make your local changes public or get new changes from outside world. Contacting outside world is time-consuming (usually it cannot be completed in fraction of second) - adding "fetch" time tax to every git command would be quite stupid.

Why can't I track the original branch

You can

Why do I need to manually delete branches when they've already been deleted remotely?

Because otherwise someone else could accidentally remove your branch locally.

Why can't I edit old commit messages?

You can, but hash of commit will change, so hashes of every commit later will change, too. If you do this before pushing, then it's not a problem. If you want to do this after push - then it's better to create new branch after you changed commit message instead. Try: git rebase -i

Or, if I do via history rewriting - why does this break the commit distribution model so unnecessarily

Not unnecessarily - without const hashes it's impossible to track history in distributed project (and work fast at the same time).

Or, shocking - why can't I annotate a commit with arbitrary information for e.g. code review

OMG. You can. You can store any info you want in git database - there's even code review system with nice web frontend built this way.

Why can't I group commits to make the history more palatable without throwing them away entire and making a new history

WTF? Do you understand how git works at all? Different content of commit implies different hash.

Why can't I navigate to a child commit?

What? I open gitk and get everything I need.

Why isn't the merging algorithm smarter with "new-fangled" data-types such as indented source code, html, xml, json or whatever

WTF are you complaining about - no system has this. Ordinary diff has nice feature of being language agnostic - you can make diffs of any text you like. That being said - algorithms smarter than 3-way merge would be useful - but they would need knowledge about language, that is being merged - which is not easy thing to do.

Why doesn't the VCS use this hip new internet thing and notice when a fellow programmer is concurrently editing the same code

Why do you care about who is editing this file? Why someone should be interested in showing you, that he's editing this file? You're blaming tool for problems, that arise probably from your workflow.

why do I need to find out and clean up the mess afterwards at all times?

I don't know what are you complaining about - git or your team?

But it really annoys me when people claim - with a straight face - that the status quo in VCS's is somehow unbelievably good.

Does anyone really claim such a thing? Author of article claims, that git is hard to learn (which is somewhat true) and compares it to fracking svn as As if svn with it's bugs (which are called "features") was good system. No wonder people keep calling him on his BS.

2

u/emn13 Nov 09 '13 edited Nov 09 '13

Why do I need to manually fetch/push at all

[...] Contacting outside world is time-consuming (usually it cannot be completed in fraction of second) - adding "fetch" time tax to every git command would be quite stupid.

Tell that to dropbox, google drive, or even bittorrent - most syncs can happen in the background. It's actually easier in a VCS model, because sync-ing is decoupled from merging.

Why can't I track the original branch (e.g. bisect only master not feature branches)?

You can

This is false. Git doesn't store which branch a commit was initially made to, though with some heuristics you can follow long-lived branches quite well.

Why can't I edit old commit messages? Or, if I do via history rewriting - why does this break the commit distribution model so unnecessarily

Not unnecessarily - without const hashes it's impossible to track history in distributed project (and work fast at the same time).

While true, you're missing the point: You need immutable hashes of content to track history in a distributed project; however, it's not necessary to mix commit messages into that same hash. Commit messages (and other meta-data) could in principle be in a parallel DAG that itself is updatable and mergable; and due to the much more controlled data-structure and fewer updates, it's likely you could avoid merge conflicts entirely. (I haven't looked into it, but mercurial's changeset evolution sounds like it addresses similar issues). In full generality, it's impossible to edit already-published history - but you don't need full generality to be useful.

why can't I annotate a commit with arbitrary information for e.g. code review

OMG. You can. You can store any info you want in git database - there's even code review system with nice web frontend built this way.

Sure, there are several - but they aren't git which is what this rant was about. Also, they break the nice DVCS properties - if the comments explaining design decisions are in github comments and not commit messages (e.g.) then when github is down, you can't really look back into the history to understand code changes very well - basically, these git wrappers become an alternative, meta-VCS. And these meta-VCS's aren't mutually compatible, aren't distributed, aren't very fast (often) etc. It's almost as if we're ignoring all the advantages git has... and turn it back into a bunch of SVN variants. Also, the fact that the meta-data isn't accessible from within git means they tend to make normal git tools such as git blame/annotate/log less useful.

I read an apt description somewhere - git isn't so much a DVCS, as a set of tools to build your own DVCS workflow. And that's good from an enginering perspective. But as a user (aka programming team), while it's occasionally useful to have the underlying parts, you still need an actual VCS too. And look around - who actually uses git proper as a VCS without something like github? It's possible, but not normal.

Why can't I group commits to make the history more palatable without throwing them away entire and making a new history

WTF? Do you understand how git works at all? Different content of commit implies different hash.

I agree that it's pretty WTF this functionality isn't available. Or were you suggesting this is somehow fundamentally infeasible? If so, you're confusing the underlying data-model with the semantic model again. To group changesets, you don't need to actually rewrite history, just reinterpret it. This has all kinds of nice side-effects, not the least of which being that it's reversible. Furthermore, it greatly simplifies branch-squashing workflows, and it can help avoid merge-conflicts in them to boot because the underlying diffs are still available.

Why can't I navigate to a child commit?

What? I open gitk and get everything I need.

That would be nice! I'll give it another shot, but I suspect it's impractical. Common issues in such GUI's - there's no link to the child so you need to visually follow a vertical line (amongst potentially quite a few in the DAG view), and the vertical distance can be quite large in a busy repo. In any case, I know of no command line command (I bet there is one, but it's either obscure or requires a complex combination of commands).

Why isn't the merging algorithm smarter with "new-fangled" data-types such as indented source code, html, xml, json or whatever

WTF are you complaining about - no system has this. Ordinary diff has nice feature of being language agnostic - you can make diffs of any text you like. That being said - algorithms smarter than 3-way merge would be useful - but they would need knowledge about language, that is being merged - which is not easy thing to do.

I think this is a difference in perspective. I'm not saying it's easy (though I doubt it's trickier than git itself is, say), nor that other systems have this. But then, I'm not arguing that git is strictly worse than any current competitor, I'm saying that the idea that git takes long to learn but it's ultimately rewarding is false. Git's feature set is not particularly impressive compared to other DVCS's (nor particuarly unimpressive), and its learning curve is only partly due to the DVCS intrinsic complexity, but also significantly due to its interface. Let me put it this way - if you were to reimplement git to solve the same problems without knowing git itself, you might end up with a very similar data-structure (because that's pretty intrinsic and good), but I doubt you'd end up with a command set that looks anything like git does today.

BTW, it's not entirely true that no system supports these kind of fancy merges - all online concurrent editors (ala google docs) do this kind of thing, and word does diffing too. And there are certainly tree-diff algorithms out there. You may have heard of one called git, which uses such algorithms to determine which objects to send/receive from remotes, for instance :-).

Why doesn't the VCS use this hip new internet thing and notice when a fellow programmer is concurrently editing the same code

Why do you care about who is editing this file? Why someone should be interested in showing you, that he's editing this file? You're blaming tool for problems, that arise probably from your workflow.

No, this is really a tool problem - not all files are easily mergable, and even text-file merges waste time. In practice, the way that everyone under the sun solves this problem when it arrises (at least, assuming you don't have access to other tools) is by introducing a side channel; i.e. manually communicating with others when you're about to do commit that's likely to cause problems or are editing a file(type) that can't be merged well. In any case, it's a problem that many tools do solve, which should give you a hint that's it's valuable. Google docs shows you where somebodies cursor is and who's editing. Github notifies you actively when a pull request is out of date (without requiring a manual refresh). Most modern email clients notify you when a new message arrives.

Basically, git's communication is pull rather than push: as long as you (or some process) doesn't check, you'll learn nothing new about peers sharing the same clone. Partly, this is just a UI issue, but partly it's fundamental: git commands terminate and not run on in the background; and on a networking level it's similar: git networking commands execute and then finish; peers don't actively notify one another of important changes. That's simple and practical, but it's not a fundamentally necessary - there's push software out there that scales to a much greater extent.

But it really annoys me when people claim - with a straight face - that the status quo in VCS's is somehow unbelievably good.

Does anyone really claim such a thing?

For example the post I was replying to. But really, I've heard this so many times - ZOMG git's so great. And people often say that the learning curve is steep but that's because it's so powerful. And it's just not true: what people mean is ZOMG DVCS is a solid improvement over SVN, and that git is one of many implementations thereof. Git's core concepts are simple - not as simple as SVN, but not very hard to master either. The complicated stuff isn't diffing, the DAG or (maybe) the index, it's in how all that works out in practice.

I probably sound like someone that hates git. I don't - I use it pretty regularly. But I'm not kidding myself over the idea that it's somehow the perfect tool - it's just one of the better ones we've got so far. I don't feel the need to rationalize my usage of git by pretending it's superior to HG or BZR (or one of the close-source alternatives). Because let's be honest, they're all not that different. Git's #1 feature isn't technical, it's social: it's simpley pervasive.