
Why Git sucks? - lelf
https://enux.pl/article/en/2014-01-21/why-git-sucks
======
Walkman
> In Git, you can checkout neither a single folder nor a file.

Yes, you can. It's called sparse checkout[1] and not that hard. Also, you can
subtree merge[2][3] directories back and forth preserving all the history and
merging back if you wish (cutting a directory out of the repository to a
separate one and putting it back). It's pretty easy to do in git>2.0 because
there is a builtin _subtree_ command[4] for it.

[1]: [https://www.kernel.org/pub/software/scm/git/docs/git-read-
tr...](https://www.kernel.org/pub/software/scm/git/docs/git-read-
tree.html#_sparse_checkout)

[2]: [https://help.github.com/articles/about-git-subtree-
merges](https://help.github.com/articles/about-git-subtree-merges)

[3]: [http://git-scm.com/book/en/Git-Tools-Subtree-Merging](http://git-
scm.com/book/en/Git-Tools-Subtree-Merging)

[4]:
[https://news.ycombinator.com/item?id=3926683](https://news.ycombinator.com/item?id=3926683)

~~~
manojlds
The actual meaning here is "clone" a single folder or file, not checkout.

~~~
Walkman
There is no practical difference. Yes, you clone and have the whole repository
on the disk, but after a sparse checkout you only have to deal with the files
you are interested in.

The only problem can be with Facebook-sized repositories, but I believe in
modularizing that big of a system instead of storing everything in one vast
repository.

------
eknkc
Used both SVN and GIT on different types of projects. Gotta admit, it's been a
little harder to get used to GIT. It has a more complex interface and ways of
doing things.

However, it feels like comparing SVN to GIT is like comparing horses to
automobiles at this point.. Yes, a horse can heal minor damages without a
mechanic, your car can't. And it can swim if need arises, good luck with a car
on that.

Woudn't choose a horse for anything serious though. Maybe for fun and sports.

~~~
jackweirdy
Nitpick: It's just Git, it's not an acronym.

I agree git has a more complex interface - I think I've read it described as
"not quite user-hostile, but only expert-friendly", which I think fits.

That said, I think the model of how commits work is far more intuitive than
anything else I've come across. A commit is just a diff and a pointer to the
commit that came before it, and a branch is just a pointer to a particular
commit.

~~~
LukeShu
Nitpick: A commit is not a diff, it is the entire tree. Any diffs you see are
computed, not stored.

You can export a commit as a diff+pointer-to-prev-commit, but when git imports
it, it gets turned back into a full tree.

~~~
jackweirdy
That's true. I simplified for the sake of not delving too far into the
details, because it makes sense at the smaller level. It's also true that a
commit isn't always just one pointer to the commit that came before it, in a
merge there are two pointers, from commit_head and merge_head

------
SDGT
> Impractical for single repository of libraries

Submodules?

I actually think an entire repo of libraries is the wrong way to go. With the
git model, we have however many repos acting as the source for these
libraries. This repository that contains all of these submodules can then be
the arbiter of which version should be included in the release.

> Yes, some will say - but this is good - centralization is bad... Well, it
> depends. If you can spend time to figure out who is who, then it will work
> for you.

And this problem doesn't exist with SVN? Sure, maybe if you are the sole
publisher of all these libraries it might be ok, but with most real world
examples, there exists multiple contributors. Now they need to go through you
when there needs to be a specific update to that library. With git, the
maintainer of the repo of libraries(submodules) just updates the specific
submodule to whatever release works for their tastes.

Most of these complaints sound like an SVN user having some pain when trying
to think in git.

------
tonetheman
I think my main problem with git (though I use it) is that things that should
be simple are mind numbing hard. At 2:00am when I working, having to read
pages and pages to decide if git pull is the right thing is just painful.

I never felt that type of pain with SVN, it more or less just maps to
directories.

To each his own I wish there was the right way to use git in 50 words or less.
If I need to read a book to correctly use it ... grrrrrrr.

~~~
thrush
Some people like git pull, but I prefer git fetch. This gets all's the history
from the remote repo without applying any changes. Then you can run something
like 'git rebase -i origin/master' which is where I think git can really
shine.

There is an excellent link out there that explains git in layman's terms. I
think it's called git for hackers or something of the sort. It's much easier
than the docs in my opinion.

~~~
SDGT
Best practices are to not use pull unless you certainly know you should.

Things should be fetched then merged with two separate commands.

~~~
gizmo686
Pulling is equivelent to doing a fetch then a merge. Unless you plan on doing
something between the two steps (like inspecting FETCH_HEAD yourself), then
there is no advantage to not simply pulling.

Of course, if (like thrush) you do not plan on doing a merge, then you will
need to do the fetch manually and do what you do want to do. Although, git
pull does have a --rebase option, but I am not sure if you can pass the -i
flag to it.

Having taught people how to use git, I found that it is easier to not show
them the pull command until they are used to doing fetch && merge.

------
undata
These are extremely superficial reasons to criticize git, leading me to
believe that the author knows very little about git internals. I'll take the
first critique and leave the second to someone else...

You can't pull a portion of the repo because the current state of the repo is
built from the tree of commit diffs... This and the fact that git itself is a
hash database leads to very efficient use of space. If you want a single
folder within a repo, why isn't that folder its own repo?

Between that, the passive aggressive ;-) and the unfortunate advocacy of
SVN... ugh.

~~~
danielweber
_leading me to believe that the author knows very little about git internals_

Needing to know about the internals of git is a flaw of git, not a feature.

~~~
undata
Why would you use a tool you don't understand? What if it breaks?

------
damm
Sounds like the author has a workflow problem here. Most of the reasons given
of why Git sucks could be from the OP's inability to adapt their workflow.

SCM is a matter of choice; there is no right or wrong answer and people need
to get over being right.

~~~
isxek
> SCM is a matter of choice; there is no right or wrong answer

That really sums it up. The right answer comes from seeing what you need and
using whatever tool fits the job.

------
idunning
A benefit of git, for which I can forgive a lot of git's flaws, that was not
mentioned in the conclusion is the light-weight branching. The ability to
quickly make a branch, experiment, branch off that, merge back, cherrypick
commits from another branch, etc. makes me more efficient by spending less
time worrying about affecting stable code with experimental changes.

~~~
jdjb
Yup this is exactly it. For developers fluent in git, it is a very real part
of their development cycle (branching, rebasing, etc). What I've seen of most
SVN (and going back to CVS) is that their SCM is more or less just an
archiving tool. A place after you've done all your hard work you use it as a
fancy rsync tool to back it up. I don't see a lot of SVN users making svn the
same part of their workflow the way git devs do. Maybe it's just the
developers I work with though.

------
ereyes01
re: the "Impractical for single repository of libraries" section... The author
seems to think the only way to manage many different plugins is to split them
into different repos: "If you have e.g. 100 plugins, you should have 100
repos."

Many times, 1 repo works perfectly fine for 100 plugins. As for wanting to
only work with a subset of the files, the way git wants you to do that is to
branch and change the subset you want to change (someone else has already
pointed that out too here in the comments). What to split into how many repos
is often a very subjective call, and depends on team, respository size, and
workflow.

A real-world example where 1 repo works perfectly fine is the Linux kernel.
Within one repo, you have all sorts of drivers for all sorts of hardware, and
you have arch-specific support for a dizzying amount of processors and
variants. The repo takes a while to clone the first time since it's kind of
big, but thereafter works perfectly fine as you whizz between branches and
jump between tags.

On some level, I understand the author's frustration with git, since it's
quite a paradigm shift from centralized repos like Subversion. I made that
shift myself once, and at first I didn't like being forced to play by git's
rules of the universe (or more correctly, the DVCS rules of the universe). I
have come to deeply appreciate those new rules over time.

There are, in fact, valid criticisms of git. One that comes to mind is the
complexity and amount of operations... looks like others have already
commented on this sort of criticism.

------
johnchristopher
> I can't also see any practical solution for a separation of concerns. Some
> users could e.g. work only on translation and need only to checkout XML
> files and push them back to the repo. With Git, that would have to be a
> separate repo.

I am far from being good with Git yet but why couldn't the translator simply
branch out and only merge back his XML files ?

~~~
rst
Perhaps the issue is that there's no technical barrier to them messing around
with something else, perhaps by accident. (And if you try to deal with this by
playing around with filesystem-level write positions in the repo, then they
can't pull down new versions of the rest of the project either.)

The only really clean solution is to use submodules (or the newer variation on
the theme, git subtree). But those aren't entirely smooth either.

~~~
bluecalm
The idea of Git is that everybody has their own local copy of a whole repo so
it doesn't really matter what they do with it or if they mess it up. If other
people want to merge the changes to their repos they will see what was changed
and what wasn't so if you get pull request from "XML only guy" you just verify
if only XML files were changed. You seem to think about it in terms of one
master which isn't Git way.

~~~
rst
And you're thinking about a workflow in which no one ever uses "git push". If
most devs do, and "the XML guy" can't (because someone else needs to look over
his commits), that's a headache, which could be solved technically.

Come to think of it, it could be solved technically even with git -- the XML
guy's repo gets a pre-commit hook that verifies that he's committing changes
only to the files he's allowed to edit. (We're now requiring him not to mess
with that hook, but if that's a problem, maybe they shouldn't have source code
access at all. The point is that now a tool is doing the checks, which frees
up the humans for things that really do require human judgment.)

------
keerthiko
I just wanted to say that even if you don't read this article, this discussion
here on HN is very enlightening for people who tend to only use a small subset
of git operations in their day-to-day small-team dev tasks (like me).

------
NumberSix
Git is overrated.

Other problems include:

o Complex, confusing terminology including multiple non-obvious names for
various components.

o Huge number, about 148, of commands with many sub-commands that often do
non-obvious, even unrelated things.

o git rebase enables users to rewrite history which subverts what should be
the main, if not only, function of a version control system.

o Git has been bundled with code review systems like Gerrit which encourages
developers to rebase heavily to create a false history presenting themselves
as fantasy 10X programmers who don't make mistakes, debug, engage in trial and
error, or all the other things developers actually do. When a bug does slip
through as if often does despite the supposed quality-control benefits of code
review, then reconstructing what happened from the rebased "history" can be a
nightmare.

o There are numerous commands to do similar, overlapping but nonetheless
different tasks. If for example you want to back up to earlier versions of
code you can do git revert, git reset --hard, git reset --soft, git checkout
-- <SHA>, git checkout <SHA> \-- all of which do different but overlapping
things.

o A supposed virtue of git is that it makes it extremely easy to create
"branches." This often leads to a proliferation of branches, making locating
changes and reconstructing the history of changes extremely difficult. A
change can occur on a local branch on one developer's computer, be rebased
into another local branch and then finally rebased or merged into the shared
"master" branch.

o Cryptic hexadecimal SHA for identifying commits instead of sequential
numbers for individual files as well as snapshots of the entire project. Even
if you track down the tricks to compile the SHA into a program or file name,
the SHA is not sequential making it difficult to know which version of a file
or group of files is in a program.

o These many flaws in git and its command line interface have resulted in a
proliferation of third-party add-on tools like the Android project's repo
utility, gitk, magit in Emacs, sourcetree, many of which fail to fully wrap
the complexity of Git forcing users to both master the wrapper tool and the
Git command line especially on more complex projects. Some of these
GUI/wrapper tools like Android repo seem to have serious bugs as well.

o Lack of backward compatibility with RCS-style version control systems like
Subversion. Instead of building on 30+ years of success and experience with
RCS-style version control systems, but extending them sensibly for distributed
projects, Git took a "reinvent the wheel badly" approach.

o A fanatical, cult-like following apparently mesmerized by Linus Torvalds
that is unable to recognize or acknowledge the many obvious problems with Git.

Yours truly,

Bit by Git

~~~
SeoxyS
Sounds like you were bit by rebasing, rather than by git itself.

Yes, the API is large and complex. But git itself is easy to learn, and
extremely powerful. Whatever situation you might have gotten yourself into,
git probably has a good way to handle it.

There's one rule I abide by, which makes my git usage sane: no rebasing.
Everything stays in the history, and there's _no reason_ to squash commits
into one giant context-less commit.

The only common case in which rebasing is valuable is in getting rid of
meaningless commits constantly merging the latest master into a feature
branch.

~~~
cozuya
I don't get the "rebasing sucks" argument about why git is bad, at all. Most
professional arenas will have a source control best practices document, how
hard is it to say "no rebasing allowed"? Just because a feature exists does
not mean it has to be used or even should ever be used.

------
tsmash
You could only come up with two things that no one ever runs in to?

Git has tons of problems but neither of these are important problems.

------
aikah
It's impressive how a software became a defacto standard when things like
mercurial or SVN existed long before it.It's not just hype or Github,though it
helps.It's the distributed nature of the software that makes it powerfull,
also the fact that git itself is more like a protocol than a piece of
software.But git dont work for every use cases though( big binary blobs ),so
there is still room on the market for such cases.

~~~
isxek
Mercurial was created around the same time as Git was (April 2005), and both
projects were announced in the Linux kernel mailing list.

You're probably referring to Bitkeeper, which did exist (and was available
commercially) before these new VCS's.

------
ramnes
> I also see no way this would work for branching. You would have to change
> all your submodules.

`git submodule foreach`

------
imcn
Use Magit, it's great.

------
Smudge
I'm a fan of using the right tool for the job. If you can't use git
effectively or it just doesn't fit into your workflow, then, hey, don't use
it.

But, having used both, I'd actually like to know... Why are these things (that
the author is claiming git can't do) so important? For instance, is checking
out a partial tree ever necessary? Is it that you'd want more granularity over
what subsets of the repo you are storing locally? Is it that you don't want to
have to set up a bunch of (sub-)repositories?

I ask because... I once worked on a codebase that was so absurdly huge most of
us couldn't store it all on disk at once. And it sucked. Hard. I WISH it had
been started as a bunch of distinct submodules, with extension points baked
into the core build system so it would be easy to add/remove sections of the
codebase. But the product predated git. And SVN for that matter. (Granted, the
majority of the issues we suffered -- nightmarishly complex build systems,
lack of transparency into what changes are being made, a bottleneck of devs
lining up to commit changes -- were caused by _process_ issues, not source
control. But the source control did absolutely nothing to _help_ either.)

I really understand the frustration when it comes to git. It took me a _LONG_
time to wrap my head around why it works the way it does, because I
wanted/expected it to work like SVN, where the repository is like a giant tree
of files reflecting exactly what I see on disk, with different branches of
code getting their own branch of the tree. Instead, git was this concise,
magical pile of data structures that somehow kept causing me to break things
whenever I strayed too far from a basic commit & push workflow.

But then I changed jobs a couple times. And, for some reason, I no longer
found git a huge pain. In part because it just started becoming more natural
and I knew what kinds of things to avoid, but also because I decided to sit
down and really learn what I was doing. For one thing, I began making more
active use of rebasing. Initially so I didn't need a ton of useless merge
commits to keep up-to-date with the master branch, but eventually as a way of
tidying up my work on a feature branch (i.s. squash, reorder, amend, etc) to
make the set of changes concise and easy to follow. When working locally on a
new feature branch, my commit log went from looking like this:

> okay one more try at part A [tests pass]

> fixing typo [tests pass]

> one last thing for part C [tests fail]

> part B bugfix [tests pass]

> fixing bug in part C [tests fail]

> finishing part B [tests fail]

> trying this again (feature A) [tests fail]

> part C, work in progress [tests fail]

> part A, I think [tests fail]

...

To this (more or less):

> part C [tests pass]

> part A (final implementation) [tests pass]

> part B [tests pass]

> part A (initial implementation) [tests pass]

...

Depending on who you are, you'll either love that, or you'll scream at my
lying, revisionist git log before wrenching out your eyes and hurling yourself
out a window. But, for me, for the team I was working with, and for the
codebase I was working on, it worked WONDERFULLY. I found myself feeling like
I really controlled the readability of my changes. Each of those commits could
be submitted individually for code review with no problems, and even though I
was wiping out a ton of minor changes, I could still preserve a record of
alternate implementations in case we wanted to refer to them later.

Anyway, this post has become a long ramble. But, suffice it to say, I've found
git to be very freeing. I just had to give up any expectations about how the
process would work, and let myself start forming a new process around the
power and flexibility that git offers. I believe I could say the same for
mercurial (though I don't have much experience on it). And I don't think I can
say as much for SVN, though I'm sure it does have a few advantages. And if
you're workflow really can't change... SVN certainly works for what it is.
It's just not something I'd ever like to go back to.

