Steve Bennett blogs

…about maps, open data, Git, and other tech.

10 things I hate about Git


Git is the source code version control system that is rapidly becoming the standard for open source projects. It has a powerful distributed model which allows advanced users to do tricky things with branches, and rewriting history. What a pity that it’s so hard to learn, has such an unpleasant command line interface, and treats its users with such utter contempt.

1. Complex information model

The information model is complicated – and you need to know all of it. As a point of reference, consider Subversion: you have files, a working directory, a repository, versions, branches, and tags. That’s pretty much everything you need to know. In fact, branches are tags, and files you already know about, so you really need to learn three new things. Versions are linear, with the odd merge. Now Git: you have files, a working tree, an index, a local repository, a remote repository, remotes (pointers to remote repositories), commits, treeishes (pointers to commits), branches, a stash… and you need to know all of it.

2. Crazy command line syntax

The command line syntax is completely arbitrary and inconsistent. Some “shortcuts” are graced with top level commands: “git pull” is exactly equivalent to “git fetch” followed by “git merge”. But the shortcut for “git branch” combined with “git checkout”? “git checkout -b”. Specifying filenames completely changes the semantics of some commands (“git commit” ignores local, unstaged changes in foo.txt; “git commit foo.txt” doesn’t). The various options of “git reset” do completely different things.

The most spectacular example of this is the command “git am”, which as far as I can tell, is something Linus hacked up and forced into the main codebase to solve a problem he was having one night. It combines email reading with patch applying, and thus uses a different patch syntax (specifically, one with email headers at the top).

3. Crappy documentation

The man pages are one almighty “fuck you”. They describe the commands from the perspective of a computer scientist, not a user. Case in point:

git-push – Update remote refs along with associated objects

Here’s a description for humans: git-push – Upload changes from your local repository into a remote repository

Update, another example: (thanks cgd)

git-rebase – Forward-port local commits to the updated upstream head

Translation: git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node

4. Information model sprawl

Remember the complicated information model in step 1? It keeps growing, like a cancer. Keep using Git, and more concepts will occasionally drop out of the sky: refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces

5. Leaky abstraction

Git doesn’t so much have a leaky abstraction as no abstraction. There is essentially no distinction between implementation detail and user interface. It’s understandable that an advanced user might need to know a little about how features are implemented, to grasp subtleties about various commands. But even beginners are quickly confronted with hideous internal details. In theory, there is the “plumbing” and “the porcelain” – but you’d better be a plumber to know how to work the porcelain.
A common response I get to complaints about Git’s command line complexity is that “you don’t need to use all those commands, you can use it like Subversion if that’s what you really want”. Rubbish. That’s like telling an old granny that the freeway isn’t scary, she can drive at 20kph in the left lane if she wants. Git doesn’t provide any useful subsets – every command soon requires another; even simple actions often require complex actions to undo or refine.
Here was the (well-intentioned!) advice from a GitHub maintainer of a project I’m working on (with apologies!):
  1. Find the merge base between your branch and master: ‘git merge-base master yourbranch’
  2. Assuming you’ve already committed your changes, rebased your commit onto the merge base, then create a new branch:
  3. git rebase –onto <basecommit> HEAD~1 HEAD
  4. git checkout -b my-new-branch
  5. Checkout your ruggedisation branch, and remove the commit you just rebased: ‘git reset –hard HEAD~1’
  6. Merge your new branch back into ruggedisation: ‘git merge my-new-branch’
  7. Checkout master (‘git checkout master’), merge your new branch in (‘git merge my-new-branch’), and check it works when merged, then remove the merge (‘git reset –hard HEAD~1’).
  8. Push your new branch (‘git push origin my-new-branch’) and log a pull request.
Translation: “It’s easy, Granny. Just rev to 6000, dump the clutch, and use wheel spin to get round the first corner. Up to third, then trail brake onto the freeway, late apexing but watch the marbles on the inside. Hard up to fifth, then handbrake turn to make the exit.”

6. Power for the maintainer, at the expense of the contributor

Most of the power of Git is aimed squarely at maintainers of codebases: people who have to merge contributions from a wide number of different sources, or who have to ensure a number of parallel development efforts result in a single, coherent, stable release. This is good. But the majority of Git users are not in this situation: they simply write code, often on a single branch for months at a time. Git is a 4 handle, dual boiler espresso machine – when all they need is instant.

Interestingly, I don’t think this trade-off is inherent in Git’s  design. It’s simply the result of ignoring the needs of normal users, and confusing architecture with interface. “Git is good” is true if speaking of architecture – but false of user interface. Someone could quite conceivably write an improved interface (easygit is a start) that hides unhelpful complexity such as the index and the local repository.

7. Unsafe version control

The fundamental promise of any version control system is this: “Once you put your precious source code in here, it’s safe. You can make any changes you like, and you can always get it back”. Git breaks this promise. Several ways a committer can irrevocably destroy the contents of a repository:

  1. git add . / … / git push -f origin master
  2. git push origin +master
  3. git rebase -i <some commit that has already been pushed and worked from> / git push

8. Burden of VCS maintainance pushed to contributors

In the traditional open source project, only one person had to deal with the complexities of branches and merges: the maintainer. Everyone else only had to update, commit, update, commit, update, commit… Git dumps the burden of  understanding complex version control on everyone – while making the maintainer’s job easier. Why would you do this to new contributors – those with nothing invested in the project, and every incentive to throw their hands up and leave?

9. Git history is a bunch of lies

The primary output of development work should be source code. Is a well-maintained history really such an important by-product? Most of the arguments for rebase, in particular, rely on aesthetic judgments about “messy merges” in the history, or “unreadable logs”. So rebase encourages you to lie in order to provide other developers with a “clean”, “uncluttered” history. Surely the correct solution is a better log output that can filter out these unwanted merges.

10. Simple tasks need so many commands

The point of working on an open source project is to make some changes, then share them with the world. In Subversion, this looks like:
  1. Make some changes
  2. svn commit

If your changes involve creating new files, there’s a tricky extra step:

  1. Make some changes
  2. svn add
  3. svn commit

For a Github-hosted project, the following is basically the bare minimum:

  1. Make some changes
  2. git add [not to be confused with svn add]
  3. git commit
  4. git push
  5. Your changes are still only halfway there. Now login to Github, find your commit, and issue a “pull request” so that someone downstream can merge it.

In reality though, the maintainer of that Github-hosted project will probably prefer your changes to be on feature branches. They’ll ask you to work like this:

  1. git checkout master [to make sure each new feature starts from the baseline]
  2. git checkout -b newfeature
  3. Make some changes
  4. git add [not to be confused with svn add]
  5. git commit
  6. git push
  7. Now login to Github, switch to your newfeature branch, and issue a “pull request” so that the maintainer can merge it.
So, to move your changes from your local directory to the actual project repository will be: add, commit, push, “click pull request”, pull, merge, push. (I think)

As an added bonus, here’s a diagram illustrating the commands a typical developer on a traditional Subversion project needed to know about to get their work done. This is the bread and butter of VCS: checking out a repository, committing changes, and getting updates.

“Bread and butter” commands and concepts needed to work with a remote Subversion repository.

And now here’s what you need to deal with for a typical Github-hosted project:

The “bread and butter” commands and concepts needed to work with a Github-hosted project.

If the power of Git is sophisticated branching and merging, then its weakness is the complexity of simple tasks.

Update (August 3, 2012)

This post has obviously struck a nerve, and gets a lot of traffic. Thought I’d address some of the most frequent comments.

  1. The comparison between a Subversion repository with commit access and a Git repository without it isn’t fair True. But that’s been my experience: most SVN repositories I’ve seen have many committers – it works better that way. Git (or at least Github) repositories tend not to: you’re expected to submit pull requests, even after you reach the “trusted” stage. Perhaps someone else would like to do a fairer apples-to-apples comparison.
  2. You’re just used to SVN There’s some truth to this, even though I haven’t done a huge amount of coding in SVN-based projects. Git’s commands and information model are still inherently difficult to learn, and the situation is not helped by using Subversion command names with different meanings (eg, “svn add” vs “git add”).
  3. But my life is so much better with Git, why are you against it? I’m not – I actually quite like the architecture and what it lets you do. You can be against a UI without being against the product.
  4. But you only need a few basic commands to get by. That hasn’t been my experience at all. You can just barely survive for a while with clone, add, commit, and checkout. But very soon you need rebase, push, pull, fetch , merge, status, log, and the annoyingly-commandless “pull request”. And before long, cherry-pick, reflog, etc etc…
  5. Use Mercurial instead! Sure, if you’re the lucky person who gets to choose the VCS used by your project.
  6. Subversion has even worse problems! Probably. This post is about Git’s deficiencies. Subversion’s own crappiness is no excuse.
  7. As a programmer, it’s worth investing time learning your tools. True, but beside the point. The point is, the tool is hard to learn and should be improved.
  8. If you can’t understand it, you must be dumb. True to an extent, but see the previous point.
  9. There’s a flaw in point X. You’re right. As of writing, over 80,000 people have viewed this post. Probably over 1000 have commented on it, on Reddit (530 comments), on Hacker News (250 comments), here (100 comments). All the many flaws, inaccuracies, mischaracterisations, generalisations and biases have been brought to light. If I’d known it would be so popular, I would have tried harder. Overall, the level of debate has actually been pretty good, so thank you all.

A few bonus command inconsistencies:

Reset/checkout

To reset one file in your working directory to its committed state:

git checkout file.txt

To reset every file in your working directory to its committed state:

git reset --hard

Remotes and branches

git checkout remotename/branchname
git pull remotename branchname

There’s another command where the separator is remotename:branchname, but I don’t recall right now.

Command options that are practically mandatory

And finally, a list of commands I’ve noticed which are almost useless without additional options.

Base command Useless functionality Useful command Useful functionality
git branch foo Creates a branch but does nothing with it git checkout -b foo Creates branch and switches to it
git remote Shows names of remotes git remote -v Shows names and URLs of remotes
git stash Stores modifications to tracked files, then rolls them back git stash -u Also does the same to untracked files
git branch Lists names of local branches git branch -rv Lists local and remote tracking branches; shows latest commit message
git rebase Destroy history blindfolded git rebase -i Lets you rewrite the upstream history of a branch, choosing which commits to keep, squash, or ditch.
git reset foo Unstages files git reset –hard
git reset –soft
Discards local modifications
Returns to another commit, but doesn’t touch working directory.
git add Nothing – prints warning git add .
git add -A
Stages all local modifications/additions
Stages all local modifications/additions/deletions

Update 2 (September 3, 2012)

A few interesting links:

1,018 responses to “10 things I hate about Git

  1. Tim Dettrick (@tjdett) February 27, 2012 at 11:28 am

    #7 only irrevocably destroys data in the remote repo if you 1) have no direct way to interact with it (eg. GitHub), 2) nobody has cloned the data in question and 3) if you don’t have your local repo to recover it from again.

    As long as (3) doesn’t apply, you can run `git fsck –unreachable` to recover your lost commits.

    Git is not meant to be user friendly or uncomplicated to beginners. Anybody who tells you otherwise is pulling your leg. Mercurial is meant to be (and still survives because of it), but it’s not quite as powerful as a result. Bazaar complicates things even more for reasons that escape me.

    Subversion doesn’t even count, because anybody can write a simple VCS if they don’t have to make it distributed. (Just like anybody can build a simple cluster, so long as it doesn’t have to be fault-tolerant.)

    • steveko February 27, 2012 at 12:56 pm

      Tim, you assume (as I think many Git users and developers do) that power and user-friendliness are somehow mutually incompatible. I don’t think Git is hard to use because it’s powerful. I think it’s hard to use because its developers never tried, and because they don’t value good user interfaces – including command lines. Git doesn’t say “sorry about the complexity, we’ve done everything we can to make it easy”, it says “Git’s hard, deal with it”.

      Here’s an interesting example: “git stash”, until a recent version, was basically broken: it left untracked files behnid, even though its man page stated that it left a “clean working directory”. They’ve now added a new option, “git stash -u”, which behaves the way git stash should always have worked. Now, making “git stash” perform incorrectly without the extra option is not “more powerful” – it’s just that they don’t value a sensible, intuitive user interface high enough to be willing to change the default behaviour from one version to the next.

      I also think the mess that is Git’s interface arose because DVCS was basically a new concept and they didn’t know all the features it would need. If they’d known about rebase at the start, it would have been more deeply integrated, something like “push –linear-merge”.

      (And your point about recoverability of “unrecoverable” Git commits is well made.)

      • Tim Dettrick (@tjdett) February 27, 2012 at 2:23 pm

        Steve, I didn’t mean to imply that powerful and user-friendliness are mutually incompatible. I completely agree that Git really doesn’t even try.

        I’ll come back to Mercurial (Hg) here to counterpoint – it’s the rival project, and it tries to be usable first, and powerful second. It does most of the things Git does, but tries to do it without hurting beginners. If the command is dangerous, you have to enable it on first. A good example is “rebase”, because it destroys history (though by default there’s a local backup). The equivalent to the Git “clean” command, “hg purge” is likewise an “only if enabled” command.

        There’s a trade-off though. There are things in Git, like “replace”, that will never be user-friendly because of what they do. In many cases Mercurial doesn’t even provide them, because a work-around exists and adding excessive numbers of commands works against their “user-friendly” aim.

        In Hg, you can’t remove or hide remote commits. Period. You want to rebase and push those commits again? You’ll need remote login access to strip the previous commits first. (BitBucket now provides a user interface for doing this.) Git makes it very easy to do this, on the assumption that you “know what you’re doing”. Hg makes it hard to do stupid things (like blow away public history), because it assumes you probably don’t.

        At my last job, I picked Hg for our developers for precisely this reason. I was very happy with it, and used to think all the Git enthusiasts nuts. I used to loath Git’s “shiny with sharp edges” nature. However after using it extensively it really is a better expert tool. I think the reason it’ll never become more user-friendly is because nobody who develops Git is interested in usability – there are other options for those that want them.

        Oh, and “rebase” is a separate command in both Hg & Git for a very good reason – it always modifies history, unlike a merge (which doesn’t ever modify history).

      • Andrew August 5, 2012 at 3:45 pm

        I totally agree with you that they didn’t try on the user interface, and that they were still discovering some of the features they needed out of DVCS.

        However, I think that the reason they didn’t focus on the UI was for the sake of the developers who would use the tool (and because they ate their own dog food). I would argue that the complex set of commands, and even some of the inconsistency, is for the sake of easy extension and integration. I think the set of commands is complex because they act almost as an API for applications to interface with Git, in a way similar to how many standard Unix utilities are useful for programming. The lack of abstraction leading to complexity is planned, I think, so that applications can have more control over how they interface. The inconsistencies are likely there so that they don’t break any existing applications which may depend on certain functionality (even if it isn’t to spec).

        Basically, Git is not intended for those who don’t want to learn a new, complex tool. It’s intended for developers. Not planning for it’s wide-spread adoption may have been a fault of the project. However, I think the API-like interface also provides opportunities that would not be available had Git gone with a clean, abstracted interface.

      • steveko August 5, 2012 at 9:45 pm

        “Basically, Git is not intended for those who don’t want to learn a new, complex tool. It’s intended for developers.”

        I think your assumption that developers want to, or at least can be expected to, spend time learning developer tools is misguided. It was more reasonable 20 years ago. These days, we have so many tools and technologies to deal with, that they all must be made as learnable and intuitive as possible.

      • coderjoe August 6, 2012 at 2:54 am

        I don’t feel like your git stash example is entirely fair.

        Nowhere in any of the git documentation does it say that it will operate on untracked files other than in the documentation for git add and commands which do an implicit add. git stash worked exactly the way it was described. Just like the vast majority of the git commands they work on the working directory’s tracked files. Not every file in the working directory regardless of if it is tracked or not.

        Honestly if git stash worked the way you describe (the -u option being the default) it wouldn’t work the way I wanted it to and I’d be much more hesitant to use it!

        To say that git stash performed incorrectly is to push your own opinion on what the correct action of stash should be while ignoring the way that git operates.

        If git stash -u was the default you probably still wouldn’t have liked it. You’d just cherry pick it as a completely different example. I could see you having written something like the following:

        “Yet another example of the inconsistency in git is ‘git stash’. Where most of the commands in git operate on a set of tracked files in the working directory, git stash works on the working directory as a whole. This can cause confusion when you end up stashing and essentially removing hidden or meta-data files in your source code which weren’t meant to be tracked by version control as a side effect of temporarily stashing some changes.”

        It feels a little bit like you’ve started with the conclusion “I hate git because it is inconsistent and the commands are needlessly confusing” and are searching for examples to prove it. Instead the better action would be trying to learn how git is used as git, why it works for the developers using it, and forming a conclusion afterwards.

        That said, it does seem like you have in fact given git a try. I’m not sure the above characterization is entirely fair… but it is the impression I get from the cherry picked examples with no care given to how it fits into the workflow of a developer using git.

      • moswald August 6, 2012 at 5:48 am

        I disagree that Mercurial is less powerful than Git. Out of the box, it’s barely crippled due to the more advanced features being disabled by default; once enabled Mercurial is more powerful than Git, while still maintaining the ease-of-use of before.

        Check out Mercurial Patch Queues. http://stevelosh.com/blog/2010/08/a-git-users-guide-to-mercurial-queues/

      • CC August 6, 2012 at 6:05 pm

        “Subversion doesn’t even count, because anybody can write a simple VCS if they don’t have to make it distributed.” You truly have no idea what you’re talking about. it was a wholly different world when Karl Fogel and company wrote SVN. You seem to have no concept of how difficult it is was to create SVN in a world where there were few good tools, very little OSS, and a much more limited concept of VCS. That SVN succeeded so well at the task you dismiss out of hand is corroborated by its wide and enduring popularity.

      • bob December 18, 2013 at 12:10 am

        basically you want git to bend to your will while thousand use it and don’t agree with you.
        to bad :)

      • sfkleach December 6, 2014 at 1:35 am

        You put your comments in an excellent and well-balanced way as usual – a pleasure to read. I use and enjoy using git every day but it’s by no means my idea of an ideal tool & your comments rightly target both the inarguable shortcomings and the closed-minded defensiveness of the UNIX community.

        I particularly have sympathy with your humorous summary “Git’s hard, deal with it.” It reminds me of a colleague who once remarked “Unix – you want friendly? Get a dog.”

        For me, I have found SmartGit/Hg to be a wonderful utility that has opened up the power of git to me without screwing up my projects & it means I can basically forget about the command line for almost everything. I’ve tried many of other tools in anger and, for what is it worth, I think SmartGit/Hg is the simplest and best – and gets significantly better every version.

        I have no affiliation with Syntevo or their product. This is simply my personal recommendation. I don’t have much money to spend on software these days, being a dad of three kids means I am perpetually poor, but I shelled out for this product because it meant I could use it at work, at home on my hobbies and on my open source projects in Windows, OS X and Linux. Syntevo have genuinely impressed me.

      • Ravi March 28, 2016 at 6:47 am

        Life is too short to spend all on learning the power of GIT. Do you learn all engine mechanism when you buy a car? Car does solve your problem. To make it easy and powerful , you make different interfaces and abstractions (can achieve in same commandline). To do it, empty your cup and keep your reasoning reasonable to real world scenarios.

        I have used mercurial, far easy and does job well than GIT. I don’t know why there is hype over GIT. What I will do with its almighty power, when it takes long to learn.

        If GIT does not simplify its workflow and commands, other variant will come out of frustration because the community failed to recognize pain.

      • mangocats May 3, 2016 at 1:56 am

        Thanks for voicing these concerns, and I believe git is (slowly) moving toward being more user friendly. Some developers tried to force the git kool-aid on me in 2009, and I steadfastly resisted, I was happier living in svn-hell than trying to make the jump to something “worse.” By 2013, I was forcing the git kool-aid on others, and liking it better than svn, it had matured considerably in the meantime and gotten much better integration with other tools.

        Keep pointing out the flaws, once people adopt git they tend to forgit how seriously messed up it is, just because it is so much better than what they left. I’m introducing a new group to git as I type this, and they’re feeling the pain. It still could be easier than it is.

      • Rafael Nicoletti June 17, 2016 at 12:53 am

        For a clean repository after git stash, one can, prior the stash, git add .
        This will send all untracked files into the stash afterwards.

      • yodaiken December 28, 2016 at 1:19 am

        It was not a new concept. Git took a lot from BitKeeper which was not only not new but was deeply familiar to Kernel developers after years of use.

      • Andrew Finnell August 18, 2019 at 3:00 am

        I’ve been using git for at least five years now, if not more. The only commands I’ve ever had to use are:

        git pull : Get the remote commits
        git push : Put my commits
        git commit : Create a commit
        git checkout : revert a file
        git checkout -b : create a branch
        git rebase : rewrite my local history to make it look as through the previous commits were always there to begin with. (rarely use this)

        People make this more complicated then it needs to be. They either try porting over their concept of how SVN works and try to apply it to git. Or they start making needlessly complicated choices with how they want to manage their VCS.

    • mark March 22, 2012 at 10:45 am

      how does bzr complicate things even more?

    • johannesnicolai January 8, 2013 at 3:55 am

      If you are worried about #7 (git push -f and accidental remote branch deletions) have a look at http://luksza.org/2012/cool-git-stuff-from-collabnet-potsdam-team/

  2. steveko February 27, 2012 at 4:52 pm

    So in terms of useful functional for you daily work, what couldn’t Mercurial do that Git could?

    One thing I find a bit frustrating in this whole debate is that in theory, interface and underlying capabilities should be separate and interchangeable. It ought to be possible to have a git-like interface Mercurial if you want that extra power (eg, rewriting published history), and it ought to be possible to have a Mercurial-like interface to Git for ease of use. But for some reason (perhaps because of CLI’s dual role in scripting) that never really happens.

    Incidentally, notice that “git clean” also by default is disabled: clearly the Git developers are capable of making intelligent user interface choices. But instead of this output:

    fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean

    how about:
    “clean wipes all untracked files from the working tree. Use ‘git -f’ or unset clean.requireForce if you’re sure. Use ‘git -n’ for a dry run.”

    Ok, now I’m just dreaming.

    • Abraka Dabra November 21, 2016 at 8:55 am

      Steveko (and a few more people here) are very reasonable in their expectations that in the year 2016 we deserve to have tools with smart, rather than cryptic, user interface. And smart error and warning messages, that respect the user. But the Linux community was always opposite from that. Why?

      Well, they’ve spent half of their life learning to use cryptic commands, and now they don’t want them simplified. But why? Here’s why:

      1. Now that they have learned everything by heart, it seems easy. They’ve forget their own pain and now don’t understand how others can find it hard to learn. Why wouldn’t you spend a few months on this tool, a few years on that tool, another few years on another tool. After all we know that an average human being lives for 800 years, out of which the youth lasts for the first 750. Right?

      2. Now that they’ve learned the tool, they don’t want user interface to change. Because that would mean they would have to learn it again. And feel that pain again… hmmmm, maybe that’s exactly what they deserve.

      3. Now that they know how to use the tool, why would newbies have it any easier than they had? Let them go through the same hell. Let everyone forever use crappy UI just because they had to use it. Let in the 24th century Capt. Picard of the Enterprise be blown away by Klingons because the ‘git am’ patch didn’t apply the new photon torpedo launch procedure.

      • sfkleach November 21, 2016 at 10:32 am

        At the risk of over-repetition, tools that provide a friendly and much easier-to-understand front-end to git already exist. My favourite is SmartGit, which I have used for several years, but I am now using Sourcetree at work and I have to say that I am very comfortable with it too. It would be lovely to have the command-line interface tidied up but there’s no great urgency to do so when you have excellent GUIs like these. To everyone who is wrestling with the command-line – destress your life by downloading SmartGit, Sourcetree and GitKraken then picking the one you fancy.

      • arnebab November 21, 2016 at 7:06 pm

        Attributing this to the “Linux community” is false. The Linux community is also the origin of Mercurial (which is feature-equal to git and with a much easier command line interface – it is not only also from the Linux community, but just like git from Linux kernel developers) as well as wonderful graphical interfaces like TortoiseHG and KDE’s Dolphin.

        There is a group of people who do not value good interfaces. But they are a subset of computer users, not a subset of the Linux community. And within the Linux community we at the same time have people who don’t value good interfaces and those who value them very much.

  3. Tim Dettrick (@tjdett) February 27, 2012 at 6:15 pm

    > So in terms of useful functional for you daily work, what
    > couldn’t Mercurial do that Git could?

    Very little. Mercurial doesn’t have the index (modified files are just committed) but it has the “MQ” plugin which can handle the same behaviour. Light-weight branches are slightly more fiddly with Hg bookmarks, but they’re a reasonable approximation to Git’s branches now. (Took long enough though….)

    I could not have easily done the CoreTardis-MyTardis history join with Mercurial, but that’s hardly day-to-day.

    > It ought to be possible to have a git-like interface Mercurial
    > if you want that extra power (eg, rewriting published history),

    That would be nice, but the Hg devs would probably prevent any core changes that would allow that behaviour, and I don’t think plugins can influence the wire protocol. Their aim is to avoid lost commits at the expense of “things you misguidedly might think are a good idea”. You might be able to trigger it via remote hooks somehow though.

    This is a good example of the mindset of the average Hg user:
    http://jordi.inversethought.com/blog/i-hate-git/

    “I didn’t even *consider* that a VCS could remotely *delete anything*.”

    > and it ought to be possible to have a Mercurial-like
    > interface to Git for ease of use.

    It’s called Hg-Git. ;-)
    http://hg-git.github.com/

    • Jordi Gutiérrez Hermoso March 7, 2012 at 6:57 am

      Average hg user here…

      hg-git is a crutch. I’ve tried it a few times. It sometimes didn’t work at all, and I was unable to push from an hg repo to a git one. I didn’t figure out what the problem was, but the real problem for me is that people use git, and I have to work with them.

      The are also other more fundamental problems that git-hg can’t solve, such as how hg stores different metadata (e.g. branch names) that are unrepresentable in git.

      I wish I could just avoid using git, I really do, but there’s a whole community of people there who make it impossible.

      • Arne Babenhauserheide September 3, 2012 at 4:33 pm

        I use hg-git whenever I interact with a git repo. When I use it for larger-scale development, I use a bridge repo (hg clone git://… git-bridge) so I have one point of interaction with git. For working on something I then clone the bridge-repo, hack on it, push back into the bridge repo and push from the bridge repo into git.

        (that’s the old outgoing-incoming repo structure :) )

    • Arne Babenhauserheide September 3, 2012 at 4:53 pm

      For merging history, did you check the convert extension? That can rewrite filepaths, get partial history and all that stuff.

      If the history is similar you likely don’t even need that:

      The honest way (shows the real merge: do this if dishonest history is no requirement):

      cd repo1
      hg pull –force repo2
      hg merge
      hg commit -m “merged repo1 and repo2”

      The rebase way:

      cd repo1
      hg pull -f repo2
      hg phase -d -r “all()” # allow rewriting published history
      hg rebase -s -d .

      The regrafting (can join anything, but is more work):

      hg init newrepo
      hg pull -f repo1
      hg pull -f repo2
      hg graft $(hg log –template “{node} ”
      hg phase -d -r “all()”
      hg strip
      hg strip

      • Arne Babenhauserheide September 4, 2012 at 10:31 pm

        hm, lost a tag to the filter… rebase way again:

        The rebase way:
        cd repo1
        hg pull -f repo2
        hg phase -d -r “all()” # allow rewriting published history
        hg rebase -s [first commit of repo2] -d .

        and regraft:

        hg init newrepo
        hg pull -f repo1
        hg pull -f repo2
        hg graft $(hg log –template “{node} ”
        hg phase -d -r “all()”
        hg strip [first commit of repo 1]
        hg strip [first commit of repo 2]

  4. Matt March 9, 2012 at 3:17 am

    Your git diagram illustrates how to contribute to a project that you are not an approve contributor on.

    How would you contribute to a subversion hosted project that you didn’t have permission to contribute to? Most projects have tight reins over who can contribute, and they would tell you to submit a patch.

    These extra steps should be included in your subversion diagram.

    • steveko March 9, 2012 at 9:23 am

      My guess, based on admittedly limited experience, is that it was much more common to grant direct commit access on Subversion projects than Git ones. MediaWiki is a case in point: it had dozens, perhaps hundreds of committers. It’s currently switching to Git, and simultaneously switching to the “gated trunk” model with very few direct committers. They’re also using Gerrit, a code review tool, which I understand to be a whole extra source of VCS pain :)

      But yes, perhaps I should include patch submission as an alternative path in both diagrams.

      • Aaron Traas August 6, 2012 at 12:12 am

        The way it used to work when everyone used CVS/SVN was to submit patches by email. Commit access was still pretty guarded, as unknown people can’t be trusted not to be assholes.

      • Aaron Traas August 6, 2012 at 12:14 am

        Most projects would accept patches by email from new/unproven devs in the SVN/CVS days.

      • Jens Melgaard November 22, 2013 at 8:00 pm

        Keep in mind that just because many Open-Source projects does that, doesn’t mean all have to, if you feel more like just allowing people to commit to your repository, then by all means… After all Forks and Pull-Requests isn’t even a Git thing, it’s a Github thing… (and other Git tools tend to begin to follow suit, like Stash)

        I see it as a great feature…

        Just allowing commit access to your repository is fine as long as there are few contributors, but how will you ever make sure that your projects stays on it’s track towards it’s vision if you allow thousands of contributors commit access?, even open source projects need someone at the rudder… I know from a “patchers” perspective, it may be a bit cumbersome, but as the tools get along it gets easier and easier to work this way, and today it’s mostly done with a single click of a button… All the commands are neatly hidden beneath…

        Turn it around, many/most open source projects are handled in spare time, giving the repository owners more tools to manage what is accepted into the project at the expense of the developers time may seem ridiculous at first. But for each 15 minutes you may spend extra, you may save 5 minutes of the owners time… Try to multiply that by a thousands… If it becomes to big of a task to accept incoming patches, they bulk up and some of them will never be accepted because there simply isn’t enough time…

        The Github model speeds that up for the owners by an incredible huge factor… Yes at the expense of your time… But in the end it means that more contributions are accepted in the end, doesn’t that serve everybody’s interest?

  5. Dan Carley March 9, 2012 at 4:23 am

    Agreed, it is complex.

    #7: Contributors with push access need to be painfully aware of what forcing a push does. It’s pretty rare that you should have to use it. If private hosting with Gitolite you can use ACLs to prevent rewinds on branches; a force push being an extreme form of rewind+ff. It’s a pity this isn’t possible on Github. However it’s worth noting that the old history is probably still available in your reflog and in other people’s clones.

    #9: Much the same applies to rebasing. It’s a really useful tool. Many SVN users procrastinate committing their work before they are 100% happy. That’s a complete anti-pattern for VCS. Git encourages you to commit frequently with the promise that you can tidy up later. The only rule of thumb being that you shouldn’t rebase a commit that has already been pushed; which would require a force.

    #10: That’s a poor comparison. You assume that the SVN user has direct commit access to their own project but the Git user is collaborating with third-parties on Github.

    • steveko March 9, 2012 at 9:29 am

      Re: #9, I think the same “anti-pattern” applies to Git. The difference is with Git you commit frequently to your *local* repository. If you frequently commit small, poorly-defined chunks of work to a public repository you will soon receive complaints. And while Git “promise[s] that you can tidy up later”, for novice and intermediate users, that tidying up is extremely difficult. (Witness the lead maintainer of a Git hosted project confessing insufficient “Git-fu” to cherry pick a series of commits here)

      Re: #10: Intentionally, because SVN is associated with a culture of direct committing, and Git isn’t. (And because that’s my direct experience based on three projects I’ve worked on that switched from SVN to Git.)

      • robertmeta (@robertmeta) August 5, 2012 at 2:06 pm

        Your assumption that those local commits have no value is wrong. They ability to locally commit and use it as a worklog is fantastic, and if you fix a bug you can just cherry-pick it to a production branch from that local branch. Following on that, the idea the squash and cherry-pick are complex commands is borderline insane to me, they are both exceptionally straightforward, some of the easiest parts of git to learn… it sounds like someone has never bothered to try them if they are having issues with them.

        Seriously, let me teach you git cherry-pick. Find the commit you want… note its hash. Checkout the branch you want that applied to… git cherry-pick … you now have enough git-fu to cherry-pick.

        Regarding cleaning up existing commits (extremely difficulty according to you). So, lets say you have done 8 ugly commits, and you want to clean them up…. git rebase -i HEAD~8 … it will combine those into one commit and pop up your editor with all your commit messages allowing you to summarize / write-up whatever you want.

        I suspect people are confusing git being hard, with an absolute inability to be bothered to learn the tool.

      • steveko August 5, 2012 at 9:43 pm

        I’ve used ‘git squash’ (or rather, ‘git commit’ in interactive mode), and find it unintuitive – I rarely get the result I want on the first try. The problem is that “squashing” a commit really means combining it with another – but I never remember if it combines it with the previous or next commit.

        ‘git cherry-pick’ is fairly straightforward, and works – but usually feels like a workaround when something has gone wrong.

        “I suspect people are confusing git being hard, with an absolute inability to be bothered to learn the tool.”

        Not in my case.

  6. Jim Ryan March 9, 2012 at 4:45 am

    Understanding that mq is hg’s answer to the index/rebasing/etc. –
    that’s a problem for me, because I find mq pretty awful. It amounts to a new VCS, except its interface is not really more usable than git. So why am I using hg, again? Even if hg is easier and saner at the beginning, if you need staging then git very quickly becomes easier because hg requires you to use mq to work on your commits, while git allows you to use a pretty good VCS to work on your commits (namely, git).

    I should not be forced to start proliferating working copies just to put together clean commits to a public repo, that is insanity.

    • André Felipe Dias May 2, 2012 at 11:54 pm

      Why use mq at all? Hg doesn’t force you to have a stage area as git does. I have never needed something like this and I’m pretty fine this way.
      The workflow should be kept as simple as possible. I think that #8 “Burden of VCS maintainance pushed to contributors” is particularly interesting.

      Great article!

      • Matt August 5, 2012 at 10:51 pm

        One of the main points of git is that maintenance is pushed to the edge, it allows for greater scaling. Imagine if Linus had to do the house keeping for every coder on the kernel; nothing would be achieved. It’s not a bug, it’s a feature.

      • Arne Babenhauserheide September 3, 2012 at 5:20 pm

        Matt :
        It’s not a bug, it’s a feature.

        It’s a system which is easy to use for maintainers but hard for contributors and which places most of the workload onto the contributors.

        Shouldn’t a system which places more work on the contributors be especially easy to use for contributors?

  7. Olav March 9, 2012 at 7:47 am

    And then there is http://fossil-scm.org/ with is a pleasure to use.

  8. Larry McVoy March 9, 2012 at 9:53 am

    I’ll get yelled at for this one, but before all of these systems there was BitKeeper, we’re still here and if you want the power of DVCS and not all the gotchas of a sharp and pointy Git, check us out. Expensive but we do stuff that you can’t do in Git (yet, I’m sure they’ll catch up).

    • steveko March 9, 2012 at 9:59 am

      The annoying thing about VCS, compared to say, an editor, is that the basic rule of “if you don’t like it, use something else” doesn’t apply. (So in my case, since I never start open source projects, I’ll never get to choose a Git alternative.) It’s a pity the DVCS authors haven’t been able to separate interface from infrastructure, coming up with a robust information model that different front ends could support.

    • Jordi Gutiérrez Hermoso March 9, 2012 at 10:01 am

      I wouldn’t mind paying for bitkeeper if you made it free. I have paid for free software, but the non-free stuff you did to Linux about forbidding reverse-engineering the protocol is unforgivable, especially if you plan to keep on doing that.

  9. JJ March 9, 2012 at 9:49 pm

    I Agree!!
    I’m still trying to figure out how to use Git. It’s just not logical … well for me at least. Most of the time I’m the only one working on it and just want to be able to securely store it off-site at my hosting provider with the ability to roll-back if needs be – Simpler would have been much better

  10. Red Toby March 9, 2012 at 10:07 pm

    The very defensive counter arguments from self proclaimed powerusers, is very shaky. There are just so many permutations of potential error and problems with Git that even power users are most likely ignorant of just how many errors they introduce into thier beloved system.

    Reminds me of the DOS WordPress defenses.

    Glad to find out about Mercurial

  11. Vincent March 9, 2012 at 10:33 pm

    Heh, what you expect from “below average” Torvalds, who created such rubbish as Linux?? :) He writes as he thinks.
    Mercurial, having the same powerful features, looks way more professional.

    • steveko March 9, 2012 at 11:03 pm

      I’ve got nothing against the approach that led to Git being created. I just wish that:

      1. Its developers recognised the value of clear abstractions and good UI design (even for command-line)
      2. Its users and developers were more willing to break backward compatibility of the interface in order to improve it
      • Arne Babenhauserheide September 3, 2012 at 5:26 pm

        Since git relies on shell scripts for extensions, you cannot actually change the commands without breaking everyones scripts…

        That porcellaine is pretty much set in stone, but the name fits since it makes everything built on it extremely brittle…

      • rdm September 4, 2012 at 1:23 am

        steveko :
        I think some issues with Git can be summarised as “it forces you to structure the *changes* to your code, in addition to the code itself”. Sometimes (in established, large projects), that forced structure is a good thing. Sometimes (for beginners, and in smaller projects), it’s a hindrance.

        How are you forced by git to make feature branches? If you like you can work directly in mater and never create any branches. Or, if you can prefer, you can make all your changes in the same branch (and then pull that into master, this might be good if you are using github).

        I hope that at least some people here are able to distinguish between “git” and “github” as well as being able to distinguish between “a good idea” and “being forced”.

        Arne Babenhauserheide :
        Since git relies on shell scripts for extensions, you cannot actually change the commands without breaking everyones scripts…
        That porcellaine is pretty much set in stone, but the name fits since it makes everything built on it extremely brittle…

        Why should you need to change the commands?

        In general, when dealing with an interface of any sort, you never change existing interfaces, you only add new interfaces. You do not even deprecate old interfaces until after you have addressed most all of the needs being addressed by the older forms. (And deprecating basically means you go for some period of years with the old interfaces working, but setting off warnings when they are used.) In some cases you can get away with deeper changes (like when there’s an accepted spec and you are living within it), but you need to be careful — that way lies madness if you go too far. Actually, introducing new interfaces can get crazy also. The most useful thing you can do with most interface changes is to reject them…

        Still, when you have a good interface change, and you’re ready to deploy it? You can do that.

        For example, currently git clown will not do anything except ask whether you meant “clean” or “clone”, but if you had a good interface design for git clown, nothing would conflict with your implementing it.

        Of course, and this is worth repeating: then you have to ask yourself, why anyone should need a “git clown”…

      • steveko September 4, 2012 at 11:40 am

        How are you forced by git to make feature branches? If you like you can work directly in mater and never create any branches.

        Git, despite its protestations, is a social tool. Decisions like these “If you like, you can do X” are rarely up to one person – you need to do what the team does.

      • rdm September 5, 2012 at 12:18 am

        steveko :

        How are you forced by git to make feature branches? If you like you can work directly in mater and never create any branches.

        Git, despite its protestations, is a social tool. Decisions like these “If you like, you can do X” are rarely up to one person – you need to do what the team does.

        This implies that solutions to these issues need to be social rather than technical.

      • Arne Babenhauserheide September 4, 2012 at 10:27 pm

        rdm :
        Why should you need to change the commands?

        Because if you are not already used to git, the current commands are pretty unintuitive and hard to learn.

        If you want an unchanging interface, you have to design it cleanly from the start and be extremely conservative with changes. Otherwise you get help output as the one seen in `git help pull`, because you can never throw out a bad idea later on.

        And the easiest way to state that you want an unchanging interface is to tell people to use it in scripts. As soon as you have enough users, every change to an existing option wreaks havoc to so many scripts which you do not control, that you cannot actually do the change.

      • Russ Nelson March 7, 2014 at 5:39 pm

        Arne is confusing the API, where your semantics are fixed once you name them, with user interface. The fact that the API and the commands can both be accessed by the shell *is* confusing.

  12. itoctopus March 9, 2012 at 11:52 pm

    “Git history is a bunch of lies” – I second this one – we do have to lie as well so we can have a clean history! It’s not acceptable!

  13. Henrik March 10, 2012 at 1:05 am

    This kind of simplified FUD is just not constructive. Anything you can do in subversion you can also do in git.

    Try to maintain a large project in Subversion before you say such things. Its a horror and all the simple things about the subversion api is just not worth anything.

    No, FUD is what it is.

    • Arne Babenhauserheide September 3, 2012 at 5:28 pm

      In git the regularly used simple things are hard and the seldomly used hard things are simple.

      Your answer belies the exact mindset which makes git so unwelcoming.

    • Andy Bolstridge May 24, 2014 at 8:26 am

      Actually to maintain a large project in SVN is quite easy – you can easily checkout partial bits, merging and branching can apply to sub-sections of the repo (which is why svn merging isn’t quite as good as gits, it has to deal with more complexity). I worked on a 3Gb repo at a previous company, without any problems.

      Part of the problem is that no-one considers the cases of a system they always prefer to spread FUD in favour of their preferred system. Don’t criticise someone else for spreading FUD and then do it yourself!

  14. Andy March 10, 2012 at 1:08 am

    And *this* is why I avoid open source like the plague!

  15. Jim Blackler March 10, 2012 at 1:34 am

    Git has beautiful technical design but quite appalling usability design.

    You can Commit, Fetch, Merge, Publish, Pull, Push, Rebase, Stage, Stash and Track. To a beginner these all sound like they might do the same thing.

  16. man_with_no_name March 10, 2012 at 1:52 am

    #6 and #8 and #10 strike at the crux. git is thoroughly decentralized, to the point where everyone is a peer. Everyone is a committer, everyone is a maintainer. Branches and tags are unshared by default. Someone could potentially interact with many other peers, and hence have many “remotes”. To some degree, this level of decentralization is just a total paradigm shift. As others have mentioned, Mercurial is more moderate in this way.

    No argument from me about the learning curve and negative usability of the information model, documentation, and commands.

    • steveko March 10, 2012 at 10:56 am

      “Everyone is a committer, everyone is a maintainer.”

      Well put – humble contributors never had to be maintainers before.

  17. Steve Hermes March 10, 2012 at 1:56 am

    SVN is still around, there’s a reason for that.

    • Q August 5, 2012 at 5:39 pm

      «Visual SourceSafe Is still around, there’s a reason for that.»

      And for both that reason it’s called “loss aversion”.

      • mikera7 December 22, 2012 at 7:48 pm

        You mean “transition costs” rather than “loss aversion” I believe. And that’s a perfectly valid reason to stick with something if the benefits from switching aren’t high enough.

  18. Glenn Lee Kian Giap March 10, 2012 at 2:00 am

    A rubbish article, compare apple with orange. Please identify what you are comparing? Distributed VCS or Centralised VCS, you should either present how SVN being use in distributed environment in order to compare with the Git having the same usage, or present how Git being used in centralized environment in order to compare with SVN having the same usage. This will benefit newcomers to learn how thy should use them and which tool is more suitable.

  19. chris March 10, 2012 at 2:33 am

    one of the best complaint about GIt I’ve ever heard, I completely agree with you !

    I can even add :
    1/ no decent IDE support (for ex, in eclipse Git has a completely different GUI from svn or cvs : where is my commit messages history, the possiblity to ignore untrack files, …)

    2/ once you’ve screwed something, it is really hard to go back.
    For ex, if you fetch then commit then push … OMG you’ve forgoten to merge so the remote repo say “no, you can not commit” but this can be a real pain to merge you own local copy with “itself”

  20. alex March 10, 2012 at 5:16 am

    For my code to be safe I have to feel in cotrol of it. With git I feel lost and insecure. How safe is my code?
    Glad to see I’m not alone with this feeling…

    • Jeffry Johnston September 1, 2015 at 8:30 am

      For my code to be safe I have to use a tool that safeguards my code from the ground up, and I must use that tool properly. Feeling has little to do with it, but nevertheless, with git I feel powerful and completely in control. How safe is my code? I have never lost any code with git. Glad to see I’m not alone with this feeling…

  21. Adam Thompson March 10, 2012 at 5:25 am

    I like git. I have used SVN, TFS, and though shamed to admit it, VSS (against my will).

    Here is an assessment from my point of view.
    TFS – Hands down the best option for a large team of .NET developers working a single project. However I find it’s overkill in smaller project with say 1-5 developers. It’s just too involved.

    VSS – Total Crap! if you use this product willingly, you should be drug out into the street and shot. This is where I could go an a rant but I wont. Just google VSS and you will see.

    SVN – Great open source source control. There is not a lot to complain about. There are a lot of great add-on’s available for visual studio as well. As a mater of fact my home development server ran SVN for years. However, I did switch every thing over to git. My issue with SVN is the same as my issue with TFS, It’s just too involved. You have t have a server just like TFS. There is administration work involved just like TFS. I didn’t realize I could git by without these tasks until I started using git. Like TFS though, it’s a better option for larger teams.

    GIT – Fast, Flexible, and easy. It’s takes me all of 2 seconds to set up a new repository. I have retired my “development server” and just use Dropbox, Github, or Bitbucket (Check out Bitbucket if you don’t allready know about it. The are just like Github, but you can have free private repos) as my remote. It’s so fast and simple that for me it takes the work out of source control. I do feel that TFS or SVN is better for larger groups though due to all the Administration options available. There are just more ways to manage them that are not really necessary for smaller teams. The other downside of git is that some folks are afraid of command line tools for some reason. My advice to this person is to grow a pair and learn the tool because it’s worth it. You won’t find me talking that way about any other command line tool period and I have to use svcutil, stsadm, and a couple of others out of necessity. I don’t go around talking them up because they would be better as GUI tools in my opinion. With git I feel this is not the case. The BASH makes it faster which is what I truly love about git to begin with.

    That’s my 2 cents. Take it for what you will.

    -Adam

    • imMute June 8, 2012 at 12:57 pm

      As someone who is forced to use TFS in a situation that TFS wasn’t made for (non Visual Studio work), I loathe it with a passion.
      I’m sure it’s great for VS users, but us linuxy guys get totally shit on.

      And as a related note, who the hell thought it was a good idea to use the write bit of the permissions as the is-this-checked-out flag?!

  22. tuseroni March 10, 2012 at 7:58 am

    git follows a simple unix philosophy: make it scriptable.
    and also “do one thing, do it well” (this applies to the individual parts, git is made of a bunch of smaller programs that make up the whole suite not just one monolithic program)
    all the command line things are made to be scripted and if someone wanted to make a simple GUI for git they could, just no one care enough. just about everyone who uses it, and everyone who uses it and has the capacity to make the gui, don’t care enough to make one. they are fine with the script and programs that make up the git suite.

    also you mentioned above the basic commit:
    git add
    git commit
    git push
    you can script that to have one script do all those, call it “checkin.sh” or something
    #!/bin/bash
    (git add && get commit && git push && echo “done”)|| echo “failed”;

    anything you find yourself doing often can be dumped into a script, that is the philosophy behind it, leave matters of interface to other people, design the system to be fast, handle merging well, be distributed, etc but allow it to be scriptable so people can build interfaces on top of it to their hearts content.

    • steveko March 10, 2012 at 11:02 am

      I actually think git fails on both those counts.

      1. “do one thing, do it well” – Git tries to be both the infrastructure (which I think it does well) and the interface (which it does terribly). The hodge podge of really commands (“git am” being my favourite) is testament to this.
      2. “make it scriptable” – It’s much easier to script things with consistent behaviours and easily understood commands.

      But yes, you can obviously script your way around anything for one local environment. Not a great solution, in my experience, if you’re frequently working on different environments, and in different teams. (“You’re having trouble committing? My “gitcommit” script runs just fine…”)

    • Arne Babenhauserheide September 3, 2012 at 5:33 pm

      By making it scriptable using the basic commands, they pretty much barred their way towards ever having a simple interface.

      If they change one of their core commands in a backwards-incompatible way, all user-scripts break. And this already happened (there was a simpler git ui whose name I forgot. It tried to wrap around the git commands and regularly broke down because of some incompatible change).

      You cannot be scriptable, fast evolving and easy to use at the same time.

      • mikera7 December 22, 2012 at 8:05 pm

        “You cannot be scriptable, fast evolving and easy to use at the same time.”

        You can if you use good abstractions for your API. But that requires more careful thought up front….

  23. alanh March 10, 2012 at 8:55 am

    Thank you for this. I’m struggling with trying to contribute to a GitHub hosted Open Source project. I thought it was me. Glad to know it’s git.

  24. Pingback: 我痛恨Git的10个理由 | 曹志士

  25. Pingback: 我痛恨 Git 的 10 个理由 - 博客 - 伯乐在线

  26. alex March 10, 2012 at 8:48 pm

    One day on a big project using GIT I got an email saying not to commit any changes or pull anything because the repository had been inadvertently reset to the state it was in three weeks before.

    It appears a developer had returned from holiday and having found it hard to merge their work simply forced a push.

    This could be seen as an argument against git. I suspect Management would consider it an argument against holidays.

    I cannot think of anyone who has used git and liked it.

    Could someone point out what advantage a distributed version control system has over (say) a clustered SVN system?

    • Edward March 11, 2012 at 10:13 pm

      They should have enabled the non-ff option on the remote – which is there for precisely this reason.

      Anyway, to answer your question, if you’ve ever had to work on a less than 100% available link, or a link that’s slow and/or expensive, then having git is invaluable.

      In a more prosaic setting, I’ve found found git awesome for being able to track an upstream project with git, pull in and review their changes at regular intervals, and apply my local platform changes over the top.

      I don’t even know how I’d approach that with subversion without a whole bunch of jiggery-hackery.

      • steveko March 12, 2012 at 12:24 am

        Right, well I wrote this blog post in a fit of rage at the crappy user interface decisions one has to deal with; I’ve never really doubted the great benefits the underlying Git infrastructure has to offer, with its superior branching and merging features. The user workflow could be still improved further though: on one project, I’m now in the situation of having to create a branch, commit code, push, then issue a pull request, then later delete the branch (and push the deletion) for every minor feature – sometimes as few as 2-3 lines of code. This could definitely be streamlined – but Git wasn’t written for contributors, it was written for maintainers.

      • Frederick Jones August 5, 2012 at 4:57 pm

        It used to be that you’d contribute your changes upstream, and people would work to produce stable, well-defined, documented, clean projects.

        Now everybody just hacks and slashes there way in, and then proclaims git to be a godsend because it enables work-generating decisions like “I’m (and everybody else) is going to maintain a fork forever”. So then you wind up wasting time, forever, instead of just paying the up-front cost to design software properly.

        In terms of market share, Linux is a success, In terms of technical quality, Linux is an unmitigated disaster zone of low quality code, failed designs, and rewrites. Git was built to support that development model.

      • Alex Chaffee (@alexch) August 6, 2012 at 3:40 am

        “I’m now in the situation of having to create a branch, commit code, push, then issue a pull request, then later delete the branch (and push the deletion) for every minor feature – sometimes as few as 2-3 lines of code. This could definitely be streamlined – but Git wasn’t written for contributors, it was written for maintainers.” — That’s not quite fair; part of git’s core design involves accepting emailed diffs as full patches. Pull Requests (and the concomitant branch mania) are a relic of the Github Era, not Git itself.

      • Arne Babenhauserheide September 3, 2012 at 5:35 pm

        I would agree, if I did not have Mercurial, which does everything git does while being easy to use.

    • Andy Bolstridge May 24, 2014 at 8:33 am

      That is a serious reason not to use it. The whole point of a SCM is to protect your commits. Anything else is just gravy.

      I’ve worked at a place where every so often someone would pop up to the git guru and ask for assistance as they thought they’d just trashed their work. That might be ok in an open source situation, but totally unacceptable if you got paid to write it. I’ve used git for a project and all I did was commit and push to master (it was just me using it) but even then one day I found it had pushed to a branch and required a pull… I still have no idea how I managed that given my workflow.

      Maybe when the SVN guys add shelving, the reasons people use git will go away, but I doubt that. The reasons to choose it seem more political than anything else. Maybe someone will create a ‘centralised SCM for decentralised teams’ that had the ease of SVN with the convenience of git.

    • Joe Example September 4, 2015 at 11:17 am

      “It appears a developer had returned from holiday and having found it hard to merge their work simply forced a push.”

      This is not a git issue; it’s a management/training issue.

      First time that happens, send the dev to be retrained, and restore from backups.

      Second time, fire the dev for incompetence.

      • steveko September 4, 2015 at 12:12 pm

        Yep. With enough training, all software is perfectly usable. :p

      • rjubber September 4, 2015 at 8:52 pm

        I think this may be the most hopeless defence of a system since Ribbentrop’s Nuremberg testimony. I hope your attitude isn’t prevalent in nuclear power stations!

        As many here have tried before, you’re blaming the user not the interface. If your safety system is reliant on everybody knowing everything the self-appointed best coder knows, and having a backup system that is somehow bullet proof (and budget proof), and moreover that fear of dismissal is your primary data protection method, your company is quite clearly a terrible place to work. (although eventually self-correcting). It’s important to try and grasp the notion that humans are not meant to program computers. We’re bad at it. Your personal vision of yourself maybe a pointy eared vulcan, watching reams of matrix like code on six monitors, CSI-style speed typing away without a bug in sight but that’s not a terribly robust approach to software design for the majority. Also, we’re not actually discussing code here, the primary reason you employ a coder, but a support system, designed to make life easier.

        Obviously I’m biased, as a games developer, but software developers or computer scientists who don’t understand or dismiss the importance of a good user interface are a menace to everybody working alongside them, simply from an employment perspective. In the shorter term, it should be obvious that a source control system, designed to transparently protect historical versions of code and resources, that encounters so much UI criticism, and that requires *such* a large body of non-coding knowledge in order to use without concern in day to day tasks, requires at the very least an overhaul. I would argue everything from terminology to failsafe conditions could do with some renewed thought. Like the SA-80 rifle, raw power is somewhat undermined if the tool sometimes kills the user.

  27. Tgr March 11, 2012 at 2:31 am

    SVN is great as long as 1) you have a fixed set of developers, 2) you don’t do much branching. Git supposedly – I don’t have much experience with it myself – makes exactly these things (“anonymous” commits and branching) easy.

    If you want to include contributions from anyone, then the simple “update, code, commit” workflow turns into something like “update, code, diff >> foo.patch, find bug tracker/mail address/whatever that project uses, open issue/write mail, attach patch, submit, download patch, apply, commit”, which must rely on big complicated hard-to-automate stuff designed for completely different purposes (like a mail client or a web browser), and most of the easy-to-automate stuff (like syntax checking and unit tests) can only be run after all this has been done manually, so integration becomes a huge bottleneck.

    If you need to merge between branches, as far as I understand the information model of SVN is just not really good for that, and so you are continuously confronted with stupid behavior (such as your own commits causing tree conflicts when you merge them back from trunk), and operations including deleting and renaming files can become quite destructive. (Worse, they often seem innocent when performed and become destructive when merged – e.g. if you delete a file and add some other file with the same name, that will be fine as long as you make them in separate commits, but when someone tries to merge them in at once, all hell breaks loose, and usually you have to delete the whole working copy, check it out again, find the offending commits – great fun if you were merging half a year’s worth of work! – and merge in multiple steps so that they do not get applied together.)

    • William Payne August 7, 2012 at 6:50 am

      Yup. SVN is really not at all suitable for distributed open-source development. I have not tried, but I can well imagine the excruciating pain and inconvenience that it would cause.

      Having said that, for small, co-located teams undertaking typical development activities in an SME-like environment, particularly when one or more team-members do not have a software development background, ease of use is paramount.

      When coupled with TortoiseSVN on Win32, Svn knocks the socks off command-line Git (Although in my mind SVN could be made simpler and less intrusive still).

  28. vzemlys April 3, 2012 at 9:23 pm

    Create an organisation on github and your problems will be solved. It has been two years when I moved my colleagues onto git and github. None of them are programmers, and none of them had any experience of git or for that matter versioning systems. Now everybody is happily working with no problems. The workflow is nothing more than git pull, git commit -a, git push.

    Sometimes new branches are created, then you need to say precisely onto which branch to push, and you need to use git checkout to switch between branches. In two years, I had only one cock-up, but after 10 minutes of swearing I fixed the problem in 10 minutes with no changes lost. The only thing which bugs me a little bit is merge commits in history. I could do something about it, but I am too lazy.

    As a maintainer sometimes I had to dive into deeper waters, but I had no problem in finding information how to do that. I also prepared mini documentation for my users, which contains everything they need to know.

    • steveko April 3, 2012 at 9:43 pm

      Yeah, the problem with advice like this, though, is that it comes from the perspective of a codebase maintainer. As I noted in my post, Git is written by, and for, VCS maintainers. My frustrations mostly stem from having to adapt to existing GitHub repositories: even if creating an organisation solves issues (I don’t know), it’s not something I could do.

      If none of your users are programmers, you’re obviously not a typical case. What are you maintaining – documentation? Do you worry about keeping a clean history, encouraging your users to rebase? If not, that’s also atypical. (I’m not trying to discredit you; I just want to clarify the situation on which my post was based, that causes so much frustration).

      • vzemlys April 3, 2012 at 10:01 pm

        Well I call myself maintainer, but I am really only the most knowledgeable user, which pays for private repositories. Several projects are running happily without my intervention, I only participate in them for my real work, statistical consulting.

        I work on statistical projects, and git is used for sharing R code and data. I do not worry about clean history, because I did not find it useful. As I said merge commits are annoying, but they do not interfere with blame history, so I can track who did what.

        And yes I understand that my setting might not be typical. But my experience contradicts several of your points made. Hence the comment.

    • Greg May 28, 2012 at 12:30 am

      I think you highlighted an importan point here. The maintainers of the code base /repository should send a one page manual to the users / contributers that includes all the settings during setup, the commands to make changes etc..

  29. Pingback: fl0blog » Blog Archive » Learning git

  30. Greg May 28, 2012 at 12:06 am

    Thanks Steveko..
    The ironic thing is your instructions and especially your diagram and helped me understand what is going on..
    Your diagram should be included in any git tutorial / manual.

    • steveko May 28, 2012 at 12:17 am

      Yeah. Because Git documentation tends to focus entirely on the relationship between your working directory and your local repository. It glosses over the relationship between your repository and remote repositories, even though that’s where much of the complexity in DVCS arises.

      • Havoc Pennington August 5, 2012 at 11:21 pm

        it’s because the Linux kernel developers don’t really use shared remote repositories I believe. My impression is they instead each have their own repo and either email patches or ask others to pull from them. This quirk of how kernel development works means they do things differently from most git users. But some UI decisions were made with the kernel workflow in mind.

  31. Pingback: Free GIT repository hosting | rizwaniqbal.com

  32. denommus June 17, 2012 at 3:13 am

    #7 is simply false. Git *never* destroys anything. It only adds. If you do anything you cited on your article with the repository, you could always use reflog and checkout to a pre-destroyer push.

    • jordigh1 June 17, 2012 at 10:40 pm

      denomus, it is a recurrent myth that git doesn’t destroy data. It does. garbage collection destroys data. push –mirror can destroy refs, another kind of data (the reflog may only store hashes, but not the actual names of refs, which can be useful metadata). History-editing operations like a bad rebase can also destroy data.

      Most “common” uses of git don’t destroy data, but if you’re learning git, it’s not that difficult to destroy data accidentally until you learn to not do it.

      • denommus June 21, 2012 at 1:03 am

        Well, I agree with garbage collection. But you can recover yourself from a push –mirror or a bad rebase checking your reflog (unless it has already been garbage collected).

        But you have a point. Git is not a mere toy, and you have to take care of some things to make a good use of it. I just don’t think this is as common as the complainers imagine it to be.

      • Arne Babenhauserheide September 4, 2012 at 10:11 pm

        denommus :
        Git is not a mere toy

        It is also not a safe tool. And that’s an unnecessary problem.

  33. C June 28, 2012 at 11:33 am

    Speaking from my heart. Very good summary. Thank you for that

  34. jason ko June 30, 2012 at 4:08 pm

    Amazing post! I totally agree with most of your statements. I am still a SVN/VSS user, but I also really like git; For One reason only. I care for the fact that I can use git commit without an internet connection, obviously can’t push without internet but I work on a lot of projects alone and on the go. So I like to be able to pull from my repo anywhere with connection.

    Because i have a home server, which is also my php server as well as my svn remote repo, I wanted to configure git with my current xampp virtual host setup. But having been at it for around 4 days now, looking at a lot of tutorials and blogs about setting up serving git over http. It is just so damn complicated and not user friendly. I got to the clone stage over http but just can’t get the push to work. Setting up svn under my xampp was extremely simple. I wish git was simpler, but it just isn’t.

    I wish I could use git for my primary source control but because of its complicated and the “Git’s hard, deal with it” part. I just gave up.

    But I like this article because its honest and shows a different perspective from the git enthusiast/fanboys blog post and comments, git is not for everyone.

  35. petedrinnan July 4, 2012 at 12:59 pm

    For me I find Git slow as hell a lot of the time compared to SVN. I am using Git because it is as I am told “better” but I am waiting several minutes for commits to complete when SVN would have taken seconds.

    • steveko July 4, 2012 at 1:12 pm

      Really? What’s the setup? Where is the repository and how big is it? I’ve never heard Git criticised for speed before – other than the initial clone, which can be very slow.

  36. jillesvangurp July 8, 2012 at 5:56 pm

    You have quite a few very valid points about Git’s usability and I won’t argue most. However, you are being overly kind towards subversion. I currently am a git-svn user and I have to deal with subversion’s limitations on a daily basis: extremely slow checkouts (think extended coffee break), my svn work directory is 4 GB, my .git directory with full history is 600MB and another 500 MB for a checkout. We have a rather messed up corporate intranet that makes interfacing with the remote svn server quite painful, especially the latency is an issue. Branching and merging requires a single person dedicated to that job. That is both stupid and costly if you are used to git. Most of the non git-svn users in our 50+ people team are eternally deadlocked on such backwards concepts as code freezes, elaborate and really messed up branching strategies, having to work one commit at the time, conflict resolution and waiting for ages for our build servers to churn through our builds. Our use of subversion is a poster child use case for why using subversion is a bad idea. It wouldn’t be fair to blame subversion for all our problems, there are many things that need fixing in this team. But it is certainly a big part of it.

    Git-svn has liberated me from that madness. I can work for weeks on my private branches (while keeping up to date with the latest changes in svn) and routinely git svn dcommit large changesets. I actually use a remote git repository for storing and sharing my branches and commits (we have a nice github like facility where I work). Scares the hell out of my colleagues because they are not used to seeing that much change in a short time frame appearing in svn. But I do my due diligence of making sure all tests pass before I dcommit so no harm gets done. Basically by the time I dcommit to svn, my work is in a releasable state. Piling up large changesets and testing them in one go would be painful in svn, which is why people don’t tend to do feature branches in the svn world.

    But Git is definitely hard to master and there is a quite high barrier for getting started. I struggled with it myself and I’ve seen other people struggle with it. It doesn’t help that it has a large overlap in the names for certain commands with svn because the semantics of those commands are quite different in the git world (e.g. git revert).

    However, the reason git is rapidly replacing subversion as the vcs of choice (most OSS projects and many corporations) is that overall you are better off with git than with svn. It enables teams to change their work flows and not be blocked on a central resource (i.e. svn). Changing the work flow is essential because it is entirely possible to use git like you would use svn, which is not a way you are going to get much out of git.

    Especially with larger teams changing the work flow is a very big deal. I agree it may seem like overkill if you have been treating your VCS as a glorified file server that you use for backing up work in progress. Which is pretty much the way most engineers tend to use it (sadly). But then, if you work that way, maybe you should consider using a version control system properly. If you use subversion properly, you’ll find that most of what you do is faster, less painful, and less error prone in git. You’ll be doing stuff you wouldn’t even dream of doing in svn because it wouldn’t be worth the pain. Fear of branching and merging is a wide spread thing among subversion users. And for good reasons: subversion absolutely sucks for these activities and you can seriously mess up a code base with a botched svn merge, thus blocking your team. The hard part of using git is learning to merge and branch properly and then unlearning that these activities are somehow dangerous, tedious and scary. They’re not. Everything is a branch in git. Your local repository is a branch. The remote git repository is a branch and if you use git-svn, svn trunk is just another branch. Git is a merging and branching swiss army knife.

    So, if you are stuck with subversion, do your self a big favor and learn how to use git-svn. I’d say career-wise picking up some git skills is essential at this point.

    • steveko July 18, 2012 at 9:26 am

      Yeah, I agree with basically all of that. SVN is easier to use, Git is more powerful. What motivated this post was the realisation that that trade-off is not inherent – it’s simply poor interface design on the part of Git. There’s no inherent reason why Git arbitrarily uses “repo branch”, “repo/branch” or “repo:branch” notation in different places.

      In my sector, SVN is basically dead – no one (myself included) really uses it by choice anymore. Partly as a result of this post, my Git skills are actually fairly decent now – because I’ve spent the time to work out the different use cases, and get my head around Git’s torturous information model.

      And yet I still constantly rub up against its irritations, and find fresh ones – like why on earth repositories don’t actually have names. The model of “I name your repository whatever I want” is much weaker than “your repository has a name which you gave to it”. Default names like “origin” work out horribly in practice (I soon forget from which repository I originally cloned), meaning you need to keep inventing procedures and workflows to avoid making mistakes – not the sign of a well-designed tool.

      • tytso August 5, 2012 at 11:33 am

        Distributed naming is very hard. What if you have two people named Steve who decided to call their repo, “Steve’s Repo”? The moment you have to start adding disambiguating information, you start ending up with something that looks like a URL: i.e, git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git. So if you want a globally unique name, that’s it. If you want to create a short name, then it should be up to you to choose what you want as a short name.

      • steveko August 5, 2012 at 9:25 pm

        That’s true if you want zero chance of clashes. If you relax that constraint (with the fall back position of URLs) then you could improve usability. Imagine this:


        $ git remote add http://github.com/steve/my-repo
        Repo "my-repo" added.

        $ git remote add http://github.com/tytso/my-repo
        Failed: Default alias "my-repo" would clash with existing repo "my-repo" (http://github.com/steve/my-repo)

        Etc.

      • skinny August 5, 2012 at 9:21 pm

        And yet I still constantly rub up against its irritations, and find fresh ones – like why on earth repositories don’t actually have names. The model of “I name your repository whatever I want” is much weaker than “your repository has a name which you gave to it”. Default names like “origin” work out horribly in practice (I soon forget from which repository I originally cloned), meaning you need to keep inventing procedures and workflows to avoid making mistakes – not the sign of a well-designed tool.

        Think about it for 3 seconds, and you’ll see that it’s impossible to name repositories in a distributed environment.

      • rdm August 7, 2012 at 11:40 pm

        skinny :
        And yet I still constantly rub up against its irritations, and find fresh ones – like why on earth repositories don’t actually have names.

        But repositories do have local names. A repository name is the file system path to the repository.

      • Kent Fredric August 6, 2012 at 6:39 am

        Those aren’t really notations for the same thing however, which is why they are different.

        repo branch # is working on a remote repo named ‘repo’ on the branch ‘branch’ ( generally )

        repo/branch # is working with a *LOCAL* (tracking) branch

        repo:branch # would be confusing to me, as far as I’ve seen, its only branch:branch , one side of the : being “local” and the other side being “remote”

      • Danillo Nunes August 6, 2012 at 7:10 am

        “There’s no inherent reason why Git arbitrarily uses “repo branch”, “repo/branch” or “repo:branch” notation in different places.”

        Yes, there is.

        “repo branch” are two independent arguments. Like when you do “git push repo branch”.

        “repo/branch” is a branch name which is a pointer to a branch of a remote repo. For example, if a remote repo has a branch called “feature-a”, you can “checkout at it”, make a change and a commit. and now you have your own “feature-a” branch with your commit, and the original “repo/feature-a” branch, with doesn’t contains your commit.

        I don’t know about a “repo:branch” syntax, but there’s a “branch:branch”, which is used when you need to deal with branches from a remote and your local repository. For example, if you want to push your new “feature-a” branch to remote, but you don’t want it to update the remote’s “feature-a”, instead, you want it to be called “steve-feature-a” there, then you can do something like “git push repo steve-feature-a:feature-a.

    • William Payne August 7, 2012 at 9:17 am

      Yeah, I can understand why Svn might be getting in your way: 50 developers provide quite a large number of moving parts to coordinate.

      My Svn experience has been in teams with between 10-20 developers, using really simple branching strategies (all development in trunk), so my experience with Svn has been very very positive overall. I am currently using Hg, and (with my current use-case) can see no overwhelming advantage for one over the other. (Although I can clearly see the benefit of a DVCS for a distributed team).

      It is worth saying that much of the development that I have done has involved compute-intensive testing and performance measurement, typically run on a limited-availability resource (High Performance Computer or cluster), driven by a Continuous Integration server.

      As a result, there was never really any practical alternative to the develop-everything-in-trunk branching strategy, and distributed development was never really an option either (If the only way you have of performing a non-trivial test of your code is to run it on a centralized, shared compute resource).

      It is also worth noting that code was usually pretty well organized, and fairly “functional” in nature, meaning that change-sets normally impacted only a small number of (closely related) files, so that concurrent changes affecting the same file were a very very rare occurrence. It is also worth noting that developers were encouraged to check in several times per day, which further limited the scope of each individual change, and further reduced the probability that two changes would affect the same part of the same file.

      In summary: for small to medium sized co-located teams, I think that Svn provides sufficient functionality. Indeed, its simplicity gives it a distinct advantage in these situations. For large, distributed teams on the other hand, where developers are forced to work independently anyway, Hg or Git are obviously more suited.

      For large, co-located teams, such as the situation described above, I suspect that much of the pain of using Svn is related to the use of complex branching strategies, as well as the manner in which code is organized and development carried out. Using Git may well reduce the amount of pain, but it seems that there are other, more fundamental problems that need to be addressed, such as how the code is organized, and why (presumably independent) changes are hitting the same lines of code.

    • cyp February 9, 2018 at 3:07 am

      Can you explain how something that saves everything is smaller than something that just saves differences? It makes no logical sense at least to me. Please explain!

  37. Craig July 18, 2012 at 9:09 am

    I find Git much easier to use than SVN. You only need to memorise (or write down) about half a dozen commands for 95% of your work. Of course Git ninja’s like to use all the funky obscure stuff, but it’s not necessary.

  38. ilupper August 3, 2012 at 6:41 am

    I have a Q actually (really looking for answers): instead of an entire repo + all branches; how about just a subset, master [+ another].

    What’s the difference between a local branch and a remote tracking of a branch?

    And why not a working dir per local branch? instead of flipping/”checking out” a branch?

    • Jordi Gutiérrez Hermoso August 4, 2012 at 12:06 am

      You can just clone one branch X if you wish, but you have to bear in mind that this branch might depend on commits from another branch Y (i.e. some of branch’s Y’s commits got merged into X). In this case, you will get X’s commits plus any of Y’s commits that are necessary for X. Both Mercurial and git allow this.

      About the difference between local and remote branches, this is a gitism due to how a branch *name* IS a branch in git. Because branches locally and remotely might be in different states, they also need different names, and there’s a mapping between local names and remote names. When the local name is mapped to a remote name, this is called a “tracking branch”.

      This concept is not exposed directly in Mercurial and is seldom necessary to worry about it there.

      About one filesystem tree per branch, there is another DVCS, bzr, which actually takes this approach. With Mercurial, since local cloning is so easy, I also do this sometimes. I have local clones for major branches (the named branches) and push and pull locally. In git, this is a bit more complicated to setup since local pushing is broken (you have to “fix” it with another gitological concept called “bare repos”). It’s also possible to do this in git, but it’s not a very natural way to work with it.

    • William Payne August 7, 2012 at 9:24 am

      I STRONGLY recommend keeping different branches in different working directories:- It lets me work on two or more features at once (one feature branch can be running unit-tests while I modify the source code of a second feature branch, and review the changes made on a third). It also lets me diff files more easily, and run tests & and compare performance metrics for multiple candidate features.

      • afinnell November 12, 2016 at 5:17 am

        I could not disagree more.. there is nothing more annoying then having to redo your workbench of whatever popular IDE you’re using every time you want to change branches. Let’s take IntelliJ for example. You can literally click in the bottom right, create a new branch, make changes, commit, switch back to another branch, merge, and never have to shutdown, restart, reconfigure, reset ENV paths, reset run paths, etc.

        While idealism says the location of a project should never matter, when attempting to run large Enterprise apps, whether they be monolithic or micro-services based in nature, at some point your setup is going to rely on the specific location of your source code.

        The separate directories is one of the more annoying things about SVN. The biggest being that it doesn’t actually support branching and it’s all smoke and mirrors.

        Git allows you to switch between branches so quickly it’s hardly an issue. Not to mention that this is an invalid argument. Nothing stops someone from cloning a Git repository as many times as they want into as many directories as they want and changing the branches in each of the folders to be whichever branch they want. That’s sort of the point of Git. It’s distributed. You can run a whole distributed system locally without the need of a server.

        There’s no argument for SVN to be had. Git supports what’s being talked about. It also supports having to NOT have a different folder for each branch. SVN supports this with switch if you want to risk losing all your code.

  39. issa August 5, 2012 at 11:49 am

    I recently switched from Subversion to Git. My ONLY complaint about git is (as mentioned in this post) the steps to do the equivalent of “svn add/commit” seem strangely verbose. Perhaps there is some deeper reason to this I am not aware of yet, but since that is what I am doing 90% of the time, you’d think it would be faster.

    • afinnell November 12, 2016 at 5:22 am

      Would you mind elaborating? It’s the same number of commands:

      git add myfile
      git commit -a -m “added my awesome file”

      done.

      People like to talk about the push/pull/fetch/rebase issues. But this turns the conversation into an Apples vs. Oranges comparison. Git is a distributed version control system. Trying to compare the entire _possibe_ workflow of a Git system to the single minded workflow of an SVN system is illogical.

      You don’t have to push anything ever. In fact.. You can require OTHERS to pull from you and you’ll just be providing changes. As this is what Linus does.

      If we want to get extremely picky and attempt to compare SVN vs. Git when adding a new file, these are the only commands you need:

      git add myfile
      git commit -a -m “added my awesome file”
      git push origin master

      done. The thing to remember here is that Git is NOT Client/Server based. This is why when you commit it doesn’t “go to some other server.” There are no servers, there’s only other participants in the commit graph you’re working on. And you can push your new commits to them or they can pull your commits into their’s.

      • arnebab November 12, 2016 at 8:41 pm

        The number of commands isn’t everything (though it’s not even the same numbe of commands: you have 3 git commands but only 2 svn commands).
        In addition it’s having to remember to add `-a` (or customize the local git) because git defaults are a bad fit to this usecase.

  40. --Anon August 5, 2012 at 11:55 am

    I submit the anecdotal evidence that I have accidentally destroyed many hours of work by running commands that sounded totally reasonable but turned out to permanently destroy data.

    • Arne Babenhauserheide September 3, 2012 at 5:42 pm

      same for me, though I only destroyed about an hour and then wasted a few hours trying to undo the damage. In the end I recloned, accepting the loss of time instead of investing much more time which I could use for recreating the work instead…

    • afinnell November 12, 2016 at 5:31 am

      It is unfortunate you lost code. That is probably one of developers worst nightmare. The person that put Git into place should have explained that it is ALMOST impossible to actually destroy data in Git. Even if you go through and force deletes (which can easily be locked out) the data still exists in the Git Garbage Collection. The Git GC doesn’t run constantly and can easily be used to recover data you’ve accidentally removed.

      Even if you undo a commit in Git the proper way, you don’t actually remove that commit. What you’re doing is reapplying the reverse changes into a NEW commit. So the commit graph shows everything that has happened.

      With all that said, here is how you setup a Git system for failure: Allow Force Push

      Here’s a more elaborate explanation:

      The people that are champions of using rebase do so WITHOUT telling people what is actually happening. If you are someone who likes to commit/push your changes often before you’re actually done and ready to merge them you can NEVER use rebase. You could destroy everyone else’s git repository.

      Git rebase is used to replay the commits you have locally on top of commits that have been fetched from a remote graph. This sounds great as it can lead to a clean commit graph, but becomes a problem when someone (or some machine) already has your commits, even if it’s in a different branch. If those commits exist ANYWHERE else besides your machine, then rewriting the history will blow up the entire Git system. It can’t reconcile two different histories. Think of it as time travel. you’ve basically gone back in time and changed the order things happened. If you were the only one that have experienced those events in time no biggie. If anyone else has experienced those events in time, you’ve just potentially killed them.

      So.. never ever ever rewrite history. If you check in a password and need to get rid of it.. It has to result in a complete and utter redo of everyone’s repository, meaning a reclone for everyone including the CI machine.

      If you don’t try to rewrite history in git you can never lose data. And even if you do manage to remove something it is almost guaranteed to exist in the Git GC. Plus, who doesn’t copy their repo before they attempt a potentially devastating change? Whether I use SVN, Git whatever, I always zip copy my repo before merging, rebasing, renaming, etc. I don’t want to lose my code.

  41. matthewfedak August 5, 2012 at 1:13 pm

    Git is distributed version control and subversion is not. Hence there are extra steps in commiting cause there is a remote repo to consider which is not necessary to update on every single commit. As for the then having to issue pull requests thats just again an extra step as its not needed on every commit. So actually more often than not git has same number of steps in storing code changes as subversion.

    • Kent Fredric August 6, 2012 at 6:45 am

      You probably could write an “auto-fetch/push” system for git as a wrapper/extension somehow, just have a list of peers ( instead of a central server ) in the config, and set it up so that “git commit” will do a “git fetch” , and upon no new changes in your current branch from other peers , completes the commit and pushes it to all the defined peers.

      Could be made to work. Just, why would you want to, that sounds awful.

  42. Josh Whiting (@yetanotherjosh) August 5, 2012 at 3:18 pm

    I have a pet phrase, “Gitguessing,” which means to execute a Git command that you don’t totally understand in the hopes that it gets you what you want. It also refers to making a frustrated and ignorant assumption about the current state of your local repo, index, or working directory. I’ve seen every developer I’ve ever worked with on a Git project do some form of Gitguessing. Often they end up in some bizarre state where their delicate balance of remote/tracking/index/working states has been corrupted and ultimately they manually copy their modified files into a temporary directory, re-clone the repo from scratch, and copy the files back in. That’s something I will admit to doing occasionally in the first couple years I was using Git.

  43. davidinnz August 5, 2012 at 3:49 pm

    How does Github for Windows affect the equation? It is supposed to be a superior UI (at least for Git).

  44. ssriram August 5, 2012 at 4:29 pm

    As far as i know, git was born out of necessity. Git was designed to be used for versioning the linux kernel (which is not a software project that you and me work on daily basis). All the hacks were not put in place but were designed into the core model.

    I feel it is insane to compare a DVCS to a VCS. It does not go by mangoes to mangoes. A DVCS _is_ a complex system than a VCS due to the Distributed features. If comparing is necessary then one could point out what Linus says in a talk that, subversion is the single most software that was started without a good reason.

    • steveko August 5, 2012 at 9:47 pm

      This rant might more accurately be titled something like “7 things I hate about Git and 3 things I hate about DVCS”, but that wasn’t as catchy.

  45. Josh August 5, 2012 at 4:47 pm

    > 9. Git history is a bunch of lies

    Code is meant to be read. If you’re sharing code with others, your commits are meant to be read, too.

    Rebasing lets you work however you want on your repo, then clean things up so that your commits are easier for others (and your future self!) to understand. This is a good thing.

    If you really wanted to preserve the original commits, you could probably work in one branch and then rebase onto another branch. Of course, nobody would want to accept your clean commit(s) AND the original messy ones, so you’d just be maintaining the extra branches for yourself.

    • Josh August 6, 2012 at 5:14 am

      I should add that I can’t really disagree with anything else you’ve said, so I guess it’s time to evaluate Fossil.

      • Chandler Liu May 5, 2013 at 8:40 pm

        Fossil is good, which provides a fully implemented DVCS and could be simplified via autosync mode. The only weakness is it cannot handle huge source tree.

    • afinnell November 12, 2016 at 5:36 am

      Until you forgot you pushed that one time because someone really really needed something and now you’ve just wrecked the entire git history because IT didn’t disallowed force pushes.. What’s with the ‘clean history’ thing? Changing source code isn’t clean. It’s messy. You can pick a file, use blame to see what’s been changed and it all works regardless of a messy graph or not. Who really finds value from a ‘clean’ graph vs a ‘messy’ one apart from some need to make the pretty lines go the right direction. rebase is incredibly evil unless every single person that is using the system knows every single way to use git. Not stopping history rewrites and telling developers to use rebase is the quickest way to lose days of work weeks at a time.

  46. x August 5, 2012 at 4:54 pm

    About some of your things I can’t say anything since I didn’t work so much which git yet (in large projects etc.). But for the first two points: yes the information modell is somewhat complex, but from my point of view the problem is not the number of features git supports, but the number of things you have to know before you can work with git (e.g. wth is staging ?!?). Everytime I try to teach someone some basic git commands, nobody understands the staging thing the first time. I might be a bad teacher, but I think is just a little too abstract. On the other hand, I don’t know any way to make it easier without reducing the functionallity of git.
    Secondly the poor cli syntax: Somehow I don’t like anything which comes after $1. Nevertheless, those arguments can really help to shorten the workflow (git commit -am “My commit message”). Finally you can user whatever front-end you like to use with git. But I would recommend to just move to the git workflow, since it makes some things possible which weren’t before (git log is much faster than svn log, what happend when your svn-server was offline/broken, git diff can be faster too).

    So I hated to learn the git concepts, but I love to use them.

  47. passcod August 5, 2012 at 5:30 pm

    This is more tongue-in-cheek than anything else, but: If you’re griping about the number of commands and the amount of knowledge required to do anything with git, why don’t you, uh, drop down to the internals for a try? Have a play creating blobs, trees, and commits :)

  48. Chris Morgan August 5, 2012 at 5:33 pm

    Edward :
    @steveko: In a nutshell, if github turns around tomorrow and demands money, or it cuts off access, then everyone who currently uses github will simply switch to another repo for upstream. By git’s nature, everyone already has a copy of all the data anyway.

    The problem is that this is probably not the case. Your code is in a git repository which you clean take away; if I recall correctly, even the uncommonly used wiki features are stored in a git repository; but what about the contents of the bug tracker which you’ve been diligently using? Unless they provide a way to get that data out, you’re stuck with a very important part of your project gone. I don’t understand why they don’t make it text-based under the covers and put it in a git repository, but they don’t (or at least, if they do, they don’t give you access to it). So, there at least is some lock-in.

    (For the record, I am one who loves hg but has found git difficult to work with and has also found hg-git to work very well.)

  49. Sakuraba August 5, 2012 at 5:45 pm

    That is why I never fully committed to totally learning Git. I am dead sure it will be replaced by something simpler in the future. Git is like the J2EE of VCS sitting in its complexity, waiting for Rails to kill it.

    • steveko August 5, 2012 at 9:51 pm

      Yeah, there could be some truth in this. Or maybe JSON vs XML or something. It took something like Git to make everyone see the benefits and potential of DVCS – now someone just needs to refine it.

  50. BAReFOOt August 5, 2012 at 7:31 pm

    In other words: Waaahhh! I’m not smart enough for this! So I’ll call it too complicated (for me) and stupid! :P

    If you can’t handle the power of a professional tool, get a consumer grade toy like Subversion, instead of complaining that you don’t like what *you* chose.

    The complexity serves a purpose, and is actually very elegant. And we won’t dumb it down for you, since we’re actually *using* those features!

    But it’s unfortunately always the dumber ones who loudly complain. Until we end up with an iPad with Clippy running on it, that is useless for anyone with a working brain.

    • steveko August 5, 2012 at 9:53 pm

      But of course few people get to choose their VCS software anyway. Refusing to use Git vastly reduces the number of open source projects you can contribute to.

    • Josh August 6, 2012 at 5:25 am

      > In other words: Waaahhh! I’m not smart enough for this! So I’ll call it too complicated (for me) and stupid!

      More like a waste of time. It’s great so long as all you need is add, commit, merge, branch, etc., and the occasional rebase, but I’m not sure I’ll ever advocate for its use at $WORKPLACE.

      Being decentralized is great (and so are easy branches, etc.), but it would be a huge waste of my time to have to provide tech support every time somebody has trouble with a merge or doesn’t know how to undo something.

      > The complexity serves a purpose, and is actually very elegant.

      No it’s not. There’s nothing elegant about git’s UI once you get into significant history manipulation.

      > But it’s unfortunately always the dumber ones who loudly complain. Until we end up with an iPad with Clippy running on it, that is useless for anyone with a working brain.

      And you’re an idiot.

    • Arne Babenhauserheide September 3, 2012 at 5:48 pm

      That mindset is one of the main reasons why git is hard to use…

  51. Martin Vilcans August 5, 2012 at 7:46 pm

    Well said! Git is my VCS of choice, as I’ve learned how it works and have use for its power. But the badly (or apparently not at all) designed user interface is still a problem, and not just because I have to read the man page every time I need to know which git reset flag I need. A big problem is that it’s difficult to introduce Git to a team of non-hipsters used to SVN. (I teach Git courses, so perhaps I should be happy that it’s difficult.)

  52. Joseph Wynn (@Joseph_Wynn) August 5, 2012 at 7:50 pm

    This is a nice write-up, and many of your points are valid. Please correct me if I’m wrong, but it sounds to me like you have started to use Git after working with SVN for a long time. Would it surprise you that I felt the same way about moving to SVN as a long-time Git user? The problem is that they both work *very* differently and you need to change the way you think about version control to switch between them.

    The thing that I like about Git is that (despite what you say in #5) there is a lot of abstraction and quite a few nice shortcuts. For example, you can skip the whole staging process (git add) by passing the -a flag to git commit. If you really want to have an SVN-like experience with Git by pretending that it isn’t distributed, you can set up an alias so that git commit also performs a git push.

    • steveko August 5, 2012 at 9:57 pm

      I haven’t actually used SVN all that much, to be honest. Less than 100 commits, over the years, let’s say. But the SVN concepts were easier to grasp.

      Taking shortcuts like ‘git commit -a’ doesn’t really help with the complex information model: you still have to know exactly what’s going on, or you’ll shoot yourself in the foot. An extra option flag bolted onto one command is not an elegant abstraction (whereas a setting that completely hid the index from sight would be).

      • Tgr August 7, 2012 at 6:39 am

        Well if you used Git but did not use SVN then I can see why you think SVN is better :)

        There is a sweet spot for SVN for which it works quite well: making small changes directly to trunk (which is typical for small-scale OS projects). You update, code, update again, resolve the rare conflict, and commit – simple and easy to understand. If you don’t have commit access (maybe you are not a regular contributor, just ran into some bug and want to contribute a fix) then SVN can be a lot more painful. Not only do you need to mail or upload the patch, but you have no way of “saving” it until it gets accepted. If you want to create two separate patches for the same file, or you are asked to fix something in your patch, things will get messy quickly.

        On the other end of the scale, if you are a major contributor to a project of nontrivial size, which needs versioning and backwards compatibility, or has big rewrite efforts which should not conflict with the continuous maintenance going on (in other words, you need multiple branches), then SVN starts sucking bad: its behavior at merging is erratic at best. Files disappear from the diff (because a merged add is actually not an add but a copy), commits start conflicting with themselves, code is duplicated without any edit conflict, and worse. (Not to mention that the whole thing is excruciatingly slow.) And the deceptively simple conceptual model you have drawn in your post is gone – suddenly you need to know about tree conflicts and mergeinfo and reintegration merges, with the difference that git makes an effort to open up its internal workings, so you can understand what is going on (not easily, but it is possible), while with SVN you usually don’t have a clue.

  53. Olivier Refalo August 5, 2012 at 8:53 pm

    Agreed! Git is way too complex.

    That’s why I built G2 !

    https://github.com/orefalo/g2

    • Alex Chaffee (@alexch) August 6, 2012 at 3:14 am

      With g2, seems you’re replacing one complicated lexicon with another. Why coin “freeze” when “stage” (meaning “add this file to the staging area”) supports the existing term “staging area”? Why make an inscrutable prompt when there are already a great prompt built in to git-completion.sh ? And you’re not resolving any of the ambiguities between reset, undo, and checkout, or between pull, fetch, merge, and synchronize…

      I do like “g panic” though :-). Think I’ll go make an alias for that.

    • Josh August 6, 2012 at 5:27 am

      > This project is an attempt to make the git command line a friendly place: it eases the learning process by providing guidance and high level commands.

      But it’s still git underneath, so the same problems will eventually surface.

  54. Simon Tewbi August 5, 2012 at 9:08 pm

    As someone relatively new to git, the thing I find really messy is submodules. Concept is great but the implementation sucks. Using Git Extensions on Windows takes away some of the pain but you’d think there would be a simple way of updating the commit the submodule points to, to the latest commit on a branch, or any branch for that matter.

    It’s really hard to convince the guys at work that git is the greatest thing since sliced bread when all they see is a mess. You really hit the nail on the head: Users just want something that works, they don’t want to have to study it to figure out how to use it. They’re too busy doing their jobs to waste time on side shows. Tools and apps with intuitive interfaces and workflows have been around for a couple of decades, at least. So expecting something to be straight-forward to operate is not an unrealistic dream.

  55. Erik August 5, 2012 at 9:26 pm

    Okay, I understand that you don’t like the complexity. But why do you want to make people change git for that? The complexity is harder to understand but if you have done so, it gives you much more power over your repository. Some people need complexity -> most of the things you say are actually considered advantages by them. Some people need simplicity -> Git sucks for them. But if you make it simpler, it will automatically destroy the advantages people love it for. So I think the decision for you is to choose another VCS and not to change Git.

    • steveko August 5, 2012 at 10:23 pm

      I think you’re making the common mistake of thinking that complexity and power are inherently linked. The most powerful tools hide complexity, they don’t expose grubby implementation details like “refs” and “tracking branches”. There are many ways that the usability of Git could be improved without decreasing its power at all.

  56. Havoc Pennington August 5, 2012 at 10:04 pm

    http://people.gnome.org/~newren/eg/ EasyGit is both a working solution to “fix the git UI” and a detailed git UI bug report (each EasyGit change to git reflects a git problem).

    • steveko August 5, 2012 at 10:20 pm

      Yeah, I sometimes use EasyGit – but it definitely runs a risk of creating even more commands to remember. It should give pointers to the Git developers though. I particularly like the message that “eg status” gives during a merge: a big warning, and a link to a man page explaining all your options.

  57. riotingpacifist August 5, 2012 at 10:57 pm

    I like the part where you complain about using a feature branch, despite:

    1) It being a good thing

    2) It being completly irelivant to git vs svn

    • Arne Babenhauserheide September 3, 2012 at 5:52 pm

      I think the problem with feature branches is not that you can use them, but that you have to.

      Feature branches are great, when you do somewhat larger development. But they are a needless complexity when you just want to do some smaller changes.

      • steveko September 3, 2012 at 7:04 pm

        I think some issues with Git can be summarised as “it forces you to structure the *changes* to your code, in addition to the code itself”. Sometimes (in established, large projects), that forced structure is a good thing. Sometimes (for beginners, and in smaller projects), it’s a hindrance.

      • Arne Babenhauserheide September 4, 2012 at 10:05 pm

        steveko :
        I think some issues with Git can be summarised as “it forces you to structure the *changes* to your code, in addition to the code itself”. Sometimes (in established, large projects), that forced structure is a good thing. Sometimes (for beginners, and in smaller projects), it’s a hindrance.

        Rather it forces you to give your changes names which you will throw away.

        It does not allow you do to add names to you changes, but enforces that – even for the most trivial changes.

        In projects where many people work simultaneously from a given base (either large or small) and merge only after many smaller changes, that forcing does no harm, because they would want to separate and name their changes anyway. But there, persistent naming would actually be more helpful, so people can later retrieve the information, why a given change was added. But since the branch name is just a pointer to the head of the branch, you don’t even have that after merging. The information is lost.

        So the forcing does not help for large projects and does harm for small projects.
        (don’t confuse forcing with the option to name your branches: having that option is great! Being forced to name them leads to a hundred “tmp” and ”foo“ branches. Whenever you see a “foo” branch, you observe time lost to git)

  58. Deon Fialkov (@777productions) August 6, 2012 at 12:31 am

    I like the way you explained certain things but the use of illustrative diagrams is more exciting…thanks

  59. Harald Wellmann August 6, 2012 at 2:20 am

    I wholeheartedly agree. Git makes simple things hard and has a completely unintuitive CLI. Frontends like EGit do not help much. And I’m not comparing Git with Subversion: Mercurial is DVCS done right, from the usability point of view. So the really interesting question is, why is Git so popular, when there is an equivalent but better alternative?

    • Arne Babenhauserheide September 3, 2012 at 5:56 pm

      “I invested so much into learning git, now I want to use it.” ← do you dare to tell them that they wasted their time?

      Second point: Good strategic option (likely not planned, though): Most times the maintainer chooses the DVCS, so cater to the maintainer to get spread around. Linus scratched his itch. Other maintainers had the same itch. Now the users are itching all over, but they do not get to choose the DVCS (except with hg-git).

  60. Alex Chaffee (@alexch) August 6, 2012 at 2:48 am

    In your list of mandatory options, you should add “git add”:

    ‘git add’ does nothing (it warns you “Maybe you wanted to say ‘git add .’?”)

    ‘git add .’ adds all local modifications and additions but misses local deletions

    ‘git add -A’ adds local additions, modifications, and deletions

    The way I like to put it is, Git was written by Martians. They’re very smart, but their brains don’t work like humans’ do.

    I say “I’m sorry” a lot when I’m teaching git. All your points are dead on right.

  61. Kephra August 6, 2012 at 2:50 am

    > But you only need a few basic commands to get by.

    You only need onw git command and a 2nd version control to get by: git clone to download a source code, and a 2nd version control system, like my home grown svc (shell version control) to create a patch to send to the upstream by mail. Thus I’m avoiding the complexity of git completely and drop the burden to the maintainer who did chose git. The drawback is, that you dont find my tag in any git based project.

    And you forgot one more problem:

    11: Git is slow as hell

    Try to download Android Cyanogenmod source. You will likely need a day even with a fast internet line.

  62. Tom (@tubbo) August 6, 2012 at 2:51 am

    Do you like, not know about reflog or something?

  63. limscoder August 6, 2012 at 2:55 am

    I love git, but I agree that some of the commands are difficult to understand, and man pages for commands like rebase are awful. The biggest thing that bugs me is the difference between pull/push. Pull fetches all branches, but only merges or rebases the the currently checked out branch (HEAD), push pushes ALL your branches to any matching remote branches unless you specify which branch you want to push to. Git could definitely use a UI make over. I also agree that Git has a steep learning curve. The first time you make some mistake and need to go back to your reflog to fix it, that’s not as easy as it should be. And despite the fact that I’ve been using git for years, I still have to look at my notes to remember how to checkout a remote tracking branch that does not exist locally.

    I could never go back to SVN, just because it’s so damn slow, and merges/rebases are more difficult. The code base I work on takes 3+ hours to checkout with SVN, while git clone takes <30 seconds. I also like how open source projects use pull requests, which are infinitely better than the SVN equivalent: emailing patches to the the maintainer. I also have trouble without the index when going back to SVN. It doesn't seem like a super useful feature until you go back to a system without it.

  64. Martin Vilcans August 6, 2012 at 5:57 am

    For those of you who that think that power has to come with a crappy user interface, take this post I wrote a year ago as an example of something that is an obvious mistake in the UI design. The UI mistakes doesn’t make Git one bit more powerful. It just makes it harder to learn. http://www.librador.com/2011/07/23/Usability-and-terminology-in-Git/

  65. William Payne August 6, 2012 at 6:22 am

    Even SVN is too difficult if you need to persuade non-software-developers to commit their code, so I agree with your thesis and then some!

  66. Josh August 6, 2012 at 6:33 am

    I love GIT and it has very many options that are simple one line commands it’s a slight learning curve compared to SVN but it’s way worth it. I also love the branching which I’m not familiar how to do in SVN and merging. GIt has a very fast workflow once you get used to it it’s definitely quicker than SVN for me anyways and I’ve worked with both of them for quite a while.

  67. Peter August 6, 2012 at 6:39 am

    1. Using a simple tool for a complex problem isn’t always a good idea. The philosophy behind Git (and most DVCS out there) is that you need that complexity to manage the problem of version control effectively. For instance: you mention the stash, that is something svn intends to add as well.

    2. True. It did get a bit better, but it is still a mess.

    3. Man pages suck, but I reckon Git has about the best docs out there. There is a huge community, a lot of books, etc.

    4. Same as 1.

    5. Not sure what the example is about, is that a regular workflow for you? Seems like an exceptional flow.

    6. Not true. The Git model is clearly appreciated by contributors, as seen by the massive adoption. What helps maintainers is also good for contributors. Also, on my one man Git projects, all the levers really aren’t in the way. The wizards in my IDE and GitHub/Google Code set up the repo, branches, etc. I just press commit and push.

    7. Yes this is scary about Git. There is a back-up to get most changes back. Although sometimes useful, I feel this ease of destroying history is a golden rule Git broke.

    8. Same as 6.

    9. Same as 7. I do think in a DVCS world it makes some sense to clean up a bit. I like the IBM Jazz model a lot.

    10. Same as 5. and as you admit a completely unfair comparison. If you’d use a similar access model, Git would only be one additional command.

    So a 2 out of 10 in my book.

    Git is by no means a perfect tool. But it is a massive improvement over SVN, especially for distributed open source development. Focusing too much on command-line quirks and the nuts-and-bolts way of working, dismissing all the great tools and services out there, I think you miss the point here about Git’s popularity.

    • Arne Babenhauserheide September 3, 2012 at 6:03 pm

      If you need a complex tool to manage the problem, then why can Mercurial do it as well while staying simple?

      Naturally you can say it can’t. In that case you should just use it for some time – and have a look at hg-git, which provides you a transparent bridge. So everything you can do it git can be done in hg, too. But most things are much easier.

  68. Richard Birkby (@rbirkby) August 6, 2012 at 7:09 am

    > git branch -rv Lists local and remote tracking branches; shows latest commit message

    You sure? Don’t you mean:
    git branch -av

  69. Darknite August 6, 2012 at 7:40 am

    Steve I agree 100% with this article. Solving problems are difficult enough, however solving problems that don’t even exist are even harder and unnecessary.

    I think Einstein’s quote sums GIT’s failure quite aptly:

    “Any intelligent fool can make things bigger and more complex… It takes a touch of genius – and a lot of courage to move in the opposite direction.”

  70. carleeto August 6, 2012 at 7:54 am

    Here’s the thing: you can hate Git all you want. The fact is, there is no substitute for it and the learning curve is a small price to pay for the power and flexibility you get – you wouldn’t expect a granny to get in and drive a race car, would you? Let me know when you find such a system. I’ll switch (and my guess is, so will the rest of the world).

    • Jordi Gutiérrez Hermoso August 6, 2012 at 12:45 pm

      There is a substitute. There are several, in fact. A DVCS doesn’t have to be the way git says it should be, because git didn’t invent DVCS, and git isn’t the fastest DVCS. Check out bzr, darcs, or my favourite, Mercurial.

      git is popular because “the guy who made Linux invented it” and because of github. It’s popular due to network effects. Not because it in itself it’s good.

    • steveko August 6, 2012 at 2:19 pm

      What kind of engineer defends a tool by saying “there’s nothing better, so get used to it”?

      • carleeto August 7, 2012 at 12:37 pm

        The kind that uses the best tool for the job. I stand by my statement that git is the most powerful. You can moan about it all you want, but it works and it works really well.

    • Arne Babenhauserheide September 3, 2012 at 6:05 pm

      Just learn Mercurial. It takes much less time than learning git.

      But then, it will still take some time. If you don’t want to invest that time, I can understand that stance. But it would completely invalidate any argument you can make about the power of git.

  71. Jeremy Brayton August 6, 2012 at 10:19 am

    You can blame hacker news for me being here (http://news.ycombinator.com/item?id=4340047) which seems awkward given this post is 6 months old now but I guess still holds relevance.

    steveko :
    I think your assumption that developers want to, or at least can be expected to, spend time learning developer tools is misguided. It was more reasonable 20 years ago. These days, we have so many tools and technologies to deal with, that they all must be made as learnable and intuitive as possible.

    +1. This is precisely the reason I went with hg. While I haven’t bitten the bullet and tried yet, there’s excellent plugin support like hg-git or hgsubversion that turns hg into a subversion client. I plan to get my feet wet with the latter and if it sticks, remove svn from my vernacular forever. When using a DVCS and getting used to even the basics, going backwards is like taking a trip back to the stone age. You mean I have to be connected to the internet to commit? The remote server has to be up? FU!

    I will second that Hg’s usefulness is in the ease of use. Hginit.com explains everything in a very simple manner too. I come from Windows, where Tortoise* is king and I find TortoiseHg to be the best package available among svn, hg, or git. Hg Workbench combines basically every UI dialog into one location which is amazingly useful. If I could choose it would always be Hg but there are things I pine for in Git, well specifically one: gitflow. There is a hgflow plugin but it’s not quite 1:1.

    Others have mentioned mq or patch queues and I think in tortoise they’re incredibly simple. I typically use it to commit anything volatile or in some instances move a block to patch and rearrange the commit order until I’m satisfied. I suppose it’s a lot like rebase but a more manual process.

    I’m not trying to be a poster boy for hg but I’ve drank the koolaid for a long time now apparently and when you find something like that, it becomes hard to want to jump to something user unfriendly like Git, despite it being billed as an “expert tool”. TortoiseGit *has* come a long way I will say and Github for Windows client helps tremendously as well but it has a long way to go still. It’s not that I need it to be awesome because I’m on Windows but you really should be able to get beginners to use a DVCS *early* and Hg will always eat Git’s lunch if it doesn’t take usability seriously.

  72. Karl Fogel August 6, 2012 at 2:43 pm

    DIsclaimer: I don’t hate git — I rather like it. But there is one complaint I could add:

    No ability to edit log messages after the fact. Especially once you’ve pushed a commit, that log message is now out there; if it’s wrong, you can never correct it, you can only try to add amendments in later commits.

    In SVN you can (if the repository admin enables it) tweak log messages after the fact, and it turns out to be really handy. Once people get used to doing it, they’ll go back and, for example, edit a log message in the past to refer to revision number that happened later, essentially saying “See also r1729”. It has many other uses as well.

    I think this feature would be very hard to support with decentralized repositories, though.

    • steveko August 6, 2012 at 3:57 pm

      Wait, what’s wrong with “commit –amend -m …”?

      • Karl Fogel August 6, 2012 at 4:17 pm

        Hey, steveko. Doesn’t that just amend tip, though? If the commit in question is past tip, and you can’t afford to rewrite history (which generally one can’t), then that log message is written in neutronium.

        And there’s a larger issue: if you’ve pushed already, and your commit has been replicated in other peoples’ repositories now, then you *really* can’t amend it. It’s not even clear in theory how one would design a protocol to reliably spread the news of the amended commit.

        IOW, in this case, Subversion’s design limitation — centralization, whereby the One True Repository is a technically rather than a socially enforced fact — becomes a feature. Because of it, editing log messages post facto is a conceptually consistent thing to do.

        This isn’t meant as general defense of centralization. I like git, and like decentralized VC independently of whether it’s done through git / hg / bzr / veracity / etc. But there are times when having a single, everyone-agrees-because-they-have-no-choice answer to “Where is the canonical data stored?” simplifies things greatly, and I’ve found this to be one of them.

    • Arne Babenhauserheide September 3, 2012 at 6:09 pm

      that’s something you cannot solve in general, though mutable-hg is aiming towards that: Safe, easy, propagating history rewriting. http://hg-lab.logilab.org/doc/mutable-history/html/

  73. NNM August 6, 2012 at 7:53 pm

    Can I use this as my homepage? lol
    Git is overrated bs.
    Don’t bother replying, I won’t bother elaborating. I hate Git.

  74. saddeveloper August 6, 2012 at 8:47 pm

    OK git has a steep learning curve, so we got someone to teach us, we mad some videos and made themn freely available here http://www.ava.co.uk/git .We also adopted / paid for smart git. The combination does a very good job, obviates the need for command line and has returned far more than the learning cost and smart git licences: it works for us

  75. stormwildstormwild August 6, 2012 at 9:14 pm

    Your post is actually a great tutorial on how to use git. Thanks!

  76. Riku August 6, 2012 at 9:52 pm

    7. Unsafe version control
    9. Git history is a bunch of lies

    This “problem” is fixed by GPG signing your Git commits. There are built-in tools in git for that. This not only prevents from accidental or intentional history rewriting but also keeps your sources safe if your git server gets hacked.

    • Arne Babenhauserheide September 3, 2012 at 6:12 pm

      GPG does not solve 9. 9 arises because people code, then rewrite the history, then push. Or worse: pull, rewrite, push – that actually garbles up the history of the contributor once he pulls, so he will have to rewrite his history, too – and all who pulled from him have to do the same. That’s the opposite of scaleability: It just means pushing the cost of scaling onto the contributors.

      • rdm September 4, 2012 at 1:32 am

        Arne Babenhauserheide :
        GPG does not solve 9. 9 arises because people code, then rewrite the history, then push. Or worse: pull, rewrite, push – that actually garbles up the history of the contributor once he pulls, so he will have to rewrite his history, too – and all who pulled from him have to do the same. That’s the opposite of scaleability: It just means pushing the cost of scaling onto the contributors.

        Huh?

        If you do not use the –rebase option when you pull the contributions, how does the rewrite get into your repository? Or, if you are particularly strict (and you probably should be, if you are pining for svn), you could use –ff-only.

      • Arne Babenhauserheide September 4, 2012 at 9:34 pm

        rdm :

        If you do not use the –rebase option when you pull the contributions, how does the rewrite get into your repository? Or, if you are particularly strict (and you probably should be, if you are pining for svn), you could use –ff-only.

        If someone else does a rebase of stuff you already pulled, your history gets garbled, because you now have duplicate history.

        If you send a pull request and the other one does a rebase, you have to prune out your copy – and rebase everything you did on top of the changes to the other changes.

        And everyone who pulled from you has to do the same.

  77. Pingback: 10 Things I hate about git | Part-time Life

  78. Fred Yang August 6, 2012 at 10:37 pm

    Honestly, I did not read very single word of your post. To be fare, the learning curve is much deeper than svn. This is not complete because the tool itself, but because it introduce lots idea of versioning control which is seem odd in other svn. The workflow of versioning in git is quite different, and this workflow looks complicated at first, but once we get used to it, we find lots rational. Here a section of script of “Scent of a worman”

    Now I have come to the crossroads in my life.
    I always knew what the right path was.
    Without exception, I knew, but I never took it.
    You know why ?
    It was too damn hard.
    Now here’s Charlie. He’s come to the crossroads.
    He has chosen a path.
    It’s the right path.
    It’s a path made of principle…
    that leads to character.
    Let him continue on his journey.
    You hold this boy’s future in your hands, Committee.
    It’s a valuable future,
    believe me.
    Don’t destroy it. Protect it.
    Embrace it.
    It’s gonna make you proud one day, I promise you.
    http://www.veryabc.cn/movie/uploads/script/ScentOfAWoman.txt

  79. rdm August 7, 2012 at 12:37 am

    First: I agree that git’s command line does not properly reflect its underlying structure. Personally, I use the guide at http://marklodato.github.com/visual-git-guide/index-en.html so that I can find the command that accomplishes what I want to accomplish.

    Second: I disagree that git does not provide meaningful abstractions. I would agree if you claimed that you do not understand the abstractions it provides, but that’s a very different kind of statement, and was not your claim. The abstractions git provides are very much like the abstractions provided by a file system — and once you understand them, they are simple to work with.

    Third: I dislike some of the defaults that git provides (for example, I always have people I am working with put in their global config: push.default=current). But my distaste for those defaults is a reflection of the admin system provided by github, and git was designed before github.

    Finally, comparing git to svn is sort of like comparing google maps with a tumblr. I can be totally in awe of the aesthetics of the tumblr and I can say all I want about how google maps does not have those design characteristics. And, in doing so, I would be pretty much missing the point of why people would like either one of them

  80. Anthony August 7, 2012 at 2:37 am

    Thank you for this well-timed post. It feels good to know that I’m not the only person who finds github impossibly confusing.

  81. Br.Bill August 7, 2012 at 4:05 am

    I am familiar with at least 9 source control systems, and I am paid-administrator-proficient with 4 of those, including ClearCase and Perforce.

    Git is such a mighty pain in the rear that I just gave up ever working on any open source project that uses it. Its learning curve is a sucktastic cliff and you really do need to know almost everything about it before you can stop being dangerous.

    And then you’re still dangerous. No thanks. The tool should not be more complicated and inconsistent than the programming language source it protects. It’s anti-developer.

    It’s as if I wrote a book entirely in made-up language because it was easier for me as an author, but then every reader would have to learn the stupid language I invented. It’s a horrible approach.

  82. ilupper August 7, 2012 at 4:38 am

    Is it possible to merge in git 2 branches that’s not the current branch (aka checked out to the working dir)

    • rdm August 7, 2012 at 4:49 am

      Yes — that is how git push works.

      But two branches in the same repository and you do not want to consider the target branch as the current branch? Why would you even want to do that?

    • Kent Fredric August 7, 2012 at 4:55 am

      It might be, but I don’t see why you’d want to, because to resolve conflicts, data must be dumped to the working directory anyway. And there’s no porcelain commands I see anywhere for this, because it would be notably complicated to perform. If you know git internals pretty well, you could probably find a way to forge a merge commit in memory without checking them out. Just… why?

  83. Vincent August 7, 2012 at 6:53 am

    It’s enough to look what Linux is to understand why Git is such a cr*p. Linus never ever studied properly even having such learning grands like Tannebaum. I hate Git too even from a first look (and I didn’t know who wrote it). Now I’m hundred times sure in my choice – Mercurial.

    • Arne Babenhauserheide September 3, 2012 at 6:17 pm

      Linus made things work where the grand Tannebaum failed.

      But I fully agree that Mercurial achieves the same as git without introducing the same kind of complex interface. That does not make git a bad tool. It just makes it inferior – but heavily hyped.

  84. Tacker August 7, 2012 at 7:59 am

    Even the first hate-thing is enough to not to read further for each one who really tried git. Other 9 are also a crap of subjective shit, decorated with lovely graphics :)

  85. Tyler August 7, 2012 at 9:04 am

    Try a GUI program called SmartGit. No more command line syntax to remember and it shows you a nice log on all the branches and past commits.

  86. Rob Horton August 7, 2012 at 10:26 am

    Just read your post for the first time, complete with the August update. This sentence really made me laugh and must be what the developers of Git say to themselves from time to time, “If I’d known it would be so popular, I would have tried harder.” :)

  87. Karl Fogel August 7, 2012 at 1:34 pm

    CC :
    “Subversion doesn’t even count, because anybody can write a simple VCS if they don’t have to make it distributed.” You truly have no idea what you’re talking about. it was a wholly different world when Karl Fogel and company wrote SVN. You seem to have no concept of how difficult it is was to create SVN in a world where there were few good tools, very little OSS, and a much more limited concept of VCS. That SVN succeeded so well at the task you dismiss out of hand is corroborated by its wide and enduring popularity.

    The original quote (“anybody can write a simple VCS if they don’t have to make it distributed”) is indeed kind of silly — SVN is certainly not simple, and it remains popular for good, understandable reasons IMHO.

    But the reason SVN isn’t Git isn’t because there were fewer good tools then, or less open source software, or anything like that (I mean, this wasn’t the Late Cretaceous — we’re only talking about 12 years ago or so). It’s because the project was explicitly started as a replacement for an older centralized version control system, CVS. The company that founded the SVN project, CollabNet Inc, envisioned something that fixed a lot of CVS’s problems but worked using basically the same model: check out from an upstream repository, make some modifications, check back in to the repository.

    Had we on the early SVN core team proposed to CollabNet that we do something like Git instead, CollabNet would rightly have rejected the idea, because it would neither have served their customers’ needs nor easily displaced CVS in the open source world. (I hasten to add that we didn’t have a decentralized vision anyway — i.e., it’s not like we considered a Git-like system and rejected it, it’s that we weren’t thinking in that direction at all.)

    But even back then, decentralized version control was not some new field of research. Git grew out of Linus’ experience using BitKeeper, which in turn grew out of the venerable SCCS. Linus was indeed bold to write his own system from scratch, and its success speaks for itself — but part of the reason he was free to do that was that he was the only constituent he had to satisfy. He wasn’t aiming to take over a broad installed enterprise base. (Whether Git ever does take over there is still an open question, I think; it might, but in many ways it’s less well-suited for that environment than SVN is.)

    Decentralization is not a successor to centralization; rather, it’s been a parallel track all along. We weren’t aiming for decentralization with SVN, and I’ll admit that I at least didn’t fully understand it at the time. But even if we had seriously considered it, I think SVN would still be a centralized system today.

    • steveko August 7, 2012 at 1:53 pm

      Git’s decentralised nature does seem to cause problems in environments where you need to end up with a single, definitive, centralised repository. The MediaWiki team has been going through a lot of pain, adopting Gerrit as a code review and Git management tool. The success of GitHub has also shown that Git alone isn’t enough – you need social tools built on top of it.

      I guess my feeling in all this is that Git (or something equally powerful) is necessary, but not sufficient, for effective code management in distributed teams. Although it claims to provide “porcelain”, it really doesn’t – and there are all kinds of features required by humans that it falls short on.

  88. Windy August 7, 2012 at 3:43 pm

    Agree. Besides the basic version control functions, intuitive and secure are the essential features of a version control tool. If the tool cannot even manage the source code safely, then why use it.

  89. Daniel Dotsenko August 7, 2012 at 5:38 pm

    A third of the rant is on the money (“git co filename.ext” vs “git reset commitid” etc). The rest is “I am a leg-less, color-blind semi-person who likes to stab frogs with bamboo sticks. This new-fangled world with distributed workflows, and the new ideas that come with it are too much. I don’t need that, therefore it’s useless. And, by the way, I don’t know why and how GitHub is a part of my angst, but let’s make it part of the problem too.”

    In other words, more than half of the rant is a person used to wheelchair complaining about complexity of using wings.

    The rant is only useful to Git maintainers really, just as a reminder that their user base is growing very diverse. You, the stray visitor that comes by and thinks this rant should somehow calculate into your decision not to / to choose Git, don’t pay attention. Just choose Git.

  90. Sopot Çela (@smcela) August 7, 2012 at 6:38 pm

    I have a feeling you approached git expecting it to be like svn and got disappointed. They are used for completely different workflows. They are suitable for completely different workflows. Try managing Linux kernel with svn…. If you have a 10 developer project maybe git is overkill, but if your project grows enough then git is the best choice around.

    P.S. Ever tried branching? ;)

  91. Jacob Groundwater August 8, 2012 at 3:13 am

    Just a note about Github, many people use pull requests (PR) as part of their daily workflow. A pull request should be opened early, very early, before any real changes have been made. The PR serves as a staging ground for discussions about the change, and a place for code review to occur.

    You can PR between two branches in the same repository. When I work on a project we all have push access to the same repository, but we still use PRs to coordinate changes.

  92. Colin August 8, 2012 at 3:55 am

    Comparing Subversion to git is like comparing a single-speed bicycle to a Jeep Wrangler or notepad to Microsoft Word. Yes, it’s more complicated. Yes, it’s harder to learn initially. But once you learn the basic theory you have a much more powerful tool at your disposal. This article is like hearing a whiny teenager complain about how hard his calculus class is because he thinks algebra should be enough math to get through a Computer Science degree. Every software developer that hasn’t yet learned git (or other respectable DVCS) and wants to stay stuck in svn-land needs to grow up or go home.

  93. Chris Carpenter August 9, 2012 at 1:13 am

    Didn’t read all the comments, so sorry if this has already been said, but the problem is you are assuming that GIT was designed to be used by the ‘regular user’. Unfortunately, it was actually created because Linus needed a tool. It was created for Linus by Linus, and then he decided maybe other people would like it too and let everyone use it. That’s why it is written to be used by a computer scientist, and that’s why it is slanted more toward the maintainer than the ‘regular user’: Because Linus is a Computer Scientist and a Maintainer.

  94. vectorgorgoth August 9, 2012 at 10:50 am

    3. git is a tool for computer scientists. Anyone who doesn’t qualify has no business writing code, and no business using git. And if they do, they certainly have no right to complain about it.

    • steveko August 11, 2012 at 9:53 am

      Heh, still trying to work out if this comment is satire.

    • Brilliand October 23, 2012 at 9:02 am

      I was thinking that, right up until I read the actual examples. From the looks of it, the Git documentation is as bad as reading source code – and if source code were good enough, there wouldn’t be any documentation.

  95. LFM August 10, 2012 at 11:17 pm

    I agree with you 100% that the man pages suck and the “porcelain” commands aren’t enough for getting a reasonable project going.

    For the rest of it, it’s an extremely flexible tool that can be misused way too easily. The key, like in probably C++, is not that you should get to master “all Git”. But that someone in your project decides what subset of Git features make most sense to you. It’s just a different job for the maintainer.

  96. Christian Höltje August 11, 2012 at 2:14 am

    Your post has good points. I’m encouraged that we’re at a point where we’re complaining about the UX for a VCS instead of about features. It shows what huge steps we’ve made in version control technology.

    I started with RCS and SCSS and worked my way up to CVS, svn, p4, hg, bitkeeper and finally git. From my perspective, git is awesome and I can live with the complexity of the commands because doing a lot of the things I do now easily with git were painful and dangerous with the previous version control systems.

    Subversion, for example, didn’t have sane branch merging when I was using it all the time. CVS was incredibly limited and I was constantly repairing checkouts by editing files in the .CVS directories.

    I think it’s time to improve the UX for git, and posts like this will encourage people to make those improvements.

    I’d love to see you write mock ups or descriptions of how the commands should work for maximum (or maybe just better) UX in an ideal world.

    Ciao!

    • steveko August 11, 2012 at 9:54 am

      Hmm, very interesting idea. It will certainly be very tricky to fix, especially because many users now depend on all the commands and options they’ve memorised.

      • rdm August 11, 2012 at 11:20 pm

        Hypothetically, though, you could design a new line of independent git * commands, allowing people to migrate at their leisure.

        That said, my impression is that people working to design new git user interfaces often have a rather limited view of what will want to be doing (or what they should be wanting to do) with git (for example: git flow).

        There’s a dichotomy between utility and workflow and in addition to the “many people are already doing it differently” thing, it can be surprisingly difficult to build a new system that integrates properly with the abstractions people are going to be wanting to use to reflect their own work…

    • wtpayne August 11, 2012 at 9:56 am

      Hear! Hear!

      It would be nice to have a tool that is really really simple for the simple things, yet also able to handle the more complex things when required, so it can be used by time-pressed non-programmers (who would really prefer not to use version control at all) and experienced developers with sophisticated needs alike.

      Sensible defaults, easy installation, good documentation etc.. all contribute to this as much as a nice interface.

      • Drak September 5, 2012 at 7:59 am

        Jepp. I use Mercurial for that…

      • wtpayne September 19, 2012 at 1:12 am

        Mercurial is still too complicated.

        On Win32, TortoiseHG is (IMHO) not as easy to use as TortoiseSVN, and even TortoiseSVN was too complicated for some of my erstwhile former colleagues.

        Unfortunately, I suspect that the tool would have to have absolutely no interface whatsoever to stop them being bamboozled. It is tempting to take an arrogant line and give up on these individuals, but I strongly disagree. There are highly intelligent domain specialists with limited time and little interest in software engineering issues, who nevertheless have a huge contribution to make to many projects.

        Bringing their contributions under version control has a huge benefit in terms of communication, automation, organization, and team synchronization.

        Bottom Line: We need to make our tools simpler. Not just a little bit simpler, but dramatically, radically, disappear-from-sight zero-interaction simple.

      • rdm September 19, 2012 at 1:52 am

        wtpayne :
        Mercurial is still too complicated.
        On Win32, TortoiseHG is (IMHO) not as easy to use as TortoiseSVN, and even TortoiseSVN was too complicated for some of my erstwhile former colleagues.

        Once upon a time, I had a colleague for whom “files and programs” were too complex. I remember spending hours working with him on this issue, before we managed to work out how to get him to “start the word processor before you start typing” though he never did understand the idea of what a program was (this was about 25 years ago).

        Anyways, my point of view on this issue is: ignorance is a solvable problem.

      • wtpayne September 19, 2012 at 2:18 am

        Telling people that they are ignorant is not the solution, particularly when they represent valuable specialist expertise to the organization. I would rather take a more conciliatory approach and save up my balance of good-will for situations where it really matters (Like the importance of keeping files neatly organized).

        In any case, they are not ignorant, merely pressed for time, and (entirely correctly) want to focus on providing value within their area of expertise, not on learning how to use (for them) obscure and byzantine “techy” tools that hinder, rather than help them achieve their own objectives.

        This is particularly true when the specialists in question view the software engineering function as something that is subordinate to them, and that should operate in the sole service of their objectives.

        In this situation, any attempt to push back needs to be handled with the greatest of discretion.

        It would really help me if the tools just got out of the way, and I did not have to apologize for them and the inconvenience that they cause.

      • rdm September 19, 2012 at 2:28 am

        wtpayne :
        Telling people that they are ignorant is not the solution, particularly when they represent valuable specialist expertise to the organization. I would rather take a more conciliatory approach and save up my balance of good-will for situations where it really matters (Like the importance of keeping files neatly organized).

        I do not think anyone has advocated that “telling people that they are ignorant” is a solution for anything.

        However, you replied shortly after my post, where I suggested that I do not accept “ignorance” as an issue.

        If I am using prepackaged software, and I am working with someone that does not want to deal with it, there are a variety of options open, including providing wrappers (click on this icon…) and engaging someone else to support them (if this fails, talk to Sam), and so on…

        That said, when I have been working with software developers, and we are using git, it’s always been simple enough to work through the issues.

      • wtpayne September 19, 2012 at 3:40 am

        @rdm – I apologize for my blatant; egregious misrepresentation of your position – I was creating a straw-man to dramatize my argument.

        :-)

        I agree with you that, amongst developers, learning new tools is rarely a significant issue – because we accept that as part of our job. (Whether we *should* or not is another discussion for another day).

        I feel quite strongly that the same tools that we use to communicate, coordinate, synchronize and integrate work within an engineering team can also be used to fulfill the same needs across the entire organizational management structure, and that lack of systematic attention to such issues is the underlying reason for a great deal of inefficiency, waste and grief in a wide range of organizations.

        I am an empiricist, and, as such, I think that empirical evidence is the most important, reliable source of truth in decision making. However, so many of our decision makers are so distant from the results of their decisions, and so removed from empirical truth, so distorted and disfigured by social and political pressures, that the quality of decisions in many organizations is simply execrable.

        Exposure to the coal-face of hands-on development gives the developer tremendous benefit – his actions must (frequently but not universally) be judged by what actually works or fails, not by his social nous, political maneuvering, faculty with weasel words, or ability to pull the wool over people’s eyes.

        I wish for that benefit, that feedback loop, to be extended more widely through the organization. For people to cease hand-waving platitudes and generalizations, to get to grips with the detail of the problems that we face, and to realize that to make real progress, you need to do real work, not busywork.

        That is my motivation.

  97. Christian Höltje August 11, 2012 at 2:19 am

    FYI: In the latest version of git, you can just do “git checkout ” and it’ll automatically do the ‘-b’ part for you (set up the remote mirroring, etc.)

  98. Roger Barraud August 12, 2012 at 10:44 am

    Love the diagrams… How did you make them?

  99. John Wiltshire August 12, 2012 at 1:51 pm

    The trick with git is to realize that it’s called plumbing and porcelain because neither are something you want to live in but something you want to just “work” and live in the corner of the house you build. Occasionally some things feel weird, but if you’ve every been to Europe then the porcelain feels weird over there too, so I write it off as culture more than true usability.

    Moving the bulk of our source code from svn to git was probably the best thing we ever did in our company, but we set up a pretty significant process and automated-merge-to-master intranet page that tied in with our work tracking system. We also left a bunch of third party stuff in svn because it just made more sense to not have every version of every binary on every clone of the git repo.

    I originally got annoyed reading your rant until I realized it was pretty much a laundry list of everything we had to plumb around in getting widespread acceptance of a distributed source-control system in the company. Things like turning off non-fast-forward commits on master, and then making master read-only to anything but the automated merge process were critical to making it all livable, and now there’s measurable improvements in workflow overheads going way down. Obviously we encourage GUIs like SmartGit, TortoiseGit and Git Extensions instead of the command line for everyone but the top end of power users, which paves over most of the usability complaints.

  100. steveko August 15, 2012 at 11:26 am

    rdm :

    Hypothetically, though, you could design a new line of independent git * commands, allowing people to migrate at their leisure.

    That said, my impression is that people working to design new git user interfaces often have a rather limited view of what will want to be doing (or what they should be wanting to do) with git (for example: git flow).

    Yes, I wonder whether something git flow could be integrated into the core git suite. So then commands like “git branch” get relegated to “power user” status, and the average user only works at the higher, workflow level. Those commands would also be able to give much more verbose output, and be free from the dual requirements of human usability and scriptability.

  101. asdf August 17, 2012 at 2:47 am

    That’s why I love SVN+Tortoise :)

    • rdm August 20, 2012 at 11:38 am

      I’m actually not entirely clear why people think git and svn conflict.

      You could easily, for example, use svn to track the history of a branch managed in git, and you could use git to propagate changes introduced in that branch using svn.

      The thing is: they solve different problems: svn keeps track of a history of document instances, while git deals with change management.

      I suppose, though, some people are saying that they do not need both features. People that are using svn but not git do not need to coordinate changes from a group of contributors, and people that use git but not svn do not need another copy of the document history.

      • Arne Babenhauserheide September 4, 2012 at 9:23 pm

        Do remember that SVN has real branches, though they are implemented via the file system. It’s a different tradeoff than with git, but SVN gives you real diffs and you can coordinate changes from groups of contributors via SVN.

        It’s just not as convenient as with Mercurial (I won’t go as far as calling git convenient…).

  102. Sam Duke August 20, 2012 at 9:16 pm

    11. Too many states
    This has been mentioned a few times now, detatched head, merge conflicted, in-the-middle-of-that-but-got-stuck state etc. Do we need them all?

    This brings me on to:
    12. Git gives up
    Someone on hacker news summed this up: “But the standard Git CLI and most interfaces to it basically just drop everything on the floor and tell you to sort out the mess yourself as soon as something non-trivial happens.”
    This is my biggest problem with it. Git needs to be more INTERACTIVE. Like if something fucks up, talk me through the issue.
    This is carried through into GUIs for Git. Take github’s Windows application as an example (“The easiest way to use Git on Windows. Period.”), if i get into a merge conflict, it just offers me a button to abort, or launch the command line. Why not bring up a diff tool at that point? why not integrate a diff tool into the application and say “look, here’s the problem i had, tell me what you want to do, then let’s continue!”

    This brings me on to:
    13. GUIs
    Ever try and learn about revision control? Read a blog about it? Get a book? Have a buddy explain it? What’s the thing in common? They ALL use diagrams (at least the good ones do). Diagrams, AKA graphics. Why not use that for git, and combine it with the user interface, we could call it a GUI! And I know about Git GUI and Gihub’s gui, but they all suffer from my previous point – they only work for a subset of git. Why not make a tool that covers the corner cases (infact, not even the corner cases, just the edge cases, or the top-left-quadrant cases, or the non-svn-user case) so you dont end up taking a user, confusing them, then sending them to the commandline.

    For the record, I was not brought up on SVN, I actually started on Rational Team Concert, when I barely new what revision control was. and found it pretty simple to use. I suppose I am spoilt by this. I’ve tried individually and within a group to learn git. I still get stuck and confused, and my head still gets detached, and then you have to guess which reset command to use.

    • steveko August 21, 2012 at 10:25 am

      Some good points. In my experience, “non-trivial” things tend to happen with Git pretty frequently, and neither Git, Github, GitX nor GitX provide any guidance when they do. EasyGit provides some pointers sometimes, such as the “middle-of-merge” help text.

      Your point 13 is well made, too. Much of the complexity of Git revolves around trying to construct the right representation in your head, then take appropriate steps to resolve it. A decent drag-and-drop GUI would help a lot, with visual representations of “before” and “after”. Perhaps there is one already, but it needs to be free.

      • Sam Duke August 21, 2012 at 10:51 am

        Yes! I’m not even sure drag and drop would be needed, but it would certainly be awesome if somebody implemented a full nodal tree that you could rearrange and play around with (like the snap-to connectors you get in MS Word drawings)

        I played with tortoiseHG today without really reading the manual. I can commit, merge, rebase, revert and push to SVN entirely from the gui. I got in some messed up states, broke a few things, but even so, after initial set-up I never typed hg again and solved all isues through the GUI. In fact, the only issues I really had were because i was doing operations against an SVN repository, which tortoiseHG has poor support for (self admittedly). The best part was it provided a simple graph so i could see all the changes i was making as i made them. I’m not sure why that should feel like such a massive feature :)
        Now, looking into tortoiseGit, it may be my saviour, as I *think* it’ll talk me through resolving conflicts. I’ll try to remember to report back when I get a chance to do something serious with it.

  103. Cambo August 29, 2012 at 3:02 pm

    GIT! FUGGIT! UI is waaayyy too hard. Even using eGit in Eclipse is still complicated. And no, I am not dumb or lazy, I just need to make code and commit it. Back to SVN for me.

    • Sam Duke September 2, 2012 at 1:38 am

      try mercurial with tortoiseHG first. I could intuitively make it work, even doing reasonably complicated things like rebasing, i managed to get it to work with a bit of playing around.

  104. Footman September 2, 2012 at 10:03 am

    I will agree with you on exactly 2 points:
    The git command line tools are inconsistent and suck.
    The git man pages need to be improved.
    Your other points either stem from this, or are simply wrong.
    Complex information model? In all the time I’ve used git I’ve never needed to know about trees and blobs and whatever.
    The only reason I know about them is because the man pages mention them for some reason. (see complaint number 2).
    The way branches and tags etc work is exactly how I imagined they would before I was introduced to subversion.
    So your problems there are mostly to do with you familiarity with subversion I guess.

    git commit -a; git push;
    is the same as svn push as far as I can tell. So that’s one extra command, and only because you are pushing to a server.
    If you only use local repository, which I do until I finish and push a bunch of things at once, it’s the same number of commands.

    git stash is useless?
    Until now I have never wanted to stash untracked files, so whether it’s useful or not depends on your workflow.

    I think the fact that you use github adds complexity that you are attributing to git.
    We have our own server where people can pull and push, so that eliminates several of your complaints already.

    tl;dr; I dissagree with you :P
    I couldn’t resist posting.

    • Arne Babenhauserheide September 3, 2012 at 6:32 pm

      “the built-in commands suck and the built-in documentation sucks”…

      Naturally every other complaint when using the tool stems from these, because they describe the whole default user interface.

      And the only way to avoid them is not using the tool directly, but using some program which uses the tool. You could say that you can improve every interface by not using it…

  105. dynetrekk September 3, 2012 at 9:49 pm

    Finally, someone said it.

  106. jason September 4, 2012 at 12:57 pm

    Why can’t I use git and svn and mercurial and vss at the same time? why let technology define us, don’t we all want more innovations. I hope git is not the final stop in the source control evolution.

    • Arne Babenhauserheide September 4, 2012 at 9:29 pm

      you can, but they have different paradigms so everytime you switch you have to change your way of doing things (except if you use emacs). It’s like programming in 5 languages at the same time. You can do it, but it has much higher friction than being able to use one language for one project.

      Joel described that quite nicely in “human task switches considered harmful”: http://www.joelonsoftware.com/articles/fog0000000022.html

      • rdm September 5, 2012 at 12:21 am

        Arne Babenhauserheide :
        you can, but they have different paradigms so everytime you switch you have to change your way of doing things (except if you use emacs). It’s like programming in 5 languages at the same time. You can do it, but it has much higher friction than being able to use one language for one project.
        Joel described that quite nicely in “human task switches considered harmful”: http://www.joelonsoftware.com/articles/fog0000000022.html

        I would draw a distinction between scope of vocabulary and interruptions.

        Personally, I use a variety of languages, and that seems to me to be a very different experience from someone coming up to me and asking me to drop what I am doing and work on something else.

      • jason September 5, 2012 at 2:16 am

        I agree with the programming language part, but since i use git/svn/mercurial/vss with their awesome augmented GUIs I find it extremely easy to use. And since i use them all anyways its automatic for me when i use them. but i must clarify i m slowing using git as my primary repo. svn is still useful for me for non programming related source control since i can check out individual files. Thts y i like using all of them.

      • arnebab September 5, 2012 at 6:01 am

        If you’re using the VCS via a GUI, that’s similar to using them via emacs. I have no problem interacting with git via emacs, because it is exactly the same as interacting with Mercurial or SVN.

        But an augmented GUI which works differently for the different systems is still a context switch which creates friction.

  107. rdm September 5, 2012 at 12:22 am

    Arne Babenhauserheide :
    rdm :

    If you do not use the –rebase option when you pull the contributions, how does the rewrite get into your repository? Or, if you are particularly strict (and you probably should be, if you are pining for svn), you could use –ff-only.

    If someone else does a rebase of stuff you already pulled, your history gets garbled, because you now have duplicate history.
    If you send a pull request and the other one does a rebase, you have to prune out your copy – and rebase everything you did on top of the changes to the other changes.
    And everyone who pulled from you has to do the same.

    So don’t pull it. Seriously, the whole reason pulls are not automated is so that you can exercise judgement about which pulls to make, and when. Problems should be fixed by the person introducing them. People that won’t fix their problems are not helping.

    • Arne Babenhauserheide September 5, 2012 at 5:50 am

      rdm :
      So don’t pull it.

      So you don’t pull the canonical repo. That creates a shism in the project, and from there on it goes downward.

      The problem is brought upon you by someone else, but git makes it easy for mainainers to screw with contributors and hard for contributors to recover. Git makes it easy to rewrite published history (you can even do so remotely!), but it provides no way to detect how history was rewritten and adapt the local DAG automatically.

      • rdm September 5, 2012 at 7:10 am

        Arne Babenhauserheide :

        rdm :
        So don’t pull it.

        So you don’t pull the canonical repo. That creates a shism in the project, and from there on it goes downward.
        The problem is brought upon you by someone else, but git makes it easy for mainainers to screw with contributors and hard for contributors to recover. Git makes it easy to rewrite published history (you can even do so remotely!), but it provides no way to detect how history was rewritten and adapt the local DAG automatically.

        Ah, I think I understand.

        You are correct: git is not designed to have a shared repository be the canonical repository.

        If I had your problem, I would create another repository which I would designate as “canonical”, which most people could only pull from.

        When you are using git, you need to be a code review process before you accept changes. If you define your policies properly, you might even be able to automate this process (allowing anything that can be fast-forwarded, for example).

      • Arne Babenhauserheide September 5, 2012 at 10:47 pm

        rdm :
        You are correct: git is not designed to have a shared repository be the canonical repository.

        That is still too short: Code review processes are exactly what creates the problem: Some code is not accepted, but someone already pulled it from another repo, then it is rebased, improved and accepted. Suddenly you have two versions of mostly the same changes floating around, which everyone has to join by hand (and change all the code they based upon that).

        And git offers nothing to recover from that condition.

        A tool which makes it that easy to break lots of code of other people should have better ways to recover. But all you have is rebasing – which multiplies the effort when people share code very vividly.

        Git gives the false impression that you can just fix a bad push after the fact without effort, because the real effort does not hit the one who “fixed” it, but those who already pulled it.

        And yes: I experienced that first hand a few times:

        – “hey folks, I just cleaned up the messy history I pushed”
        – “you did WHAT?”

      • rdm September 6, 2012 at 12:00 am

        Arne Babenhauserheide :
        That is still too short: Code review processes are exactly what creates the problem: Some code is not accepted, but someone already pulled it from another repo, then it is rebased, improved and accepted. Suddenly you have two versions of mostly the same changes floating around, which everyone has to join by hand (and change all the code they based upon that).
        And git offers nothing to recover from that condition.
        A tool which makes it that easy to break lots of code of other people should have better ways to recover. But all you have is rebasing – which multiplies the effort when people share code very vividly.
        Git gives the false impression that you can just fix a bad push after the fact without effort, because the real effort does not hit the one who “fixed” it, but those who already pulled it.
        And yes: I experienced that first hand a few times:
        – “hey folks, I just cleaned up the messy history I pushed”
        – “you did WHAT?”

        Ok, yes: git also does not solve the “no one is in charge” problem — it was originally designed for a notable case where this had been solved for decades.

  108. rdm September 5, 2012 at 12:28 am

    Arne Babenhauserheide :
    Rather it forces you to give your changes names which you will throw away.
    It does not allow you do to add names to you changes, but enforces that – even for the most trivial changes.
    In projects where many people work simultaneously from a given base (either large or small) and merge only after many smaller changes, that forcing does no harm, because they would want to separate and name their changes anyway. But there, persistent naming would actually be more helpful, so people can later retrieve the information, why a given change was added. But since the branch name is just a pointer to the head of the branch, you don’t even have that after merging. The information is lost.
    So the forcing does not help for large projects and does harm for small projects.
    (don’t confuse forcing with the option to name your branches: having that option is great! Being forced to name them leads to a hundred “tmp” and ”foo“ branches. Whenever you see a “foo” branch, you observe time lost to git)

    You are not forced to use names which you will throw away. For example, you could use your own name. And you can keep using that same branch name for all of your changes, if that seems to be a good thing for you.

    If you do not know how to make this work, here’s two different approaches:

    1. on your branch: git merge master (to bring yourself up to date on changes in master, before doing further changes)

    2. on master: git branch -D yourname; git checkout -b yourname (this will destroy your branch and recreate it as a fresh copy from master — clearly you need to exercise good judgement about going this route).

    Or you could use initials and the current date. Or you can create a file documenting the changes and you can use the same name for your branch that you used for the file. (And note that you can start with a temporary name — your initials and a date, maybe — and then bring those changes into another branch that’s a permanent name.)

    Or, you know, you could just stay on master and try to do all of your work there. That might not be the best idea, but it can be done.

    Anyways, nothing is forcing you to follow any specific naming policy.

    • ArneBabenhauserheide September 5, 2012 at 5:02 am

      arnebab is just another name for foo, when it comes to my repo. Same for time and anything else with which you try to replicate anonymous branching.

    • Arne Babenhauserheide September 5, 2012 at 5:58 am

      arnebab is just foo by another name. It has no information correllation to the repo I work in, so it is just useless effort forced on my by the lack of anonymous branching.

      Staying on master is hard for the same reason: lack of anonymous branching. Though that would be possible to fix by automatically creating a branch with a random name whenever someone commits on master.

      PS: If I need to exercise good judgement for doing simple stuff, something is wrong.

  109. rdm September 5, 2012 at 12:29 am

    Arne Babenhauserheide :

    rdm :
    Why should you need to change the commands?

    Because if you are not already used to git, the current commands are pretty unintuitive and hard to learn.

    So, if you are seriously talking about modifying git, why not introduce new commands that work the way you want them to work?

    • Arne Babenhauserheide September 5, 2012 at 5:55 am

      There are several reasons:

      * They won’t be default, so I would have to bring my adaptions everywhere I go to be able to do basic stuff.
      * If they’d be integrated into git, I would not be able to use the words commit, push, pull, merge, …
      * Why reinvent the wheel (and add my own mistakes)? Mercurial already does all that. And since the Mercurial devs discuss the interface in depth before adding anything, the number of unintuitive options is extremely low.

      • rdm September 5, 2012 at 7:17 am

        Arne Babenhauserheide :
        There are several reasons:
        * They won’t be default, so I would have to bring my adaptions everywhere I go to be able to do basic stuff.
        * If they’d be integrated into git, I would not be able to use the words commit, push, pull, merge, …
        * Why reinvent the wheel (and add my own mistakes)? Mercurial already does all that. And since the Mercurial devs discuss the interface in depth before adding anything, the number of unintuitive options is extremely low.

        “Won’t be default” is going to be the case for anything new that you write. You’d have this problem even if you could change the commands without breaking any shell scripts.

        So you are not actually trying to solve the problem of how to improve the UI. You are just finding reasons to object to it.

        Meanwhile: it’s fine to admire Mercurial. But you’re missing the boat if you characterize that admiration as contrived criticisms of git. Just say what you like about hg and have fun with it…

      • Drak September 5, 2012 at 7:57 am

        rdm :
        Meanwhile: it’s fine to admire Mercurial. But you’re missing the boat if you characterize that admiration as contrived criticisms of git.

        I think you’re missing my point. In my opinion git is pretty much unfixable for several reasons:

        * The default commands are unintuitive,
        * The commands are really hard to change constructively because they are intended to be used in scripts,
        * Regardless of that, the commands change in small ways, which don’t hurt small scripts but make full-featured commandline ui replacements hard to maintain and
        * The community around git has quite a nonsignificant proportion of quite vocal people who say and mean stuff like this: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-357

        I am forced to use git in some projects (or rather: was forced till I switched to using hg-git), and I got bitten by it quite badly a few times. Due to that I think that promoting git over equally powerful but easier to use solutions is a problem for making free DVCS systems become the de-facto standard – with the goal of replacing all unfree versioning tools (from VSS over Clearcase to TimeMachine).

        For everyone who writes stuff like “finally someone said it” in here, there are likely hundreds of people who silently harbor a hate for git – and project that hate over to all other free software tools (because its shortcomings are so typical of early free software utilities). And those are the people who could really help free software.

        …ok, now I framed git as harming free software. Please read this with a grain of salt: Git is a great tool. I just think that it is not the best, despite its popularity, and that other tools would draw more people towards free software and DVCS – and even more importantly: alienate less people.

      • rdm September 5, 2012 at 10:36 am

        Drak :

        rdm :
        Meanwhile: it’s fine to admire Mercurial. But you’re missing the boat if you characterize that admiration as contrived criticisms of git.

        I think you’re missing my point. In my opinion git is pretty much unfixable for several reasons:
        * The default commands are unintuitive,
        * The commands are really hard to change constructively because they are intended to be used in scripts,
        * Regardless of that, the commands change in small ways, which don’t hurt small scripts but make full-featured commandline ui replacements hard to maintain and
        * The community around git has quite a nonsignificant proportion of quite vocal people who say and mean stuff like this: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-357
        I am forced to use git in some projects (or rather: was forced till I switched to using hg-git), and I got bitten by it quite badly a few times. Due to that I think that promoting git over equally powerful but easier to use solutions is a problem for making free DVCS systems become the de-facto standard – with the goal of replacing all unfree versioning tools (from VSS over Clearcase to TimeMachine).
        For everyone who writes stuff like “finally someone said it” in here, there are likely hundreds of people who silently harbor a hate for git – and project that hate over to all other free software tools (because its shortcomings are so typical of early free software utilities). And those are the people who could really help free software.
        …ok, now I framed git as harming free software. Please read this with a grain of salt: Git is a great tool. I just think that it is not the best, despite its popularity, and that other tools would draw more people towards free software and DVCS – and even more importantly: alienate less people.

        Drak :

        rdm :
        Meanwhile: it’s fine to admire Mercurial. But you’re missing the boat if you characterize that admiration as contrived criticisms of git.

        I think you’re missing my point. In my opinion git is pretty much unfixable for several reasons:
        * The default commands are unintuitive,
        * The commands are really hard to change constructively because they are intended to be used in scripts,
        * Regardless of that, the commands change in small ways, which don’t hurt small scripts but make full-featured commandline ui replacements hard to maintain and
        * The community around git has quite a nonsignificant proportion of quite vocal people who say and mean stuff like this: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-357
        I am forced to use git in some projects (or rather: was forced till I switched to using hg-git), and I got bitten by it quite badly a few times. Due to that I think that promoting git over equally powerful but easier to use solutions is a problem for making free DVCS systems become the de-facto standard – with the goal of replacing all unfree versioning tools (from VSS over Clearcase to TimeMachine).
        For everyone who writes stuff like “finally someone said it” in here, there are likely hundreds of people who silently harbor a hate for git – and project that hate over to all other free software tools (because its shortcomings are so typical of early free software utilities). And those are the people who could really help free software.
        …ok, now I framed git as harming free software. Please read this with a grain of salt: Git is a great tool. I just think that it is not the best, despite its popularity, and that other tools would draw more people towards free software and DVCS – and even more importantly: alienate less people.

        Being a newcomer to git, and working with it, and helping others with less experience than I use it, I do not think that “the commands are unintuitive” is a real issue. In my mind the biggest problem is that I need to tell everyone I work with to use:


        git config --global push.default current

        This command means that


        git push (without any file name)

        only pushes the current branch. That’s not the default behavior, and that is tremendously confusing.

        Once that’s out of the way, the recipes for git init and git clone combined with these commands, are pretty much all that I ever use:

        push and pull:

        git push -u
        git pull

        branch switching (and creating a new local copy of a known remote branch):

        git checkout BRANCHNAME
        git checkout -b REMOTEBRANCHNAME remotes/origin/REMOTEBRANCHNAME

        branch creation and deletion:

        git checkout -b NEWBRANCHNAME
        git branch -D DEADBRANCHNAME (or maybe use a small -d if I'm paranoid that I had work on that branch)

        janitorial cleanup:

        git gc
        git fetch --prune origin
        git reset --hard (to throw away changes)
        git reset --soft (to undo a commit that was on the wrong branch)

        and queries

        git status
        git diff (sometimes with arguments)
        git branch

        and, of course

        git add (with file names)
        git commit -m 'message'
        git merge (branchname)

        Now, you can say that this is unintuitive, and I’ll grant that I’ve not spelled out ever detail of why I’d use these commands. But as near as I can tell the big “intuitive” issue is that we have multiple repositories with git — when I commit, I am committing to my local repository, not to some other repository. I own my local repository, and it can only include changes that I bring into it. If I’m being paranoid I might set up another local repository to pull into — this way I can pull changes and discard the entire repository if I don’t like them.

        And no one that I work with uses rebase. Ever.

        And if someone creates a problem for someone else, that person is responsible for fixing it. It sounds like some people posting in this forum don’t work with people that are responsible for fixing the problems they create. But I feel that that’s a social problem and not a git problem.

        That last concept is worth repeating: If you are working with people that will not take responsibility for fixing the problems that they create, your life is going to be unpleasant. You are going to have a lot of frustrating experiences, cleaning up other people’s messes.

        And if you feel that you need better tools, to cope with other people’s messes, so be it. Personally, I think that that problem should not be considered a technical problem, but a social problem.

        I do wish that git could be configured to never allow a local name for a branch to differ from the remote name for a branch. But by restricting myself to the above commands (and note that I never name a branch during push nor pull), I get close enough to that ideal for me to get my job done.

        As for the comment about “computer scientists” — my guess is the person making that comment does not understand the scientific process. (From my point of view, the closest thing to a “computer scientist” is someone that actively practices test first design, and that doesn’t even make sense as a constraint on git use.) I think we should ignore ignorant comments like that.

        As for people that hate git and/or feel the need to blow off steam… *shrug* yes… haters are going to hate, or something like that. But if they want to have a coherent discussion about the problems that they are encountering, and I have the time and interest, I might try seeing if I can talk with them on some sort of reasonable basis.

        This comment was rather long and I wish I could preview it before it goes live — here’s hoping that it doesn’t look too dumb…

      • Drak September 5, 2012 at 11:16 pm

        rdm :
        Being a newcomer to git, and working with it, and helping others with less experience than I use it, I do not think that “the commands are unintuitive” is a real issue. In my mind the biggest problem is that I need to tell everyone I work with to use:

        git push -u
        git pull
        git checkout BRANCHNAME
        git checkout -b REMOTEBRANCHNAME remotes/origin/REMOTEBRANCHNAME
        git checkout -b NEWBRANCHNAME
        git branch -D DEADBRANCHNAME (or maybe use a small -d if I'm paranoid that I had work on that branch)
        git gc
        git fetch --prune origin
        git reset --hard (to throw away changes)
        git reset --soft (to undo a commit that was on the wrong branch)
        git status
        git diff (sometimes with arguments)
        git branch
        git add (with file names)
        git commit -m 'message'
        git merge (branchname)

        Now, you can say that this is unintuitive, and I’ll grant that I’ve not spelled out ever detail of why I’d use these commands. But as near as I can tell the big “intuitive” issue is that we have multiple repositories with git

        If you manage to get people to restrict themselves to those commands, you should have a quite solid setup which people can enter nicely.

        But I think that these are already far too many commands.

        * git branch and git checkout -b NEW should be redundant.
        * There are two calls to reset, which do very different things.
        * why do you need fetch –prune? Is there any reason to not prune?
        * why the need to give the local and the remote branchname on checkout? If it exists in origin and not locally, why should I ever not want the branch from origin?
        * why do you need git gc? (actually you don’t need it anymore, since there’s auto-gc)

        In my opinion an intuitive set of commands would rather be


        git push
        git pull
        git fetch
        git checkout BRANCHNAME
        git branch -d DEADBRANCHNAME
        git reset
        git status
        git diff (sometimes with arguments)
        git add (with file names)
        git commit -m 'message'
        git merge (branchname)

        Those are still too many (11 commands for the core functionality), but since they are for different tasks, you could say “local work: checkout, branch, reset, status, diff, add, commit, merge” and “sharing changes: push, pull, fetch”.

        Checkout/branch and reset could be made redundant, since you can just checkout an earlier commit.

        But restricting checkout to getting branches is the best reason I ever saw for forcing people to use branches. I still don’t like that forcing, but if you make it a workflow, that you never checkout commits themselves, it can help you.

        Could you do `git reset –soft` via `git checkout BRANCH~1; git branch BRANCH`?

        Pull vs. fetch still disturbs the image. You should only need pull, if you work on a remote branch, after all. So cut pull and always merge remote branches explicitely.

        Then the commands would reduce to


        git push
        git fetch
        git checkout BRANCHNAME
        git checkout BRANCHNAME~1
        git branch BRANCHNAME
        git branch -d BRANCHNAME
        git status
        git diff (sometimes with arguments)
        git add (with file names)
        git commit -m 'message'
        git merge BRANCHNAME

        That’s 9 commands now, where 2 commands have 2 different ways of calling them: checkout gets a branch or earlier commits on the branch, while the other sets or deletes the branch.

        7 commands for local work, 2 for sharing work.

        Still too much, but hard to get smaller.

        I’m pretty sure that someone will now say “git does not work like that”. But well: It should.

        This comment was rather long and I wish I could preview it before it goes live — here’s hoping that it doesn’t look too dumb…

        I think it’s quite good.
        Though it would be nice to be able to branch it instead of having to copy your commands. Being able to show a diff between your commands and those I consider mostly sane :)

      • Arne Babenhauserheide September 6, 2012 at 11:11 pm

        rdm :
        Ok, yes: git also does not solve the “no one is in charge” problem — it was originally designed for a notable case where this had been solved for decades.

        The problem does not only arise when “noone is in charge”, but as soon as the system is not fully hierarchic.

        In Linux kernel development you have clear hierarchies: There is Linus and there are his lieutenants. Some lieutenants release special builds of their domain. And you have groups working on a clearly limited area of the kernel, who rebase once their changes get accepted.

        Now imagine this as a writing group (I am a hobby author, so my VCS has to work for that task, too). Someone rewrote a part of a book (=commit0) and others get his changes. They like some key phrases and use them in their parts (=commits). Now the rewritten part gets accepted, but rebased, so history appears linear.

        All those who used that commit0 have to rebase all their work to the new base of commit0.

        You might have someone in charge of publishing the final book, but if the writers coordinate independently, he can either not rebase at all, or break their work repeatedly. As such git cements a hierarchy: it makes it less likely that the non-leaders build their own versions with changes from different groups, because doing so means that rebasing on part of the leader would create a big burden for all of them.

        Interestingly Linus himself warns against rebasing – possibly for exactly that reason: http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html

        Essentially he says “as long as you’re not ready, send patches around, but don’t publish git history”.

        But git itself does not help you with that: It will happily break other peoples history, without even giving a warning. It does not track for you what has been published (and thus should not be committed) and if a given rebase would be safe. You have to keep all that in your mind – where you would normally rather keep more of the structure of your code.

        So git makes it very easy for you to make mistakes, but really hard to fix them (because other people have to fix your mistakes in their repositories).

        And that irritates me. It’s like a road on which someone planted snares on purpose – and then tells you to avoid them.

      • rdm September 6, 2012 at 11:53 pm

        Arne Babenhauserheide :
        The problem does not only arise when “noone is in charge”, but as soon as the system is not fully hierarchic.
        In Linux kernel development you have clear hierarchies: There is Linus and there are his lieutenants. Some lieutenants release special builds of their domain. And you have groups working on a clearly limited area of the kernel, who rebase once their changes get accepted.
        Now imagine this as a writing group (I am a hobby author, so my VCS has to work for that task, too). Someone rewrote a part of a book (=commit0) and others get his changes. They like some key phrases and use them in their parts (=commits). Now the rewritten part gets accepted, but rebased, so history appears linear.

        And that irritates me. It’s like a road on which someone planted snares on purpose – and then tells you to avoid them.

        Right… do not accept rebases. Rebases might be fine for cleaning up your work before presenting it to someone else, but it’s silly to expect someone else to want to accept your rewrite of their history.

        Accepting rebases is like copying and pasting javascript urls — yes, if you completely understand what’s going on, it can be useful. But if you do not understand what you are doing, down to the last relevant detail, you’re just creating a security hole.

        Anyways, if someone sent me a rebase and I wanted the change, I might accept the changed content without accepting the history change. And, quite likely, I’d want to ask them to do the tedious work. If it’s a gift, though, I’d probably just smash their entire set of changes down into a single delta from my current branch head.

  110. rdm September 6, 2012 at 12:44 am

    Drak :
    If you manage to get people to restrict themselves to those commands, you should have a quite solid setup which people can enter nicely.
    But I think that these are already far too many commands.
    * git branch and git checkout -b NEW should be redundant.
    * There are two calls to reset, which do very different things.
    * why do you need fetch –prune? Is there any reason to not prune?
    * why the need to give the local and the remote branchname on checkout? If it exists in origin and not locally, why should I ever not want the branch from origin?
    * why do you need git gc? (actually you don’t need it anymore, since there’s auto-gc)
    In my opinion an intuitive set of commands would rather be

    git push
    git pull
    git fetch
    git checkout BRANCHNAME
    git branch -d DEADBRANCHNAME
    git reset
    git status
    git diff (sometimes with arguments)
    git add (with file names)
    git commit -m 'message'
    git merge (branchname)

    Those are still too many (11 commands for the core functionality), but since they are for different tasks, you could say “local work: checkout, branch, reset, status, diff, add, commit, merge” and “sharing changes: push, pull, fetch”.
    Checkout/branch and reset could be made redundant, since you can just checkout an earlier commit.
    But restricting checkout to getting branches is the best reason I ever saw for forcing people to use branches. I still don’t like that forcing, but if you make it a workflow, that you never checkout commits themselves, it can help you.
    Could you do `git reset –soft` via `git checkout BRANCH~1; git branch BRANCH`?
    Pull vs. fetch still disturbs the image. You should only need pull, if you work on a remote branch, after all. So cut pull and always merge remote branches explicitely.
    Then the commands would reduce to

    git push
    git fetch
    git checkout BRANCHNAME
    git checkout BRANCHNAME~1
    git branch BRANCHNAME
    git branch -d BRANCHNAME
    git status
    git diff (sometimes with arguments)
    git add (with file names)
    git commit -m 'message'
    git merge BRANCHNAME

    That’s 9 commands now, where 2 commands have 2 different ways of calling them: checkout gets a branch or earlier commits on the branch, while the other sets or deletes the branch.
    7 commands for local work, 2 for sharing work.
    Still too much, but hard to get smaller.
    I’m pretty sure that someone will now say “git does not work like that”. But well: It should.

    This comment was rather long and I wish I could preview it before it goes live — here’s hoping that it doesn’t look too dumb…

    I think it’s quite good.
    Though it would be nice to be able to branch it instead of having to copy your commands. Being able to show a diff between your commands and those I consider mostly sane

    1) I use git branch without any arguments, to tell me the name of my current branch. I advise people not to use git branch with a branch name.

    2) People need to learn that when working with git this way there’s a command prefix which determines what action git will take. That’s only a minor wart, though, if people avoid using commands designed for a different workflow, and limit themselves to a locally meaningful subset of its capabilities.

    3) fetch –prune deletes local branches which were deleted in the remote (along with bringing the local copy up to date with the remote). When your team is productively generating several branches an hour, after a few months things can start slowing down. So someone needs to delete the branches from the remote and fetch –prune copies those deletions locally.

    4) I really wish I could tell git “I want to work in single remote mode, local name should always match remote name”, with a corresponding “create this branch based on the remote instance” command option. It does not have that right now, though, so I have to cope with this issue somehow.

    5) git gc is for windows machines which can cause the auto gc to fail. The workaround is: when you reboot your machine, run git gc in your active repository.

    6) The distinction between “checkout” and “reset” has to do with the distinction between “working copy” and “staged copy” and “history”. git add is adding to your staged copy. git commit is adding your staged content to your current branch of history. git reset –soft is removing the most recent local history entry (and ideally, I’d like it to throw an error if that entry existed in the remote). git reset –hard makes your staged and working copies match history. I can easily imagine a new command set which is more technical, requiring explicit keywords to represent each of these three data structures. Until then, I use http://marklodato.github.com/visual-git-guide/index-en.html

    Anyways: checkout without -b updates working copy. checkout with -b also creates a branch in history. checkout with -b and two arguments pulls that branch from the named remote. (or it can fail if you give it names that don’t work.) All of this is additive only. git reset is subtractive — it’s discarding information (and should only be used to erase minor errors). And I’m not sure that adding a new “subtractive data” syntactic element to save a command is a worthwhile change.

    7) Note also that I use a shell script which looks something like this:

    #!/bin/sh
    set -e
    branch=`git branch|awk ‘/\*/{print $2}’`
    if [ master == “$branch” ]; then onestep=true; else onestep=false; fi
    trap “git checkout $branch” EXIT
    git fetch –prune origin
    git pull
    $onestep || git checkout master
    git pull
    $onestep || git checkout $branch
    $onestep || git merge master
    git merge origin
    trap “:” EXIT

    (I’ve cleaned out some language and environment specific cleanup and requirements stuff). I’ve been considering adding the -ff-only option, but so far I’ve not seen any problems that that would solve for me.

    So this brings down everything from git and possibly chokes if something conflicting has happened. If the conflict is not trivial, I’ll clone another copy of the repository so I can inspect the changes, and decide what to do about them. So far, the one time that that has happened, I went to the developer who caused the problem, talked to him about it, and he cleaned up the problem.

    8) If git could have a “single remote mode” I agree that it should also be able to do –prune locally. But I forgot to mention git branch -a in my list of commands we use and perhaps in single remote mode it should do an implicit git fetch, if it can.

    Perhaps it’s worth noting here that some people use git differently. “single remote mode” implies a team working against the same repository, which is inspired by github. In “multi-remote mode” which I do not use, people apparently use it as more of a test bed, lab and community publish mechanism. Anyways, not everyone uses github, and things that seem necessary when using github can be silly in other contexts.

    So, anyways, my thing has been to discover enough about how git works to use it, as is, sensibly. And I have been trying to wrap my mind around a minimal set of changes, that fit within the “git design” to ease my major pain points. So far those issues all have seemed to resolve around the idea that local branch names can be different from remote branch names. Since I do not need that feature, I have been fantasizing about “single remote mode” and how git could behave if it had that.

    • rdm September 6, 2012 at 12:46 am

      actually.. to some degree you are right about reset and checkout, I should think about that more.

    • Arne Babenhauserheide September 6, 2012 at 7:38 pm

      For fetch without –prune, I think it would be nice to have it prune those branches automatically which are neither checked out nor changed locally nor ancestors of local branches.

      That way you would likely never need the –prune, because all useless remote branches would disappear automatically and the others would stick.

    • Arne Babenhauserheide September 6, 2012 at 7:48 pm

      note that the branch behavior in your single remote mode is the normal behavior for named branches and bookmarks in Mercurial. Additionally it has diverging-change detection, though: named branches can have multiple heads and diverging bookmarks automatically add a postfix to the remote bookmark.

      Consider that you have a refactor branch and your colleague „mark“ has a refactor branch. When you pull the changes from him with Mercurial, you now get either the refactor branch with 2 heads (for named branches) or the bookmarks refactor and refactor@mark.

      If you use it with a shared repository, the bookmarks would instead be named refactor and refactor@default, since the default remote repository is called default in mercurial.

      And this works with multiple remotes, thanks to the divergence detection.

  111. rdm September 7, 2012 at 12:02 am

    Arne Babenhauserheide :
    For fetch without –prune, I think it would be nice to have it prune those branches automatically which are neither checked out nor changed locally nor ancestors of local branches.
    That way you would likely never need the –prune, because all useless remote branches would disappear automatically and the others would stick.

    That could be annoying. You checkout a local copy of a remote branch, then study it some, and it’s actively being worked on so you want to see if there’s any changes so you do a git pull and it vanishes (because pull uses fetch). Maybe you clean this up by never pruning the current branch, but I feel like there’s other subtle consequences lurking in there (especially since once a branch is merged it’s an ancestor of the resulting branch).

    But I think I see what you are getting at.

    I think if I were going to try to implement something to satisfy this way of thinking, I’d give git a “cached mode” where the local repository is assumed to be a cached copy of the remote repository whenever possible. In other words, it would assume that upstream was available and any remote branch would be assumed to exist locally — the local repository would be a cache of the remote.

    And, to make this work cleanly, remote would have to be in an “append only” mode — it would be configured to only allow additions with perhaps a “slow deletion” mode where deleted content first is hidden for a long period of time and only is actually removed from the repository after a painfully long wait (weeks, months).

  112. Pingback: git hates

  113. tbxi September 12, 2012 at 8:16 pm

    1. Index may be ignored (use commit -a/-A), tags may be ignored (they are strap-on data).
    4. Tags and reflog may be ignored.
    6. Guess what, Git _was made_ (initially) by and for Linus himself. I wage to say users who don’t want to deal with it should be using tarballs. (Web-)Interfaces like cgit can produce one for an arbitrary hash if you do at one time need one just to eschew the revision
    control system.
    7. People mentioned it: git fsck
    9. Yes, history is the important product, because it can reduce the amount of WTFs. http://commadot.com/wp-content/uploads/2009/02/wtf.png

    • arnebab September 13, 2012 at 5:52 am

      tbxi :
      6. Guess what, Git _was made_ (initially) by and for Linus himself. I wage to say users who don’t want to deal with it should be using tarballs. (Web-)Interfaces like cgit can produce one for an arbitrary hash if you do at one time need one just to eschew the revision
      control system.

      Or a system which works better for them. If enough people would realize that the fraction of developers who maintain a project with over 100 contributors is far below 1%, then it’s likely that more would realize that git isn’t made for the regular developer – and that hey themselves are most likely regular developers.

      9. Yes, history is the important product, because it can reduce the amount of WTFs. http://commadot.com/wp-content/uploads/2009/02/wtf.png

      Good code reduces the amount of WTFs.

      History can help, but good code goes first. And if you worry too much about the history, it can have a bad impact on your code.

  114. nobar September 21, 2012 at 9:20 am

    You are dead *right* about the “crappy documentation”. But now that I have figured it out, I think Git is awesome and I *hate* having to use Subversion.

    How best to learn Git? Make heavy use of the graphical tools such as “gitk” and “git-gui”. Stackoverflow.com seems to have the answer to any specific “howto” question.

  115. just jared September 24, 2012 at 10:32 pm

    Thanks , I’ve just been searching for info approximately this subject for a long time and yours is the greatest I’ve discovered till now.
    But, what about the conclusion? Are you certain about the supply?

  116. Bernd Jendrissek September 25, 2012 at 9:12 pm

    “git checkout .” is what I use when I want to zap all local changes. I *don’t* want to use git reset –hard, because that also resets the branch HEAD, which I almost never want to do. (Usually what happens is that I litter my code with printf to debug something that started breaking a few commits ago, that I didn’t realize at the time.)

    Overall, I understand your frustrations with git. I probably once shared them, but as I get more and more used to git, I find myself bumping into the sharp edges less often. The experience reminds me of how, at first, I *hated* vi[m]: what blatant disregard for an intuitive interface! What capricious use of random letters for commands! But due to my constrained home PC at the time, I was forced to learn it (emacs was simply too big – to install, let alone to run), and over the years we’ve become best buddies.

    • Arne Babenhauserheide September 26, 2012 at 7:18 am

      The difference today is that you don’t actually have to go through that hassle, since I’m pretty sure that Mercurial runs on yout platform of choice. And that you have to know to choose checkout . instead of reset –hard to undo uncommitted changes is aproblem in itself… both do it, but one has a side effect while the other does not always work.

      It’s clear that you can get git to work for you, but you very likely(1) don’t get something extra for the additional work you put in.

      (1): You only get something extra, if you happen to be maintaines of a program with more than 100 developers – and then at the expense of the others. That’s my current understanding after using both – though I use Mercurial much more, because I at one point decided to not risk hitting any more pointy edges of git – using the mostly safe subset when I have to. That means, that my perception today is skewed, but for good reasons…

  117. Kaysey October 1, 2012 at 10:02 pm

    Your top ten is very fair IMHO. I’m looking at moving my development to git, all hosted internally (not using GitHub). I’ve used commercial CM for over 18 years and Git amazes and worries me deeply.

    I love Gits ability to work out what’s changed in your working tree and thus what to commit. When you’re working on multi million LOC tree’s, I like that this is extremely fast.

    Switching branches is also very neat.

    Yep, that’s about it.

    I guess your point #7 is my biggest concern. For a company to keep a central repo of their expensive IP, requires someone to babysit it so no idiot can rebase the history into oblivion. This is a crazy waste of time and money. Hoping that someone has an untarnished clone of it on a PC somewhere that you can recover is not a mitigating strategy!

    Second is that CM should be as close to invisible as possible for the humble developer. A company pays them good money to develop IP. Anything that distracts them from that is a waste of development $$. With Git, your devs will be using useful brain energy on high level of tricky mental gymnastics trying to work out what command to use, which branch to merge with and undoing things that went “wrong”. While they are doing that, your other n-1 developers will be sat there waiting patiently..

    My ideal SCM system would have a lot of the great ideas of GIT, but without the complexity. You always need someone who knows the internals of a SCM system, who can set up the branches and the integration strategy.. but the developers should have a much easier set of commands to use.

    • Arne Babenhauserheide October 19, 2012 at 7:25 am

      You could have a look at Mercurial. An example Workflow I wrote just requires the developers to commit and merge – and I can explain it in 3 steps:

      1. you do all the work on default – except for hotfixes.

      2. on stable you only do hotfixes, merges for release and tagging for release. Only maintainers touch stable.

      3. you can use arbitrary feature-branches, as long as you don’t call them default or stable. They always start at default (since you do all the work on default).

      http://draketo.de/light/english/mercurial/complete-branching-strategy (with task diagram :) )

      Your regular developers only need to know three things:

      (a) commit changes: (edit); hg ci -m “message”

      (b) continue development after a release: hg update; (edit); hg ci -m “message”

      (c) Share changes: hg pull; (if new changes: hg merge; (if conflict: hg resolve -l (fix conflicts); hg resolve -m;) hg commit -m “merge work from others”;) hg push

      More advanced developers can use feature branches and a host of other features, but no one has to.

  118. Java Tutorial October 3, 2012 at 6:23 pm

    Nothing is better than CVS and SVN, I tried perforce, clear case and GIT but only like CVS and SVN .

  119. waynoss October 11, 2012 at 9:15 am

    Yep you have to take a solid week out of your life and work sched to learn the monster. Like others have said, guis are the only way to go far as i’m concerned – command line just seems crazy to me.. Get the concepts then use smartgit is my plan.
    Thanks for the post.

  120. Johan October 11, 2012 at 9:28 pm

    The way I like to put it is, Git was written by Martians. They’re very smart, but their brains don’t work like humans’ do.

    While they are smart, they are not brilliant. If they were, they wouldn’t have created such a mess in the first place.

  121. Git is awesome October 17, 2012 at 4:53 am

    From my time in the field it seems like a lot of people have forewent actually looking at the problem of VCS. Most chose a centralized one and left the developers to fight with it. In my opinion, things like Eclipse cover up the giant gaping hole in centralized versioning systems. If everyone had to use SVN and CVS command line, they would run screaming for the hills. Most people cannot conduct a merge even in SVN WITH a GUI. There’s nothing that can be done to help people that don’t understand VCS. If you don’t know how to use a versioning system, any versioning system is going to be difficult to imagine.

    Then there’s Git. Git to me is a VCS for people who have seen the problems in other VCS products. I think Linus saw the flaws in existing tools and truly tried to create one that would help everyone. It IS complex, but that complexity comes with great flexibility. I am able to use Git to produce just about any imaginable workflow. I’m able to use it behind SVN in my day-to-day work to allow auto-merging where I’d usually have to manually alter files in Eclipse.

    Local branching support and stash are the bar for how much git will be of use to you. If all you want is a centralized backup of your work and you’re willing to sacrifice experimental branching and willing to have your project function linearly, then SVN or CVS are for you. There are people who would rather work surrounded by a local VCS bubble in which they can make their changes without being affected by the unwashed masses. I’m one of those people. I find commits important. I find what I commit on what branch to be important. I want to keep around experimental changes locally in case I need to use them again.

    Git is a replacement for not only a centralized version control system, but also a replacement for Eclipse local history. It functions in both ways and allows you to work independently of what you commit, allowing you to push what you want when you want where you want. I have not seen another VCS even come close when you look at the ideas it abstracts.

    The learning curve of the command line is a little steep, I’ll give you that. But is VI not difficult to learn at first? Was bash a walk in the park? Is CVS or SVN easily digestable from command lines alone? Most people I know wind up needing Tortoise or an IDE to make the type of merges I can make in seconds in git.

    Just because something is complex to learn and powerful does not mean it’s a reason for hatred. I find git better than the alternatives because after I learned the basics of what I was actually trying to do, I can stack overflow a way to get there. When I can’t do something in SVN it’s usually just because it’s simply not possible, not because I don’t (yet) know the correct command syntax.

    I understand git command line is probably not for everyone, but I would argue that it SHOULD be for REAL programmers. People who like to get shit done without the tooling getting in their way. SVN and CVS have always felt they could just pulverize my local files even when I have important changes in them. I cannot tell you how many times you wind up resorting to making a copy of your whole workspace just so you can get SVN or CVS out of some retard state in Eclipse and then had to pull diffs back in. I have never done so with Git…because I never had the need to. Git is trying hard to make it so you don’t lose your work. Let it help you.

    • Arne Babenhauserheide October 19, 2012 at 7:38 am

      I readily prefer git to svn, and I would agree with you, if Mercurial did not exist.

      > It [git] IS complex, but that complexity comes with great flexibility.

      If we had no Mercurial, I’d think that this might be true. But I know Mercurial and therefore I know that it’s not the complexity of git which gives the flexibility, but the underlying decentralized model. Mercurial showed me that it is possible to have all that flexibility without the complexity of git.

      The decentralized model gives a lot of flexibility and I would not want to work without that. But git makes it pretty hard for normal developers to harness the power of the model while Mercurial makes it really easy, giving all the safety and convenience without the pain of git.

      So I disagree with your sentence. It implies that the complexity of git is required to get the flexibility of the decentralized model. And that is not true. But creating an interface which makes it easy to use the flexibility of the model is a pretty hard task – and that’s the task at which git failed and Mercurial mostly succeeded. The google folks called that the “sweet spot” of VCS. It’s not yet perfect and there are some points where git actually provides more convenience (remotes are nice!), but those are mostly relevant for maintainers of big projects and not for regular developers.

    • Doctor Who November 8, 2012 at 7:46 am

      > Is CVS or SVN easily digestable from command lines alone? Most people I know wind up needing Tortoise or an IDE to make the type of merges I can make in seconds in git.

      SVN is, indeed, very simple to understand. I know training guys from my company, most people non-technical are able to work with it just fine after one hour of basic training. And merging is merging, the git heads often pretend to save a lot of time on merging with their great system while in fact most time is spent on resolving the conflicts in actual contents. And a VCS can hardly help you there.

      > “Just because something is complex to learn and powerful does not mean it’s a reason for hatred.”

      Did you read the same article above as I did? hatred doesn’t come from the fact of dealing with something powerful but from the thoroughly braindead user interface of this powerful thing.

  122. Pingback: Git is awful | Smash Company

  123. Don November 1, 2012 at 10:40 pm

    Git is like a ferrari covered in fresh dog turd. Yes, the fundamentals are awesome. But it’s hard to think of anything with a worse interface. Consider a really, really simple and common action: deleting a non-merged branch. Based on analogy with “git remote” I would expect “git branch rm –force foo”. Git seems happy with that; but instead of deleting, it creates a copy of foo called ‘rm’! My next guess would be
    “git branch –force -d foo”, but that’s wrong too. You need “git branch -D foo”. That’s really apalling. How on earth did they do such an awful job? The whole thing is inexcusable.
    Sure, when you’ve driven the ferrarri for long enough, most days you hardly notice the smell any more. But some days you just wish they’d clean the seats.

  124. demizeyde November 4, 2012 at 5:47 am

    Linus Torvalds is actually against GitHubs pull requests. You were supposed to send a patch to the ML and then a maintainer merged the patch.

  125. Gary November 6, 2012 at 5:38 am

    Indeed, I’m hating Git. It is NOT friendly for Enterprize usage (I’m at Intel). Git was obviously designed by college students who worked in groups of 4-6, and wanted to make big changes entirely disconnected from any repository, and wanted NOBODY else to own the official “known good source for release”. Fine. Use Git. Submit your college class semester project.

    Git is NOT happy at Intel. There MUST be one “holy and blessed” repository for burning released chips. In this environment, Git sucks. All developers want to do is “Update, Commit” (repeat), and truthfully, that’s ALL you want developers to do! Focus on their code, their features. Code analysis tools and Build machines will catch errors and reject submits. In this environment, SVN or Perforce are kings.

  126. Sean Roehnelt November 6, 2012 at 7:29 am

    Oh, how I wish this post existed when I was forced into the Git world. It would have helped me understand a little bit better how to hold my head when I try to understand anything related to Git.

  127. Sergey Tihon November 6, 2012 at 9:36 am

    Reblogged this on Sergey Tihon's Blog and commented:
    Exactly the same emotions

  128. Doctor Who November 8, 2012 at 7:32 am

    Steve, thank you so much for this summary. It points out most things I have been feeling for git in the last couple of years.

    Honestly, git is a toy from nerds made for other githeads ticking the same way as they do. It seems to match the taste of many project managers who then quickly switch to git, forcing whole communities to use this user-unfriendly software. And a couple of other guys that want COMMIT; COMMIT, COMMIT every second minute.

    The bad thing about git is that it isn’t actually really bad for most things but is totally embarrassing for other basic features, like not being able to handle empty directories or the crude hacks it uses to track file renaming operations. And the consistency of the user interface somehow reminds me on PHP’s API – inconsistent behavior, dangerous commands are just one CLI switch away from harmless operation, and the vocabulary which has been partially stolen from CVS/SVN and others with the meanings totally mixed up.

    Sorry git guys, that sucks. I just don’t trust a VCS which feels like steering on ice.

  129. Pingback: git vs svn | objetweb

  130. roychri November 27, 2012 at 10:38 am

    Very good article Steve!

    I thought I was too old, or too stupid, or a little bit of both. I am glad I am not the only one with the same frustrations.
    I have been using VCS for 17 years.

    I used RCS, CVS, SVN, Bazzar (just a tad) and now I am using GIT full time for the past 5 months.
    I spent a lot of time learning each and everyone one of them. Knowing my tool is important.
    They each had their strenght and weaknesses (ok, lots of weakness in RCS and CVS).
    I was able to master SVN and it was not frustrating.

    I found Bazzar more intuitive and easy to use than git. I was confident with Bazzar even though I did not use it for a long time. I had the feeling that I was controlling my project.

    With GIT, I am not confident at all. I am always cautious and nervous and.. it’s slowing me down a lot.
    Trying to master git is very frustrating.

    I WANT to be able to master git like I was able to master SVN. I just don’t see the end of the tunnel yet.

    • Dex Barrett (@dexbarrett) December 28, 2012 at 2:03 pm

      Pretty much the same feeling as you. GIT is all fun when you follow a simple forward workflow; I also find the staging area useful when you modify a bunch of files but only a few are ready so you “stage” only those to commit them…. the problems begin once you need to rollback and do more “advanced” stuff (I use the quotes because they shouldn’t feel like advanced things but they do).

      I’ve read the documentation, Scott chacon’s book, articles and everything and yet I don’t feel confident to do things backwards. The reset command is still black magic to me even though I have spent plenty of time reading how it works. You know something is wrong when you need to figure out all the things the commands will do before running them (should I use the –soft flag when reseting to leave the index and tree untouched? If I specify a previous commit using something like HEAD~2 when reseting, how do I ensure the good files are not modified and only the bad files are brought back to the working tree?)

      I know it’s just me not understanding it fully but it’s funny that something that it’s meant to make your development more organized and safe has to be so complicated even for the most basic workflow.

      Steve: the command with the “remote:branch” syntax you may be looking for could be the command used to delete a remote branch–> git push origin :branch_to_delete and yeah, it’s damn weird and inconsistent.

      • rdm December 30, 2012 at 2:59 am

        My take is that resets and other such reversions should never be pushed off into another repository — they are only for cleaning up messes locally. When dealing with other repositories, I think the right approach is to create a new branch that’s fixed up properly. (And, eventually, pruning the damaged branches.)

        The reasons for this might include technical issues, but mostly it’s people issues that this is solving. I do not get to control what other people do in their own repositories.

  131. Mike December 31, 2012 at 11:37 am

    Git? I just don’t get it! there are no reliable tutorials. They all say something different and give no valid examples.

      • rademi January 15, 2013 at 12:34 am

        That tutorial is a nice piece of work, at least the first part, but the bit on rebasing does not convey its destructive potential in [for example] the context of a shared github repository, and the later “multi user” treatment does not fix that, either.

        Rebasing is fine for unshared changes, but it’s an utter mess when you have a shared history with someone else. And, yes, everyone can agree to rebase instead of merge, but that means that you lose the ability to revert to earlier versions of the code!

        If you have a shared history with someone and you really want a re-arranged view of history, you really should put that new view into a new branch. Otherwise, you are not using git as a version control system (which might be fine, but you should never expect that other people want to lose their version control abilities).

  132. Arne Babenhauserheide January 15, 2013 at 7:41 pm

    rademi :
    And, yes, everyone can agree to rebase instead of merge, but that means that you lose the ability to revert to earlier versions of the code!
    …which might be fine, but you should never expect that other people want to lose their version control abilities

    That’s the best rebuttal of rebasing when you get remote changes I ever heard. Thank you for that!

    How come that this “I hate git”-thread is a much better guide on using git practically than the man-pages?
    (“don’t use it, but if you have to, do it safely)

  133. systemBuilder January 16, 2013 at 1:04 pm

    I am pretty certain that GIT was designed by Google to drive the next-generation of load on their search engines, because GIT is the ultimate driver of “help” queries, as in “help, this software has screwed up my tree and I can’t do what I need!”…

  134. darkfader January 16, 2013 at 7:07 pm

    tl;dr
    git is like mercurial with less than 5% extra features and 100% less usability.
    It speaks volumes that git’s adoption is so much bigger in certain circles.

    • Arne Babenhauserheide January 18, 2013 at 8:28 am

      it shows the stergth of group effects and strategicla advantages over utility for the majority I think: Git caters to the maintainer, and who chooses the VCS?

      Interestingly most projects which did a clear check of requirements (mozilla, google, python) came out in favor of Mercurial (with the disclaimer: “I remember this and I like Mercurial much better, so I could have a supports-my-position bias here”).

      • rdm January 18, 2013 at 8:39 am

        yes… and there is also some possibility that you are overgeneralizing here. Consider, for example, consider: https://github.com/google

        On the other hand, Linus Torvalds had some interesting comments on git, and github, visible at https://github.com/torvalds/linux/pull/17 …and after reading his point of view, and thinking about my own experiences, I am wondering how many people are struggling with github, and its workflows, vs. how many are having problems with git in a context which is independent of github?

        That said, everyone has their own needs, and their own ideas of how to address those needs, so personally I do not buy into the idea that one tool can be universally superior to another tool — I am much more interested in the reasons a person uses to pick a tool than I am in the choice they made. (But, sometimes these discussions reveal the kind of view points that I am interested in…)

  135. darkfader January 16, 2013 at 7:12 pm

    and regarding
    8. Burden of VCS maintainance pushed to contributors

    Why you would push the burden of VCS maintenance and branching (i.e. for every “clean patch” if you go by some manuals) to everyone instead of having a group of specialized people do it?
    Oh, because the specialized people are divas and don’t care that the summarized effort is a lot more and scales with the number of contributors? Isn’t that cute?

  136. Arne Babenhauserheide January 20, 2013 at 10:57 am

    rdm :
    yes… and there is also some possibility that you are overgeneralizing here. Consider, for example, consider: https://github.com/google

    That possibility always exists, especially for complex topics.

    But the google hosting is no real counter-example: It shows a handful of projects which chose to not use googlecode…

    The example I showed is not what google does today (it now also offers git for code hosting, see the group effects), but why they chose to use Mercurial:

    Mercurial offers an excellent “sweet spot” in terms of flexibility, simplicity, and speed. – Alex Martelli, Google Tech Lead

    And for me: I have more usability problems with git itself than with github. I wrote some of my reasons and wishes herein our previous discussion here: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-500

  137. Pingback: gitの図 at softelメモ

  138. Pingback: GIT: a Nightmare of Mixed Metaphors – Ventrella Thing

  139. Chris January 26, 2013 at 12:37 am

    I think you got one of those examples wrong, it should be:

    git push master push push more squeeze wriggle merge pull tickle squeal commit puff puff

  140. Jeffrey Ventrella January 28, 2013 at 5:15 am

    Here’s my recent rant on git: “…a Nightmare of Mixed Metaphors” –

    GIT: a Nightmare of Mixed Metaphors


    -Jeffrey

  141. Paul February 1, 2013 at 7:24 pm

    Many thanks for this article.
    I thought it was just me, finding GIT so hard to learn and so ridiculously complicated, having previously Clearcase and then SVN.

  142. Mr. Lee February 5, 2013 at 7:17 am

    tldr;

    Not because of you but because of the subject matter. Anything about git automatically makes my brain shutdown. A few weeks ago I ran into a revolving door and broke my nose. It was less painful that git branching.

  143. Ethan February 7, 2013 at 2:42 am

    “git checkout — ” performing a similar operation as “svn revert ” still gets me.

  144. sswam February 13, 2013 at 1:40 pm

    As an example of git being somewhat batshit insane, this is the method I found necessary to properly and fully garbage collect the repo. There might be some unnecessary steps in there, but yeah… this took quite a while to figure out!

    git remote rm origin || true
    (
    cd .git
    rm -rf refs/remotes/ refs/original/ *_HEAD logs/
    )
    git for-each-ref –format=”%(refname)” refs/original/ | xargs -n1 –no-run-if-empty git update-ref -d
    git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc “$@”

    No git, I do not want you to provide backup services in case I am stupid, I do my own backups before dangerous operations. I want you to do what you’re told, without needing a 10 line script to spell it out!

    I’m not sure if hg is more sensible with garbage collection, I haven’t used it much, but it has a much better reputation for sanity.

    • Jordi Gutiérrez Hermoso February 14, 2013 at 12:54 am

      > I’m not sure if hg is more sensible with garbage collection, I haven’t used it much, but it has a much better reputation for sanity.

      hg doesn’t create garbage to begin with, so there’s no need to collect it either. The closest to garbage that hg has is backup bundles. They’re all stored under .hg/strip-backups and can be deleted at any time, since they’re just backups.

  145. sswam February 13, 2013 at 1:56 pm

    addendum: svn is not comparable to git. hg is the only free product which compares favourably to git.

  146. karl hoover February 14, 2013 at 4:50 am

    There are thousands of medium size, commercial project for which svn is perfect. And I really like the ‘comparative anatomy’ diagrams. Thanks!

  147. mvswdev February 15, 2013 at 11:57 am

    The author is absolutely correct. Git is a nightmare. And it’s not even a version control system, as even Linus admitted: https://lkml.org/lkml/2005/4/8/9

    • steveko February 15, 2013 at 12:09 pm

      Well, I don’t think you can read too much from Linus commenting that after two days, his primitive tool was not *yet* capable of SCM.

  148. Tony Cavanna February 24, 2013 at 7:00 pm

    I’ve just discovered git init will overwrite a repository without question. Just lost a day’s work, restoring my source from backups.

    • steveko February 25, 2013 at 12:22 am

      Really? What was the sequence of events exactly? I get the message “Reinitialized existing Git repository in …”, and nothing is lost.

  149. Tony G February 26, 2013 at 8:01 am

    Haha – pshew this post makes me feel much less stupid. Plus I learned more about how git works from this page then half the other git instruction sources including the oreilly book…LOL!

  150. Diego February 27, 2013 at 1:09 am

    You’ve intentionally removed complexity from the SVN examples and added useless complexity into git examples. Git already has some shortcomings, you should stick to those.

    * For example, how do you avoid pull-requests on subversion? Oh, right, you give write access to everyone? That’s smart and so realistic.
    * Rebase? Never used it, never needed it. If someone wants to put some make-up over their repo history, that’s their problem, it’s not required at all.
    * You can add/commit in one command: commit -a
    * And no, you don’t need to push to a remote unless you’re working with a remote… In which case, you tell me how is subversion better, when you push directly (usually a bunch of changes that don’t fit logically in a unit) without enough testing, since all you want to do is “make it safe” as soon as possible? Half the times you either collide with another dev or you simple screw the main repo for him and for yourself.

    And I could go on, your post is just a bunch of these, with little truth lost among it.

    • steveko February 27, 2013 at 9:24 am

      >For example, how do you avoid pull-requests on subversion? Oh, right, you give write access to everyone? That’s smart and so realistic.

      You’re right, the Subversion open-access model is not equivalent to the Git pull request model.

      > Rebase? Never used it, never needed it. If someone wants to put some make-up over their repo history, that’s their problem, it’s not required at all.

      That’s not the case for everyone. Many projects require contributors to rebase patches.

      > You can add/commit in one command: commit -a

      True – although new files are missed.

      > And no, you don’t need to push to a remote unless you’re working with a remote…

      If you’re not working with a remote, you’re in a completely different category of use: solo developer.

  151. Pingback: kirjoittaessani » Blog Archive » Revisionismus

  152. hossbeast March 7, 2013 at 2:39 pm

    The man pages are one almighty “fuck you”.

    This is officially my favorite thing on the Internet!

  153. Pingback: Git מהשוחות, אמנות אסקי יהודית בגטו ועוד. קריאה קוד פתוח ושיטוט ברשת « טכנולוגיה בשביל אנשים

  154. therealprologic April 24, 2013 at 9:23 am

    As a long time Mercurial and BitBucket user I agree. I find Git to be terribly confusing, unintuitive and cumbersome to use. –JamesMills / prologic

  155. Stephen Leach June 24, 2013 at 8:07 pm

    While I agree to a greater or lesser extent to all the points made in this article, the advantages of git are so compelling I would never select Subversion in preference – and I never expect to have a use for Subversion again. For me, SmartGit/Hg tamed git and made it very simple to drive effectively.

    The key defect of git from my perspective is that is cannot handle files > 2GB in size. I work in GIS and that’s not a particularly large file; files up to 10GB are commonplace. Although I don’t especially want to version control such large data files, I do want to manage them and base my development platform on a single repository with a single API. It seems surprising weakness to me.

    Mercurial and Bazaar also seem like fine tools, with slightly different strengths and weaknesses. I have not spent much time on them, other than to verify that they also suffer from the same irritating defect and hence I have no compelling reason to switch.

  156. Pingback: Free GIT repository hosting | Think Digital, Talk #Interactive

  157. Pingback: River Recycled » From Twitter: Continuing my anti #git ranting. this suits my moo… » The Same River. Twice.

  158. Wes Roberts (@jchook) July 10, 2013 at 6:40 pm

    git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.

  159. Herb Morris July 23, 2013 at 9:19 pm

    Thanks for your excellent, well thought out comments, Steve.

  160. Pingback: Blackmoor Vituperative » I dislike Git

  161. jeabraham August 16, 2013 at 1:49 am

    Thanks for the “bread and butter” figure. It really helps me understand git.

  162. cloa5132013 August 26, 2013 at 6:47 pm

    I guess GIT screams for someone for someone for someone to make a decent interface for it (probably paid for). Most of the issues would then either be bypassed or simplified and probably something like a cutback form for users.

  163. nashvilericEric September 3, 2013 at 3:09 pm

    I’ve been thinking recently about this very issue. It seems noncontroversial to say that git has the best adoption and the strongest architecture. It’s true that there are some great git clients out there which help get you access to that strong architecture. I’ve tried Tower and Gitbox and others. They help, but the complexity of the system, even for not-very-advanced tasks, comes out if you need to do anything besides clone, commit, pull, push, and merge without conflicts.

    I think there’s definitely room out there for a git command line abstraction that thinks about every common case that a contributing developer would come up against, and basically maps those use cases into git commands. GUIs could be built on top of that command line abstraction, but without the abstraction first, the temptation with a GUI is just to give buttons for each command. With git, I don’t think that’s good enough.

    Would someone else want to work on this? Does this sound like a promising idea? I’ve seen some other tools try this but I don’t think they go far enough. Simplification for this would be really, really difficult and require a deep as sea trenches understanding of everything that can happen when you want to, say, undo a commit.

    In a way this could be like “Javascript the good parts” for git. List out all the common end-user workflows, build aliases/scripts/walkthroughs for them that cover all the bare metal decisions your average contributor doesn’t want to have to make (undo commit that has/hasn’t been pushed to remote, push before pulling intentionally(?), rebasing vs merging).

    I’d view such a project a success if it could work for a team of 1-20 developers managing a repository that does basic staging, production, and version tagging contribution behavior and they could learn the whole thing in less time that it takes them to figure out why their git 3-way merge thinks the wrong side is more up to date.

    • steveko September 3, 2013 at 3:24 pm

      Very insightful comments. Working on a project like this, although very valuable, could be unrewarding. As you point out, you’d need a very deep knowledge – but once you get to that level, you may not be so motivated (because, after all, Git is so simple now!) I doubt you’d get much support (if not downright hostility) from the main Git developers, so you could be working in isolation for years, constantly frustrated by small changes in Git’s internals.

      • cloa5132013 September 3, 2013 at 6:14 pm

        Why not just map the command line with intelligent logic- do not delve into the internals of git- sure they might change the commands but that can be patched over. If need be merely hide the command line and simulate keystrokes.

  164. Pingback: Don’t be a git, use subversion | ebeab

  165. etg September 15, 2013 at 11:38 am

    Another issue for me is the impossibility of checking out just one folder of my repository, not the repository as whole.

    I understand the concept of Git managing “projects” in the meaning of “you have to check out everything or nothing” but this is often not the way I need a version control to work.

    Example: I provide several useful files for my company: a LaTeX tree, OpenOffice templates, Office templates etc. A user interested in the LaTeX tree only does “svn checkout …/trunk/latex” and is done. In git she has to clone the whole repository including all branches tags etc. and then has to use the one folder she is interested in.

    Thus I still use svn for this project only to avoid this special issue.

    • rdm September 17, 2013 at 1:27 am

      svn is great if you want to prevent shared ownership – if what you want to prevent is group effort. (cvs is another possibility for that.) There’s nothing wrong with hating git – if what you need is a bottleneck – if git is the wrong tool for you.

      • Drak September 19, 2013 at 3:11 am

        It is possible to dislike git without preferring svn. I wonder whether you tried the DVCS alternatives. Compared to git, the Mercurial UI is wonderful…

      • steveko September 19, 2013 at 2:08 pm

        It’s possible to hate part of something without hating the whole thing. (Hating your government without hating your country.)
        It’s possible to hate one thing without preferring a certain other thing. (You think Git is a 3/10 but SVN is a 2/10.)

  166. Tomas Novoselić September 18, 2013 at 9:17 pm

    Lol, so many git haters and all i see is complaining about things that they don’t understand.

    • sfkleach September 19, 2013 at 3:06 am

      Or, to put it another way, the mismatch between git’s functionality and version control functionality that leads to confusion and disdain.

    • Drak September 19, 2013 at 3:12 am

      Also please do not mistake criticism for hate: I prefer git over svn any day. But it loses to Mercurial by a huge margin.

    • Alex January 14, 2014 at 9:59 pm

      >Lol, so many git haters and all i see is complaining about things that they don’t understand.

      That’s kind of the point, actually.
      I doubt that the people posting here are stupid. Still it requires more time and work to understand git good enough than they may be willing (or paid for) to spend on understanding their version control system.

      The version control system should not be harder to understand than the code itself.

  167. Drak September 19, 2013 at 3:09 am

    Tomas Novoselić :
    Lol, so many git haters and all i see is complaining about things that they don’t understand.

    That so many people do not understand git is not a good sign…

  168. Jam King September 26, 2013 at 7:40 pm

    I’ve used a variety of VCSs over the years and finally stumbled (got lumbered) on Git. A long-long time ago I used CVS (I cant remember much except it was a bit crap). Then we got VSS (absolute crap and dangerous), then SVN (yeaa! happiness at last). Then in one company I worked in an abomination called “AccuRev” was intoduced, an interesting attempt to create a visual UI, some good ideas but so horrible that we needed a support team to look after it. Then I discovered DVCS and Mercurial (enlightenment and bliss). Used it for two years in my last job (still using it for my own stuff on BitBucket). For the last year I’m working in a company that is migrating from a mix of VSS (aargh) and SVN (I know, mad in 2013). My boss has decided that Git is the way to go even though I am the only one in the company with DVCS experience and would much rather use HG. I set up a server in-house with a demo repo, wrote a three page guide for everyone (and pointed them to Joel Spolsky’s excellent hginit tutorial) but no, my boss is insisting on Git. I’ve spent the past few days cursing and gnashing as I’ve tried to set up the Git server on Windows and port a few projects into it (the pain!, thanks to Tim Davis ‘http://www.timdavis.com.au/git/setting-up-a-msysgit-server-with-copssh-on-windows/’ for really trying to explain it all). It’s got to the stage where I’m about to tell my boss it’s HG or I’m outa here…

    • Jens Melgaard October 30, 2013 at 11:17 pm

      Try to look at some of the 3rd party suppliers, I have never ever installed a pure git server my self, but Stash (from Atlassian) was virtually pain free…

      Overall it seems there are more momentum on git these days, e.g. Atlassian adopting it in Stash, Microsoft delivers git integration in Visual Studio and many others… So it might not be such a un-informed choice to adopt it over e.g HG…

      I can second you on that It’s a damn risky decision if you don’t have any in-house that has the knowledge though… But top bosses often tend to think in terms of “That is what they all talk about, so we should go there to…”, and while it’s a decent philosophy on some cases, you need to be ready to pay the price.

      Anyways, 3rd party integration’s can help you… And one thing is initial installation, another is ongoing maintenance and administration, tools like Github Enterprise and Stash can IMO really help here… Even for my personal SVN i found it far easier to just install CollabNet’s subversion edge over a standard subversion server…

  169. Pingback: Some notes and links on DVCS (dynamic version control systems) « The Wiert Corner – irregular stream of stuff

  170. Hirsy October 4, 2013 at 9:41 am

    I actually had to turn down a client because they use git. I got fed up doing 1 hour billable work and 4 (unpaid) hours trying to figure out what git did. Too bad it wasn’t designed better. Oh well, lots of other choices.

    • Tomas Novoselić October 4, 2013 at 3:53 pm

      GIT is state of art software and if you have problem with it, then it is more likely that you should debug relation between chair and keyboard, rather than trying to figure out “what git did”

      • Jam King October 5, 2013 at 2:20 am

        The only thing about GIT that’s ‘state of the art’ is the concept. There is no doubt that DVCS is the way to go. Making DVCS hard is not ‘state of the art’. Mercurial (which is what I use at the moment) is at least consistent and pretty quick to learn and easy to use every day. It’s not because I learned it first that I prefer HG (SVN was the third ‘traditional’ VCS system I learned and easily the best). When I learned HG I had a number of tasks to accomplish, learn the DVCS concepts, learn HG itself and learn to set up and use remote HG servers. I came to Git with an open mind (I was genuinely interested in adding another VCS to my repertoire) but the pain was too much especially in setting up a server for the team. From nothing to a server supporting a few HG repos was an hour or two. With Git I gave up after two days. I’m not smart enough, obviously.

      • Tomas Novoselić October 6, 2013 at 5:34 am

        Well, in my personal experience, I had a problem “to get the mindset”, but then I started to work with it and beside few occasional issues mostly produced by me or someone from my team, it is a lifesaver… I really can’t imagine to work without it… I do have some little experience with Mercurial, but that long time ago. I would like to try it again, but there is really no need (for my team, I’m not saying someone doesn’t like anything else better)
        Once we started to practice http://nvie.com/posts/a-successful-git-branching-model/ our git troubles are mostly based on “someone didn’t follow the rules”, but even in that case we always managed.
        I am kind of sad when I see many people in this thread are spiting all over git, but for very wrong reasons, especially if they like SVN…that is just wrong :(

  171. Phil October 16, 2013 at 4:19 am

    http://www.sourcetreeapp.com/

    Atlassian makes a this great free git client that handles most of your common git tasks without any command line work.

    • steveko October 16, 2013 at 11:30 am

      Yeah, SourceTree is pretty good. It does a great job of helping you understand exactly what mess you’ve gotten into this time.

  172. Rashid November 1, 2013 at 10:22 pm

    Steve agreed 100%. Unfortunaltey what sells in IT is complexity not common sense

    • steveko November 1, 2013 at 10:30 pm

      I don’t think that logic holds. There are hundreds of technologies that have done very well due to making a complex problem very simple. Git has succeeded in spite of its complexity, not because of it. If there was a simpler version, I think that’d do pretty well.

    • Stephen Leach November 1, 2013 at 11:21 pm

      I honestly disagree. git succeeds despite its complexity because what it offers is so good.

  173. Matt November 13, 2013 at 4:29 pm

    I’ve been using git for over a year and it has only provided frustration and suffering, though I can appreciate it’s power. I’ve nevertheless managed to trash my repository several times trying to fix what should be trivial issues. You are right on that git is made for power users not the end user.

    One extreme annoyance for me is that I need to distribute my code over several machines from which I do not intend to do any development. In fact for most use cases, when I want to pull code out of the git repository I want to replace whatever rotten old code I have in the current directory, ie I just need an update to the latest. To do this I must use the extremely hard to remember commands,
    git fetch origin master
    git reset –hard FETCH_HEAD

    The git developers apparently never thought that some people might just want to use git to fetch code. I have found that it is much safer to only develop code for my repository from one golden directory. Otherwise you can get unwanted merges that are a pain in the arse to unwind. In fact it is not that unusual to alter compile flags that are specific to the architecture of a given machine, or to set data directories in source configuration scripts that are also specific to a given machine. I don’t want to pollute the repository with that sort of thing. Yes there are commands that enable this such as the -s ours flags etc., but it is very hard to remember the exact syntax, since, as described it is not consistent.

    Someone really needs to develop a consistent easy user interface overlay for git for common simplified workflows. I also find it annoying that the gui’s that are provided don’t have some of the most important commands. git gui is very poor with regards to fetching and merging but pretty good with regards to adding committing and pushing.

    • arnebab November 15, 2013 at 6:33 am

      Did you try switching to Mercurial? Your usecase would be resolved with `hg pull -u`.
      hg-git allows you to easily access git repositories with Mercurial.

  174. lundril November 18, 2013 at 10:33 am

    First of all thanks for your post. At work we use subversion; while I start to get used to git, I do not think it would be a good idea to introduce it at work exactly because of its complexity; so yes I fully understand why you “hate” git.

    Still I think some of your points are not very valid:
    1. Complex information model
    Hmmm. The way most tutorials are written you are correct. The main reason why I still disagree is, because once you look at the “advanced” stuff it actually gets simpler. Once you understand that git stores three main types of objects (blob, tree, commit) + each object is referenced by a SHA-1 checksum over its content, the information model starts to look a lot simpler.
    After that reading https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html clears up lots of questions.

    2. Crazy command line syntax
    I agree. It really could be better; but then again it would be really easy to make it less crazy if people cared enough.
    What about the project “Easy Git” ?

    3. Crappy documentation
    I agree that the man pages do not make sense to a new user. But that is because you first should understand about git objects, then understand of local / remote repositories, then read “gitglossary” and then at last read the man pages of the commands (at least this was the order which made most sense to me).
    I once gave an introduction to subversion. If you talk to people, which are completely new to version control in general, then even this is hard, even if the concepts in subversion are much simpler and easier to understand. I think that learning something completely new usually means that the terminology will sound like gibberish.

    4. Information model sprawl
    Once you understood about “blob”, “tree”, “commit” it does not seem so complicated anymore…
    The biggest problem seems to decide how to organize branches for a given project. With subversion this seems to be even harder; at least from my experience.

    5. Leaky abstraction
    The example you give here seems to be something which you could not even do in subversion ?
    So the complaint seems to be, that you do something quite complicated and it turns out that doing it requires a set of complicated commands. This seems not very surprising. Maybe what you were trying to do was not complicated ? But then it might help to explain first what you were trying to do, before complaining.

    The “no abstraction” means that you are able to do these complicated things, because these complicated things do not allow for an easy abstraction…

    6. Power for the maintainer, at the expense of the contributor
    In all your examples you seem to assume a model in which everybody has write access to a central repository. At least that would be the “easy” case in subversion.
    How would you setup a maintainer kind of workflow with subversion ?
    I am really interested, because I really have no clue how that would work:
    – Checkout
    – Modify
    Now:
    – Commit ? Hardly; I do not think everybody gets write access to the central repository
    – Commit to some other repository, which was cloned somehow ? Who then integrates my changes into the “master” repository ? A maintainer ??? this poor guy! How do I get updates from the “master” repository ?

    So what would be the easy workflow without expense for the contributer ?

    7. Unsafe version control
    That was an interesting topic, because I am still quite new to git and understood the concern. After googling: What about
    git config receive.denyNonFastForwards true
    on the “master” repository. This seems to avoid most of what you are worried about or am I wrong here ?
    In general all of this assumes that you have write access to the master repository.
    As I said I do not understand how you would have a maintainer like workflow, if everybody has write access.

    8. Burden of VCS maintainance pushed to contributors
    How do you “update/commit/update/commit” without write access ?
    How do you have a maintainer if everybody has write access ?
    I do not seem to understand how you would implement your supposedly simple workflow.
    What happens in the case of “update/commit” … oh crap I broke the build ?
    “undo commit” (not really possible in subversion) ?
    revert change then commit ? What happens with the user users who already “updated” the broken commit ?
    Maybe they fixed it on their local working copy and now get conflicts when they update my “undo commit”…

    The model you describe seems to put a lot of responsibilty on the contributors; they really should not make any mistakes, because it hurts everybody else.

    9. Git history is a bunch of lies
    “Surely the correct solution is a better log output that can filter out these unwanted merges.”
    That sounds like you want a sophisticated AI as a filter. When I look at the logs of our subversion repository at work it is quite hard to tell which log entries might be merged; so no clue how a computer might do that.
    Git history on the central repository (or master repository) is only a lie if you allow it, by allowing non-fast-forward updates.

    10. Simple tasks need so many commands
    This is mostly unfair. If you want to do the same as subversion you would do

    1. modify
    2. git commit -a
    3. git push
    So exactly one more step than in subversion. The git way allows you to do “git status” (ok I did not forget anything), compile … broke the build; oh good I can still fix it, before anyone notices it and gets angry.

    The thing about github only applies if you use github. You compare oranges with apples; a central subversion repository with github…

    Note that after using git for a while, I never use “git commit -a”. It simply happens far too often that I modify several files, but only want to commit few of them. It is much easier to first use “git add”, then “git diff –cached” to see if you really got everything and then use “git commit” to commit exactly that (yes I agree: The syntax could be more obvious). With the subversion command line there simply is no way to do that; you need “svn commit ” and sometimes you might commit too much or not enough.

    Another example: “git stash”. The way I do that with subversion is, to first use “svn diff” to create a patch file, then undo all my changes with “svn revert” and then to reapply the changes later when I am done with whatever I wanted to do. Note that re-applying the patches requires “patch” a non-subersion command as far as I know. So the “simple tasks need so many commands” applies to subversion in this case.

    “As an added bonus, here’s a diagram illustrating the commands a typical developer on a traditional Subversion project needed to know about to get their work done.”

    And where is the maintainer in this picture ?
    That is where the complexity from the github example comes from. So again you compare apples and oranges.

    Summary: I still completely agree that git is a lot more complex than subversion. Yes it really lets you shoot into your food. Still I am not convinced that subversion is so much easier (I just have to remember the svn-property and “how to merge” discussions we had at work).

    • steveko November 18, 2013 at 11:07 am

      >The main reason why I still disagree is, because once you look at the “advanced” stuff it actually gets simpler. Once you understand that git stores three main types of objects (blob, tree, commit) +…

      This is kind of true, which is very weird. You really, really shouldn’t need to know this stuff.

      >2. Crazy command line syntax I agree. It really could be better; but then again it would be really easy to make it less crazy if people cared enough. What about the project “Easy Git” ?

      I don’t think it’s about “caring”, it’s that the syntax is too hard to change now. The attempt to separate “porcelain” and “plumbing” has failed. EasyGit doesn’t go far enough.

      >That was an interesting topic, because I am still quite new to git and understood the concern. After googling: What about git config receive.denyNonFastForwards true on the “master” repository. This seems to avoid most of what you are worried about or am I wrong here ?

      I think if new users need to set some hidden flag on their repositories in order to protect against data loss, my point is confirmed, no?

      >The model you describe seems to put a lot of responsibilty on the contributors; they really should not make any mistakes, because it hurts everybody else.

      I’m not really advocating for “everyone has write access” workflows. I’m just pointing out how complicated the default workflow is for Github. GitFlow probably improves things a lot.

      >Git history on the central repository (or master repository) is only a lie if you allow it, by allowing non-fast-forward updates.

      Interesting idea, thanks.

      >Still I am not convinced that subversion is so much easier (I just have to remember the svn-property and “how to merge” discussions we had at work).

      Yep, Subversion is too limited for modern development.

  175. Pingback: Learning to Code | Quartet

  176. MrKii December 10, 2013 at 10:18 am

    I agree, and I could probably add 10 reasons more to hate git :)

  177. Chemist December 11, 2013 at 5:11 am

    I hate git right now. It is the source of great frustration. :/ Suck it, git!
    These things should be much much easier to do, instead it’s harder than actual programming and such.

  178. Pingback: Learning to Code | Decluttr

  179. Simon December 29, 2013 at 3:32 pm

    Someone probably said that already, but the Information Model is not that complex, given the decentralized nature of Git. Repositories are repositories, whether they are remote or local. Tags are actually tags, much closer to the real life thing than in SVN, and there is no trunk, which was some kind of a fuzzy notion in SVN. Commits are still commits, on SVN same as on Git. I don’t know what treeishes would be. Stash is just like a commit, and you don’t have to use it if you don’t like/understand/feel comfortable with it.

    But I guess all this is just a matter of perspective.

    Apparently, you have been spending a lot of time on Github, and it is the real target of several of your criticisms. The thing is, a/ I don’t know any code hosting system that allow anyone to do something similar with SVN (I’m only talking about the pull request part, of course), making the comparison quite pointless, b/ github is not git. It is one way of using it. Most usage of git I have seen are very similar to what SVN was like before the switch, only more powerful (not going to be to long on that, but the merge tracking alone justifies the switch)

    Last point, regarding rebase, it is not a “lie”. The commits you push to the remote are not modified once they are pushed. No pull is ever made of a different tree, history is not rewritten, you simply apply your work on top of the latest remote version. (If you use rebase after a pull has been made on your repo, that’s a different story, but the SVN admin could do just the same).

    • steveko December 29, 2013 at 4:48 pm

      >Repositories are repositories, whether they are remote or local.

      Remote repositories, local repositories, and local copies of remote repositories (ie, origin/master) all behave differently on the command line.

      > there is no trunk, which was some kind of a fuzzy notion in SVN

      “master” is a pretty fuzzy notion in Git.

      > I don’t know what treeishes would be

      That’s what Google is for.

      > Stash is just like a commit, and you don’t have to use it if you don’t like/understand/feel comfortable with it.

      Except the syntax is all different and a few other peculiarities.

      > Last point, regarding rebase, it is not a “lie”.

      If the sequence of development goes A-B-C-D-E, yet the version history after a rebase goes A-C-E-B-D, I think “lie” is an apt description.

      • Sean Roehnelt December 31, 2013 at 7:14 am

        > > > Last point, regarding rebase, it is not a “lie”. > > If the sequence of development goes A-B-C-D-E, yet the version history after a rebase goes A-C-E-B-D, I think “lie” is an apt description. >

        Agree.

        I think an important default behavior would be for rebase to be the default merge behavior when history lines up correctly; automatically use merge instead if/when history isn’t congruent. In other words, new commits should normally go on top of pulled changes regardless of the timestamps without requiring a different set of commands or prior knowledge if what has changed in the remote repo.

        Another related behavior that would help me understand our current repos would be for git to show history in merge order instead of commit timestamp order by default, or at least provide an easy tool to display history in merge order.

        >

      • Tisza Gergő December 31, 2013 at 8:32 am

        > new commits should normally go on top of pulled changes regardless of the timestamps without requiring a different set of commands or prior knowledge if what has changed in the remote repo.

        New commits go to the top by definition. Of course, by the time you pull, they are old commits. You might be thinking of unpublished vs. published commits – but the software cannot reliably determine which is which. You can set the pull behavior per-branch via the branch..rebase config option.

        > Another related behavior that would help me understand our current repos would be for git to show history in merge order instead of commit timestamp order by default, or at least provide an easy tool to display history in merge order.

        What do you mean by “merge order”? Commits which happened on different branches do not have any obvious ordering. If you want to keep together consecutive commits as much as possible, you might be looking for the –topo-order flag.

  180. homeawesomation January 9, 2014 at 1:27 pm

    At first I was going to hate, but then after getting through your post I think it’s pretty well written. I’m not expert so I can’t debate. My only confusion is when you compare SVN process to GIT why you also talk about github. I don’t use github professionally so it clouds the point a bit. I do use github for my public/personal code.

    • steveko January 13, 2014 at 8:26 am

      I wrote the article about my own personal experiences with Git which all involved (and still do) Github. I almost never come across projects that use Git but don’t use Github in either my work or sideprojects.

      • homeawesomation January 14, 2014 at 11:00 am

        fair enough. I mean I use github for my public projects but I also don’t do much collab on there. I use just git on the commandline for my private projects and for work we use gitlab which is just an alternative to github. But without me knowing better I wouldn’t think you’d need any gui (gitui, github, gitlab etc) to manage repositories. So I’m just saying if you take that out of the equation I wonder how its diagram compares to svn in complexity. I figured github was just for managing repo’s and users in a GUI friendly way, and to merge forks and stuff like that, but not necessary.

  181. yura January 10, 2014 at 5:11 am

    Perfect article which reminded me of my 9-month experience with Git after 5 years of experience with SVN. I definitely agree that user interface of Git totally sucks comparing to one of SVN. Git beats SVN in lots of things just because it is DISTRIBUTED version control system (VCS), while SVN is centralized one (ironically 90% of Git supporters doesn’t know the difference :)).

    So, I’ll add to superb comparison of “Granny on the freeway”:
    Git is like Formula-1 sports car – it accellerates very fast, it brakes very good. In hands of a professional it’s really awesome tool. But for beginner to intermediate user it’s total overkill and out there there are 95% of such users.

    SVN is like normal city car – it has normal engine, normal brakes and normal suspension and hence fits 95% of use cases. Any professional on this car will easily beat beginner on Formula-1 simply because he/she knows that in most cases power is not what matters.

    So, 90% of arguments for Git over SVN looked like advocating Formula-1 car in small city over normal city car just because it’s so damn fast :)

  182. Pingback: My Journey Towards Learning Git | Robert Cina Online

  183. Kevin January 15, 2014 at 6:55 am

    Great article. I must say it has been quite “challenging” being forced to switch to Git from SVN. It is a completely different mindset which I have had trouble switching to after 12 years of Clearcase, then SVN. I got very use to using SVN through Eclipse and using Git through Eclipse seems to be much more difficult, at least at the very beginning.

  184. Glenn January 29, 2014 at 5:51 am

    The bottom line for me is simply that Git is in my way. It consumes more time $@#&ing with it than it’s worth. Source control should be a tool to enable my coworkers and I to collaborate effectively while focusing on the core work of programming. As such, I need them to have a tool that’s simple and bulletproof. Git is anything but.

    • Raul Miller February 4, 2014 at 1:03 am

      Glenn, I totally approve of your approach. However, I must also admit it is not for me.

      See… from my point of view what you are telling me is that you (a) do not understand Git, and (b) are happy with the alternative you are using. So you are not motivated to change. That might change in the future, but that future has not arrived, yet.

      That said, if we were working together? I would bet that I could have you up and productive with Git within an hour (probably half an hour, but let’s allow some time for unanticipated problems…).

      Something similar could probably be said of other tools (like Hg). Proficient technical people learn to take advantage of their tools, whatever they are, and to focus on delivering what some people ask them to deliver. [Management, of course, has a slightly different job.]

      • Drak February 4, 2014 at 5:13 am

        That is then an hour you spend, getting someone else up to speed. And if stuff I read on the internet is of any value, he will keep stumbling regularly and ask you again.

        With hg you could say that I have that position in the team I work in. We have 3 people not really familiar with version tracking. And in 2 years, I got about 6 questions after the initial setup. Not per month and not per year, but overall. How’s your mileage with git?

      • Raul Miller February 4, 2014 at 12:04 pm

        Maybe, yes. But often enough that hour spent saves me a good 10-30 hours over the course of a year. Also, most of the younger programmers I have worked with already know how to use git. So it’s really not that big of an issue for me.

        Also, a lot of problems with git are really github issues, and most of those can be resolved by cloning a fresh repository and working with it. Most of the remainder can be resolved by making sure that they are using a relatively recent version of git.

  185. lundril February 10, 2014 at 11:17 am

    Hi again,

    I still would really like to know how to setup Subversion in such a way, that you get a maintainer workflow. You write:
    ——- snip ————
    8. Burden of VCS maintainance pushed to contributors
    In the traditional open source project, only one person had to deal with the complexities of branches and merges: the maintainer

    —— snip ———-
    I work with Subversion each day, but I still have no clue how you would setup a maintainer if you have a central Subversion repository.
    How would you do that ?
    I am really interested, because I certainly do not know.

  186. Karl Fogel February 10, 2014 at 11:47 am

    Hmm. lundril, if you seriously need to know how to do maintainer branching patterns with Subversion, ping me at my consulting address http://opentechstrategies.com/. (This is not meant as a statement one way or the other in the git-vs-subversion debate, by the way. Git has great branching and merging, and I use it all the time. But I couldn’t tell if your question was just part of the conversation, or was an actual attempt to find help for your workplace. If the latter, I’m happy to take a look, though it sounds like you understand Subversion pretty well and basically are just missing what you’d get from Git.)

  187. Pingback: Version control Part 1: Local repository | Tom Wallis

  188. Pingback: The Git Reference | Tamasdan.com

  189. cjp39 February 15, 2014 at 1:35 am

    > “git pull” is exactly equivalent to “git fetch” followed by “git merge”.

    Actually, “git pull” does more than that; it also spots upstream squashes. See http://gitolite.com/git-pull–rebase.html

  190. Pingback: Git: what they didn’t tell you | Steve Bennett blogs

  191. gbutiri March 11, 2014 at 5:38 am

    Yikes. Interesting post. From my experience it’s like someone trying to re-invent the wheel. First time I used Git, I had conflicts on my second commit. It’s not as much about the tool you use, but more about how you use the tool at hand. In repository’s case, for the projects that I’ve worked on, SVN is just fine. No need to complicate things.

  192. lsmgeb89 April 13, 2014 at 12:09 pm

    What flowchart software let you make the beautiful charts in the article? Thx!

  193. waxbear April 22, 2014 at 4:47 am

    You’ve summed up my feelings with more educated examples. I gave up on subversion in favor of git, and I think it has the features that I want. But, man, it is so difficult figuring out the way to use that functionality.

    It was extremely easy getting the repository and first import setup, but after that, the developers decided to let the users suck it after that.

  194. paj006 May 1, 2014 at 5:39 am

    Amen brother! I am boggled by how the industry is turning to favor Git and not Subversion.

  195. Marcus Aurelius May 14, 2014 at 5:28 am

    > To reset one file in your working directory to its committed state:
    > git checkout file.txt

    It seems that the correct command is

    git checkout HEAD file.txt
    or
    git checkout HEAD — file.txt

    I was bitten by this. When you pass paths or –patch, git checkout defaults to the index (staging area), so if you want to revert to its committed state you must pass HEAD explicitely as a parameter.

    Of course this only proves that git does things very differently when file names are present on the command line…

    However, after learning git for about one or two months, it does not look as horrendous as people say. It’s certainly possible to use it despite the little annoyances, and it usually prints useful messages on the screen while it operates.

    Currently I’m a little annoyed with git add -A, git commit -a, git stash -u…
    If only we had git add -A, git commit -A, and git stash -A plus an easier to use git reset… I think it should be separated in two commands: one to undo git add and other to move HEAD.

  196. James Dean May 22, 2014 at 9:18 pm

    Just wanted to vent:
    Git again fucked up my local changes when I did a pull.
    Git is so stupid compared to TFS wheneven I try to pull changes from teh server it can’t just download the unchanged files and leave the changed ones alone. I had to stash my local changes, then pull server changes, then un-stash my local changes and retarded git couldn’t unstash my local changes (dunno why, it didn’t say, but I guess it’s because git is the most retarded source control out there).
    .
    To the morons who wrote it – you should learn from Microsoft and TFS – TFS is the best!

    • Tomas May 23, 2014 at 3:27 pm

      In my experience whenever you have problem with git, it is at chairkeyboard relation. I am absolutely sure that you don’t know what are you talking about, so unless you have any argument to confirm that you did everything right and git “fucked it”, please go use something more close to your intelectual capacity. Thank you very much!

      • steveko May 23, 2014 at 4:00 pm

        If a product is hard to use, is that a “chairkeyboard relation”, or a problem with the product?

      • sfkleach May 23, 2014 at 5:08 pm

        You have missed the point of this article, which is about the poor “UI” design of git that leads to these muddles. You may well wear your underpants over your spangly tights but if that’s really what it takes to use git reliably then most of us would say it’s not fit for purpose – because most of us don’t believe version control is that difficult. Simply insulting people doesn’t make git a better tool and, given that James seems to be happy with TFS, should give pause for thought.

      • Raul Miller May 23, 2014 at 5:17 pm

        While technically correct, it seems like there ought to be a better way of addressing people with this kind of problem. Everyone starts out ignorant of the technical details.

        In my experience, usually the best way to approach this involves asking for:
        (a) What specifically did you do (exact steps)
        (b) What did you expect to happen
        (c) What did you see instead (exact error messages).

        People will usually range from too impatient to deal to those that are interested and capable. Many times when a person follows these steps they will figure out how to make it work. Sometimes they will have trouble finding relevant documentation – that can be a good opportunity to point them at the documentation you find relevant (and hopefully they see it the same way). Sometimes they will have found an actual bug (like if the code crashes or whatever), and if that’s the case they need to be treated with respect.

        Unfortunately, it’s all too easy to think you’ve found a flaw when you have not. But by asking for a small amount of effort from people you can weed out most of those who aren’t worth your time.

      • Max Weber June 5, 2014 at 9:06 pm

        There might be a set of 9+ commands to make git reliable; but, there’s a single click in SVN. It might be an egit problem and it might be a stash app problem; but its not a chairkeyboard problem. For sure, what works every time with one click in SVN (and CVS before it etc) had a high probability of failing with git. – off to manually resolve even more files git failed to commit.

    • sfkleach May 23, 2014 at 5:00 pm

      I use both git and TFS every working day and I have managed to get myself in bad muddles with both. However, in normal working practice I find git enormously more comfortable and secure feeling. The ability to stay under version control when I am working offline is essential, similarly private branches, and the freedom to manage my branches without managing a horrendous pile of nested folders. If you have to use git, may I suggest getting holding of SmartGitHg (or Atlassian Sourcetree), which are excellent tools and make git safer and more manageable.

    • cjp39 May 23, 2014 at 7:07 pm

      James, I suggest you always `git commit`, not `git stash`, before pulling, merging, rebasing, or whatever. That (a) forces git to merge the changes in as part of `git pull`, which makes `git rebase –abort` available; (b) gives you an exact commit to return to if you find things get horribly borked, so you know your changes are safe.

      Your specific feature suggestion, downloading unchanged files and leaving the changed ones alone, is not workable, as it would silently drop upstream code on the floor. That could well lead to the project being uncompilable! It would also be a nightmare when you came to git push again, as you’d be reverting parts of other people’s work.

  197. joni May 30, 2014 at 12:10 pm

    I do hate also this stuff, since it doesnt provide download resuming like cvs does !

  198. Pingback: The Guy Who Made Your Android Phone Possible Responds To Nasty Tweets About Him | Construction

  199. Pingback: The Guy Who Made Your Android Phone Possible Responds To Nasty Tweets About Him | Digital Wealth

  200. Max Weber June 3, 2014 at 6:02 am

    Great post. Most use git in a source control pattern where changes are branches and must be approved. This is great for two scenarios: 1. mature code base with high risk aversion. 2. Junior programming teams where most do not comprehend the whole product. The main problem with this approach is the merge conflicts. Way, way, way, way, way worse than source control usage patterns common with CVS/SVN. In those, you merge at least daily so must keep the entire product in sync. Another problem with the way git is used is many (all of both medium-sized projects I’ve worked) projects allow specific persons an advantaged seat where they can merge as is convenient to them, but everyone else has to manually resolve the junk they did. Maybe its human nature; but in the typical SVN pattern, the first merge wins; so, good developers constantly keep their code in sync with the product. In git, it quickly goes to …

    • Max Weber June 3, 2014 at 6:09 am

      BTW, ever notice how git takes like 5 commands to do something which is two right-clicks in svn. No matter what you think of how people use git/svn, the fact of usability is there. What is even more strange is its perfectly possible to make lots of branches and do code reviews on those with svn – looks more like the primary goal for git users was to be able to stash/local commit. That is the only differentiating feature as far as capabilities which I have observed. Outside of that, everything you can do with svn you can do with git, and vice versa. Svn is just 10x easier and less error prone.

      • Max Weber June 3, 2014 at 6:14 am

        Do have to give credit to egit, Eclipse plugin for git. I used it before enduring lots of gaps; but, on this project its quite decent. I almost never have to shell out. (had to for merge to do a “git commit -a” to make git take the changes.) Its a great plugin and makes using git/stash tolerable.

      • arnebab June 4, 2014 at 4:12 am

        The local commits are one of the major reasons why I prefer Mercurial over SVN. Also branching has lower overhead. And you can commit before you merge, so you first secure the work you did, then you integrate it.

  201. Max Weber June 3, 2014 at 6:20 am

    OK, read through some of the posts. FYI, svn merge intra-file is very good. Git sucked. Perforce sucks. MKS probably sucks worse. ClearCase – been years since I used it but it sucked in several places. Used several others. So far, SVN is the cleanest. Of course, have someone with a brain deciding the branch and release strategy is far more important. I actually think git merge might have improved some since 6 months ago when I used it alot. Not sure but latest project I’m seeing less mess to manually clean up after git.

    If you want a maintainer then just have all commits reviewed before being accepted into the head/trunk. No matter what source control, you can branch to your heart’s content. Just like people do with git.

  202. Max Weber June 5, 2014 at 9:02 pm

    Some things you should NOT do with GIT which are common with SVN.
    #1. commit+pull on a whole tree. While this works sometimes, when we are on this project with different timezones then silently many files do not get picked up. Sure, you might should notice it in the list; but with SVN this just always works. In contrast, with GIT you had better commit -m “” exact-path-to-file for every file. Don’t just “commit” at top of node with egit nor even try git -am.
    #2. Don’t do lots of pulls. If you come from a distributed team development background, then you are used to very, very often pulling the latest. This is BAD with GIT. Apparently the git tools are like MKS and determine diff based on timestamp. laughable if not so true. I never had this problem with SVN and think they might do binary compare. You’ll end up needing BeyondCompare or another binary folder tree comparison tool if you use GIT.
    Long story short, in GIT you checkout/pull ONCE, make all your changes. Then try to commit+push everything at which time you do lots of merge conflicts resolution. With GIT you cannot sync frequently or things stop working. (assuming you are branched and have a fairly complex branching relationship and have lots of people changing lots of files).

    • sfkleach June 5, 2014 at 9:26 pm

      If anyone is reading this, please don’t follow this advice. Heuristic: follow the practices of people who have good experiences, not those who have bad experiences. Frequently pulling the latest is only correct in one particular workflow, where there is a single, central master copy. Also note that in git you should be fetching not pulling.

      • arnebab June 6, 2014 at 3:18 am

        In Mercurial you normally *merge* frequently and explicitly. It works pretty well. A canonical upstream is not needed for that, just sane people who do not rewrite history.

        I agree on fetching: git pull is essentially a fetch+merge and as such quite dangerous if you do not commit beforehand.

      • Max Weber June 18, 2014 at 1:04 am

        In summary, with GIT you do LOTS of manual merges for any normal-sized project where you have lots of people working on the same files. So, to use GIT like is done in Linux, you need a MAINTAINER. Only he or she really changes the files he or she owns. Changes are suggestions to him or her. That’s GIT in a nutshell. Worth noting that the two projects where I used it quickly devolved into one or more “Leads” who would delay reviewing the changes from the rest of the team while he/she refactored the underlying code base, and then expect the rest of the team to sort it all out manually. That is common and repeatedly occurs on GIT projects. It never occurs on SVN projects because, with SVN, if you want to refactor the hell out of the source base then you do it all one late night after clearing that with everyone else or you do it piecemeal after clearing it all with everyone else. Not saying GIT couldn’t be used equanimously; but, definitely tends towards creating constant merge messes which must be manually cleaned up. Bottom line: GIT is a REAL TIME WASTER. You can add at least 20% additional time to the development effort if you choose GIT instead of SVN. At least. Honestly, I think its more like 40% because with GIT you need tons of meetings to figure out what in the heck is going on whereas with SVN the small changes are palatable and, therefore, somewhat self documenting. With SVN, if you make a change affecting others then they see it soon and can understand it better. With GIT, you wait around until a Code Review event, and, by the time that occurs, then the entire code has moved on and manual merge is almost guaranteed. (well, 20% of the time at least).

      • Raul Miller June 18, 2014 at 9:27 am

        Ok, let’s blame the tools for our own failures. Because if we were responsible for getting something useful done we’d be doing that instead.

        Seriously, if you like SVN that’s great. if you like Mercurial, that’s great. If you like Git, that’s great. But maybe also take a look at what you are accomplishing and how you deal with other people, also.

        Put differently: in a few cases changing the tool will actually help. But if you are frustrated with wasted time then you need to seriously think about doing more arguing about what tool other people should use.

      • arnebab June 19, 2014 at 4:26 am

        @Raul Miller: Keep in mind that having to do more than changing the tool does not mean that the tool is not partially responsible for bad habits which evolved.

        A good tool makes it easier to do the right thing than to do the wrong thing. And while the the obligatory branch-naming of git is pretty good at making people use branches, it is pretty bad at keeping a code-base in a consistent shape (I‘ve seen quite a few year-old branches slowly rotting away because no one merges them)..

      • Raul Miller June 19, 2014 at 5:49 am

        Sturgeon’s law is probably relevant here.

  203. Raul Miller June 18, 2014 at 9:28 am

    correction: “about doing more than arguing about what tool other people should use” …

  204. Pingback: Git | Rauhe Sitten

  205. Roman Newaza June 23, 2014 at 2:41 am

    Git is cool! If you don’t like it, just use your outdated svn or whatever, maybe cvs))

    • Max Weber June 24, 2014 at 10:49 pm

      That was what I found too. “Git is cool”. Just use it. “Its cool”. Pretty much sums it up. Two features make it a choice for special cases; but, those are really edge conditions these days where everyone has Internet every time and where setting up a branch in your favorite SCS is easy everywhere now.

      • Max Weber June 24, 2014 at 10:50 pm

        In contrast, as chronicled in this page, GIT will add 10% to 40% project cost versus using SVN. But, I’m sure most GIT fans don’t want to talk about reality.

  206. Max Weber June 24, 2014 at 2:24 am

    Just did a git merge on two branches. Stash (git) said each was in conflict. In one, in a class a _different_ constant had been defined by each. Git could not auto-merge that! In another, the imports changed. Git could not automerge that! Would be nice if git know something about Java; but at least it should be able to automerge non-conflicting changes. IDK what tool git uses for merge. I know I worked at one huge co that used Perforce and its merge was bad. SVN has been good IME. Why use a tool if you git to do it all manually!!! “Git it”

    • Raul Miller June 24, 2014 at 2:49 pm

      Why even write code if you do it all manually? All that finger motion – it’s just so… exhausting? All that thinking! How horrible. Maybe someone else should do it?

      • Max Weber June 24, 2014 at 10:45 pm

        Exactly! Last thing you need is a manual SCS! One more flaw of GIT while we are talking about GIT warts…. its “local repos” are just copies of stuff in your working folder. I know, many SCS have this problem. Heck, the project.pj files from MKS break Android compiles; but, since GIT is THE LATEST AND GREATEST, couldn’t they do this right?

        BTW, GIT’s salient feature is support for code reviews. Each change is a branch. This allows one to hire unskilled high school, offshore, and other unskilled people and give them one single task. Experience will teach you that the time to code review and teach them to program is greater than the time to just hire good people. But GIT would be great for a college, and that’s effectively what most large corps are when it comes to trying to use unskilled labor to do skilled work.

    • Max Weber July 10, 2014 at 11:36 pm

      A few more things which don’t work in git merge and cause manual work:
      1. comments. (really, not kidding, you’ll have to manually merge if someone adds a comment (// stuff) to a file in another branch
      2. net adds. Yep, when you follow the steps below as listed by stash (git site) then you’ll find the net added file is not pulled. Ridiculous bug in git (or else stash’s directions. And if a git dedicated site can’t even figure out how to make git work…).
      3. multiple other problems. Its tedious to list because clearly the author of git did NOT bother to learn from the others who have written SCS in the past. Git is absolutely a way to waste another 10 to 30 minutes for each bug/feature point. Sometimes can be even more time.
      (The reason I’m chronicling here is this pattern of people with 0-5 years experience jumping on fad frameworks is a waste of human productivity. For us to take the next great leap forward as a species, we must learn to “Build on the Work of Others”. Not continually doom ourselves to make the same mistakes. At the very least, decisions need to be made with a list of Pros and Cons; not based on what someone hears at Google IO or whatever latest conference.)
      Stash steps (works sometimes :-) (mostly from memory)
      git fetch origin ORIGIN_BRANCH_LABEL
      git checkout FP_BRANCH
      git merge FETCH_HEAD
      (stash omits but here you make changes and must do “git add fpath” for each file. woohoo, so user freindly, NOT!)
      git commit
      git push origin HEAD
      (now, sometimes you’ll have various problems since this won’t work. MOST git users end up deleting everything, doing a new clone, and redoing there changes. Watch them. This is the type of sgit people are doing with git. But, you can get things working with some git fetch and/or git pull – at least in the case found.)

      • Tisza Gergő July 11, 2014 at 4:43 pm

        Huh. This thread has always been a rich source of bullshit, but recently it has crossed straight into tinfoil-hat-land. I look forward to the first report of how someone got rashes from using git.

      • sfkleach July 12, 2014 at 4:58 am

        Indeed, it’s all a bit over-excited.

      • arnebab July 14, 2014 at 5:08 am

        @tisza: You can’t expect the positive sides of git adoption to show up in a thread which is the first google hit for “I hate git”.

        On the other hand, git adoption is strong enough that the dark sides of having a mostly implementation motivated user interface with quite a few awkward workflows show up more and more. And these are very likely to show up here.

        So you should not be so fast to insult those who made negative experiences with git. I also contribute to a project where git costs quite some time again and again because the necessary actions for what we need are needlessly complicated and require googling everytime. This wastes quite a few resources (several hours per year for a team of ~6 people).

        Was git an overall win over SVN? I think yes. We are no longer dependent on a single server. Due to having a transparent bridge to Mercurial we can also reintegrate anonymous development into our main repositories with ease. That’s a big conceptual win. That we do most things over github is a big conceptual drawback, though: We always have to ensure that we regularly pull all history from all clones, so we don’t lose development when a user decides to delete the github account.

      • sfkleach July 14, 2014 at 3:50 pm

        I don’t think @tisza was ‘so quick to insult’. He was responding to an incoherent post that lowered the tone of discussion of what has been, by and large, a well-considered discussion. I am genuinely interested in the problems people have with git, as I am introducing it in my workplace. So I am very grateful when people take the time to explain the issues that they have had with git.

        However in your post you allude to “the necessary actions for what we need are needlessly complicated and require googling everytime”. That doesn’t help me understand the issues that you’ve encountered or how they might apply to my own workplace.

        You continue tantalisingly: “We always have to ensure that we regularly pull all history from all clones, so we don’t lose development when a user decides to delete the github account.” This is about github rather than git, I suppose, but how is it possible for users to delete github accounts?! That sounds like your project is set up wrongly but I would be interested to know more.

      • Tisza Gergő July 14, 2014 at 5:33 pm

        @sfkleach, GitHub’s authorization control is extremely poor. While users are not able to delete repositories if the configuration is sane, there is no way to limit force push access; if someone has it for some branches (which is usually needed when people work together, e.g. to rebase a feature branch shared between two coworkers), they have it for everything, and if they accidentally rebase master, it is not even logged, nor is there any way to restore the lost commits, unless someone has them locally. It is quite easy to lose work that way.

        Not really a problem with git, of course, and supposedly GitHub Enterprise has more granular access control, so leaving this out of GitHub was probably some sort of business decision.

      • sfkleach July 14, 2014 at 5:57 pm

        It’s a fair comment that git doesn’t build in authorisation and arguably a weakness. But I would be inclined to say this an issue with GitHub rather than git (and the reasonably well-know workaround for GitHub is to use forks). I haven’t personally configured gitolite but it seems to include branch permissions as a key feature.

        Your point about rebase being a good way to screw up is valid regardless of whether it’s one person or several people. And there are some very good ways to get lost in git. I recently got in a muddle doing a demo by doing a ‘revert’ rather than ‘reset’ – which was a classic terminology blunder. I used the word ‘revert’ while speaking and the rest was … unimpressive. It took me a while to untangle myself.

      • Tisza Gergő July 14, 2014 at 5:26 pm

        @arnebab, this thread started with some reasonable (if overplayed) usability concerns, then turned into “I did this stupid thing and git didn’t stop me!” (it is of course a valid philosophical stance to prefer tools which have a dumbed-down instruction set and do not allow anything nonstandard because there is no way to tell whether it is stupid, but if you nevertheless choose a tool with a completely opposite philosophy, no sense in blaming anything but yourself), and finally descended into conspiracy theory realm. Git not being able to commit files which have been edited from a different time zone, or merge back a branch if a comment was added to the same file on master, SVN being better at merging renames, etc… Had Max not been the only one commenting here lately, I would have probably assumed that he is mocking the blog author by making ridiculously over the top claims.

      • Tisza Gergő July 16, 2014 at 5:19 pm

        @sfkleach: whether to include the kitchen sink or concentrate on version control and let you deal with other tasks using tools specialized for those is again a philosophical issue (personally I would prefer the latter). gitosis, gitolite, gitorious etc are easy to set up if you need access control.

        Rebase in git is quite safe: you can use the reflog to restore the old state if you mess up. The problem with GitHub is that it doesn’t expose the reflog but makes it easy to mess up (and hard to even just verify whether you messed up). But that’s a business/legal decision, as I said, not a technical one.

        (git reset, on the other hand, is a major usability blunder.)

  207. Max Weber June 28, 2014 at 4:55 am

    One more. If you move a file to another package then it will show in git history but egit compare shows them as two totally separate files. Not sure if you blame the poor, out-dated compare support on egit or on git itself.

    • maxweber May 5, 2016 at 1:20 am

      I’m pretty sure this is a git bug. Same sort of crap happens with Android Studio. Rename stuff loses history. That’s crap which used to be in other SCS’s like 15-20 years ago. Hope AS/git get fixed.

  208. Max Weber July 15, 2014 at 12:25 am

    Yet another! egit says “failed to push due to funny remote ref”.
    Well, that’s odd since the remote ref listed as an OLD branch and NOT the one just checkout’ed.
    Well, its not even an egit bug, its git itself (using the stuff downloaded from github.com for Windows)
    Here’s the command line example. Git, “Not only user-hostile, but also buggy”.
    136 git checkout EPIC_BLAHBLAH
    137 git pull
    138 clear
    139 git status
    140 git push
    141 git status
    142 git push origin EPIC_BLAHBLAH
    Ok, so, someone will say “you should have have done a “git pull”. Why not? Details:

    $ git status
    On branch EPIC_BLAHBLAH
    Your branch is ahead of ‘origin/EPIC_BLAHBLAH’ by 1 commit.
    (use “git push” to publish your local commits)

    $ git push
    ! [rejected] HEAD -> TAG-bugnumber (non-fast-forward)
    error: failed to push some refs to ‘https://accutname@stash.r.company.com/scm/stuffer-android.git’

    $ git status
    On branch EPIC_BLAHBLAH
    Your branch is ahead of ‘origin/EPIC_BLAHBLAH’ by 1 commit.
    (use “git push” to publish your local commits)

    EPIC_BLAHBLAH

    So, YES, you can MAKE Git work. But, WHY? Why not just use svn and save yourself headache after headache after headache?

    • Max Weber July 15, 2014 at 12:28 am

      Sorry, comment was filtered due to gt/lt.
      $ git push
      ! [rejected] HEAD -> TAG-bugnumber (non-fast-forward)
      error: failed to push some refs to ‘https://accutname@stash.r.company.com/scm/stuffer-android.git’

      — comment: why is Git pushing to another branch? I checked out from the one I want. It even told me “(use “git push” to publish your local commits)”? Someone will say “You should not ‘git pull’.” Why not?

      • Max Weber July 15, 2014 at 12:29 am

        TAG-bugnumber is an old branch. The same steps used worked for a month or so until last week. The only thing I know changed is a bunch of remote branches are being deleted as part of cleanup (more make-work you get to do if you use Git).

    • rademi July 15, 2014 at 2:05 am

      You haven’t really given enough information here to isolate the problem. But, at a guess, you are thinking that “push” pushes a single branch (the current one) but have not configured push.default=simple and are using a version of git earlier than 2.0.

      By default, git push tries to push everything in all branches up to the remote repository. But rather than trying to explain how many developers use git, I’d recommend just setting push.default (globally). This is especially important for “corporate use” where a number of people are pushing to some repository which is being maintained by an ops person or some external company, instead of a developer.

      Note that this also means being willing to have someone spend 10 minutes with each developer if they are using a version of git older than 2.0, to make sure they have a reasonable push.default (and/or have read the relevant git.config documentation).

  209. Joey July 15, 2014 at 10:58 am

    I am a user of both GIT and SVN. I have also implemented a few content and data versioning systems myself (although quite basic systems). This is a wonderful critique and parallels my experience with GIT/SVN perfectly. You have missed the most important negative aspect of git however which is its “promoters” or fundamentalists. Those who believe that git is the only viable choice for a VCS. These are people who push git unconditionally over SVN with total disregard towards that facts of a given situation and without consideration of the fact that GIT and SVN follow different paradigms.

    GIT is great for what it was designed for, a massive project with thousands upon thousands of random contributors. Of course it makes sense to be distributed here, provide more control (communication and coordination is impossible one such scales) and so on. The masses of incomplete work alone would pose a severe problem. For me this is counter productive because I need to see what people are actually doing and steer them down the right path where necessary and that will lead into a point later.

    GIT is very powerful indeed and therein lies the problem. It is too powerful. I receive little benefit from this in commercial work and it only becomes a burden. Developers losing hours tangled in GIT is a common phenomena and it has even happened to be a few times when attempting something that should be simple. These are not always stupid people but people who just want to program and not spend an hour battling with GIT. In SVN I have never seen this happen even after thousands of commits.

    GIT is a risk as it lets developers do things that frankly, they really never need to be doing. Where the tables are turned, it is simpler for me to establish constraints when using SVN by establishing procedures for developers and SVN wins here because there are simple, easy to understand things such as “don’t touch the release branch” that anyone can understand. Restricting with permissions is not even necessary. As a mentioned before on committing partial work, yes, you can commit partial work with GIT but I have no need for developers to not commit partially complete work at then end of the day or when they want to include others in their efforts. Some of weaknesses SVN has over GIT can be compensated for by power users with a few basic helper scripts. If I need a backup, this is not a problem, I can’t stress how easy it is to backup SVN especially in a corporate environment where we already have backup solutions in place for everything else anyway. I find it quite bizarre how often people make this argument for git. You can’t seriously propose this in place of a proper backup solution rather than a bi-product. SVN is not perfect but it has not given me any significant problems.

    Many of the problems that it “solves” are better simply avoided or not relevant in my situation. This isn’t the situation for everyone. There are situations where git makes sense but the point is, it does not make sense in every situation.

    This is really an issue of scale that drives me up the wall with some people (young and old). I am very tired of hearing hotwords such as “workflows”, “continuous integration”, etc from people with little real experience or rather theoretical understanding rather than practical understanding. I have real problems and none of these solutions help. The worst of it is receiving these proposals or insistent imperatives that I must use GIT when I have no problems at all. These people are becoming the problem themselves. They have ruined GIT for me. I now block it out, i simply do not want to hear about it from others. The truth is that GIT can’t always pay for its self. It’s not a guaranteed investment.

    > Git is cool! If you don’t like it, just use your outdated svn or whatever, maybe cvs))

    I’m sorry, it’s not that I don’t like it, it’s that I don’t need it.

  210. Francois Joubert July 18, 2014 at 10:05 pm

    Check out https://github.com/landobyte/glo Its a git addon we built and it works well.

  211. norman July 20, 2014 at 2:45 pm

    i’m totally agree with this writing.
    still looking simple SVN/GIT.
    just need clean easy interface for managing my PHP code.
    any suggestions app?

    cheers

  212. Y Tế Sức Khỏe July 25, 2014 at 4:44 pm

    It look easy than SVN. I think we need adaptation it.

  213. johanakz July 30, 2014 at 10:19 pm

    I feel your pain! Didn’t know someone felt the same about some of those issues. I’m working with git and svn together and it took a while until I found a comfortable workflow.

  214. Alex Quintana August 3, 2014 at 5:57 pm


    Make some changes
    git add [not to be confused with svn add]
    git commit
    git push
    Your changes are still only halfway there. Now login to Github, find your commit, and issue a “pull request” so that someone downstream can merge it.

    Granted, I have never used Github, I use Beanstalk, but this is my process:

    1. Make some changes
    2. stage all changes (i use git tower but you can easily do git add .)
    3. git commit
    4. git push origin master

    My changes are ALL the way there. no need to do anything else. This is pretty much constant. Maybe Github is different.

    • steveko August 3, 2014 at 9:13 pm

      By “halfway there” I mean, I they’re still only in your personal repo. You generally have to then make a pull request.

      I should point out that since writing this blog post, Github’s workflow for making pull requests is smoother – you don’t need to “find your commit” anymore.

  215. steveko August 3, 2014 at 11:58 pm

    >Github does not allow you to push changes into random people’s repositories without their consent. Shocking!

    Yep, sarcasm’s easy. Think harder though, and you’ll realise there are lots of alternative workflows that the designers of Git and Github could have used instead. The concept of proposing changes to something managed by someone else is not unique to source code – but the pull request model is a particularly clunky solution.

    • Tisza Gergő August 4, 2014 at 6:33 am

      Handwaving about how everything could be done much better in some unspecified way (without even trying to understand the trade-offs involved) is even easier. Creating pull requests directly would be theoretically possible, certainly (gerrit works like that, for example), but – apart from being complicated to implement in pure git – leaves you with authorization problems. (If project A makes a pull request to project B, and project B requests improvements, then everyone who has the right to push changes to project A can do them. If you would create a pull request directly, it would be associated with your user, and there would be no way for others to collaborate.)

  216. steveko August 4, 2014 at 8:49 am

    Ok, so first “implementation in pure git” is not a requirement, because I’m criticising Git itself, and its pull request model.

    Second, you speak of pull requests between *projects*, but one of my gripes is that Git and Github treat individual contributors to a single project as if they were each running their own project. Sometimes that’s appropriate, but it also creates a lot of bureaucratic overhead.

    • Raul Miller August 4, 2014 at 10:03 am

      I share your dismay with bureaucratic flaws.

      Still, the woes of bureaucracy are not constrained to git.

      In fact, I prefer to think of the issue you are describing – this “clunkiness” – as being an inherent property of bureaucracy. And, yes, git “reveals” this issue, and github – with its billing model and authentication issues – makes this issue even more obvious.

      Or: the model you are implicitly advocating – where one person gets full control on checkout but no one has needs to review changes – has its own headaches. And when they arise, they are not pretty.

      People aren’t perfect.

      Unfortunately.

      • steveko August 4, 2014 at 11:10 am

        >the model you are implicitly advocating – where one person gets full control on checkout but no one has needs to review changes

        There were other options available, say, commits automatically become some kind of personal branch in the main project repo, and the maintainer can pull from them when ready.

        I’m not really implicitly advocating any particular solution.

    • Tisza Gergő August 4, 2014 at 3:55 pm

      > Ok, so first “implementation in pure git” is not a requirement, because I’m criticising Git itself, and
      > its pull request model.

      Git actually does not have a pull request model; pull requests are an abstraction layer built on top of git by GitHub to manage authorization for pushes. (Git itself does not concern itself with authorization at all, just provides hooks so another tool can deal with it.) GitHub chose an implementation which is completely simple: you use the normal git commands for remote repos, plus an external step for creating the pull request. (Again compare with gerrit, where you have to push to a weird pseudo-branch to create the local equivalent of a PR.)

      But certainly criticism is a lot easier when there are no requirements.

      > Second, you speak of pull requests between *projects*, but one of my gripes is that Git and
      > Github treat individual contributors to a single project as if they were each running their own
      > project. Sometimes that’s appropriate, but it also creates a lot of bureaucratic overhead.

      That is completely untrue. A GitHub project can have multiple contributors who push to that project directly. You can use pull requests within different branches of the same project for code review (or just have everyone push directly to master, and not do code review at all, although sane projects tend to avoid that option). This is not exactly top secret information either; it’s right there at the beginning of the GitHub help page on pull requests (they call it the shared repository model).

      • steveko August 4, 2014 at 4:54 pm

        Right, Github offers a choice between:
        1) multiple trusted people can commit directly to the same repository, and potentially seriously break things (a single `git push –force` can wreak serious havoc)
        2) everyone has to create a separate branch for every small chunk of development, rebase it to master, push to github, create a pull request, then rewind.

        Github does the best it can to create usable workflows over the top of Git, but the underlying interface it works with is so ugly.

      • Tisza Gergő August 4, 2014 at 6:18 pm

        None of what you describe has anything to do with git’s interface whatsoever. GitHub in fact supports access levels so only certain people can force push to certain branches, they just made a business decision to restrict it to their enterprise product (as I noted a few comments earlier). And it is trivial to get the same restrictions in plain git via hook scripts (gitorious does that, for example).

        Anyway, GitHub’s shared repo mode works fine in practice if you don’t have to deal with patches coming from outside a team. We used it for a smallish project with half a dozen people where everyone was new to git, and there was IIRC one force push accident in half a year which could mostly be repaired from local reflog.

      • arnebab August 5, 2014 at 4:52 am

        as info-point: to date I witnessed two force-pushes which broke stuff for me. And stopped at least as many from people who thought that this would be a simple option to just cleanup stuff.

      • arnebab August 5, 2014 at 5:01 am

        to make matters worse, github pull requests and git branches aren’t really a good fit.

        Git requires creating a branch when you do local changes and want to push and pull locally (that just means using the basic features of git locally).

        Github gives you the second layer of mutliple repos with pull-requests which replicates most of the functionality of simple branching – except if you want to have multiple pull-requests. But additionally per-commit code-review advertises rewriting history in the branches. Which is easy to do locally it git, but horror to do in published code.

  217. max September 6, 2014 at 1:53 am

    This article is awesome. Firstly, because it is informative, and secondly, because it is magnificently misleading. Comparing svn and git is like comparing a swiss army knife to a *carpenter*. “But my knife has these five features, why is carpentry so hard?”

    If your git team doesn’t do anything complex and YOU don’t want to do anything complex, you can just stick to pull, push, checkout (-b, god forbid), and merge. You want to move a commit from one branch to another then rebase your changes against master so your history looks really nice? You can cherry pick and rebase. Or you can do what svn teams do–copy and paste things to $%^&* notepad or use 4 extra commands in a 10 step process, as they proceed to build a chair with a swiss army knife. Which is completely possible.

    If what you’re doing is “svn-simple”, you’ll find the surface area of git you have to know is ‘tiny’. But if you want to have X participants each with Y versions of the project and the ability to compose anything from any of them, you can do that too, it’s your call how to use the tool. My $.03.

    • steveko September 6, 2014 at 2:00 am

      >If your git team doesn’t do anything complex and YOU don’t want to do anything complex, you can just stick to pull, push, checkout (-b, god forbid), and merge.

      In my experience, this is simply not true. Git doesn’t work like that. You can end up in complicated, messy situations very easily, and a simple set of commands won’t get you out of it.

      Simple example from the other day.

      1. I fork a friend’s project, add some commits, push to my Github repo, and send a pull request.
      2. Friend looks at my changes, decides to implement them a better way, and does so. My pull request is ignored.
      3. I now want to submit new changes, so my github master branch needs to be in the same state as his.

      Very simple situation, and yet hard to resolve with only the basic commands.

      • max September 6, 2014 at 3:16 am

        That’s git checkout. In my opinion, you should just checkout his latest in your master. If you’re trying to turn all your changes into his head, instead just using his head, that’s not a simple example, it’s not even a good idea. Nevertheless, it wouldn’t be trivial in another VCS.

        If you had work you wanted to keep, you could just merge and resolve conflicts with ‘theirs’.

      • arnebab September 6, 2014 at 9:59 am

        Actually this IS a really simple situation, and I also found myself in that one.

        The answer is obviously, if you use git, you must not work in master.

        And by the way, the answer in incomplete: It misses the required force-push to github to recover the online repo.

        But then, here’s an even easier example.

        I have a local repository.
        I clone it locally to do some hacking.
        I push back and the repo errors out on me. Because I cannot push into a checked out branch (useless implementation details invading the user interface). And the advise is to use an intermediate bare repo. At that point I was left thinking “are you serious?” To just transfer changes locally you actually have to understand how the internals work?

        Well, I’m obviously biased by Mercurial, where this just works.

      • Tisza Gergő September 7, 2014 at 6:11 am

        Actually, when you try to to push in a checked-out branch in git, it patiently explains you why you why that might not be the best of ideas, and what to change if you want to do t nevertheless. That’s pretty good usability in my book.

        remote: error: refusing to update checked out branch: refs/heads/master
        remote: error: By default, updating the current branch in a non-bare repository
        remote: error: is denied, because it will make the index and work tree inconsistent
        remote: error: with what you pushed, and will require ‘git reset –hard’ to match
        remote: error: the work tree to HEAD.
        remote: error:
        remote: error: You can set ‘receive.denyCurrentBranch’ configuration variable to
        remote: error: ‘ignore’ or ‘warn’ in the remote repository to allow pushing into
        remote: error: its current branch; however, this is not recommended unless you
        remote: error: arranged to update its work tree to match what you pushed in some
        remote: error: other way.
        remote: error:
        remote: error: To squelch this message and still keep the default behaviour, set
        remote: error: ‘receive.denyCurrentBranch’ configuration variable to ‘refuse’.
        To ../foo/
        ! [remote rejected] master -> master (branch is currently checked out)

      • steveko September 7, 2014 at 7:21 am

        Agreed – sometimes Git gives good output. I really wish it did this consistently. Sometimes it gives no output, sometimes it gives very cryptic output – and just occasionally, it gives enough information to point you in the right direction.

      • arnebab September 7, 2014 at 8:26 am

        I disagree: This Wall-of-Text which nicely illustrates that in git implementation details dominate over the user interface. And the error message actually requires implementation knowledge to understand.

        All this to work around the limitation that the git branching model is a bit too simplistic in that it does not allow multihead branches. For git the state of a branch is always unambigous and it is the user who has to work around the fact that in reality that’s not the case between clones. it nicely explains, though, why git users almost exclusively branch by branching and don’t use quick testing clones.

        An example:

        To create a quick, clean, local test environment, git requires you to:

        – clone the local main repo to another directory, [mental task: think of a name]
        – checkout a new branch there, [mental task: take a name you did not use before]
        – do and test the changes. If they are good:
        – push or pull the branch into the main repo,
        – merge the branch into master in the main repo, and
        – delete the branch in the main repo.

        With Mercurial you cut out 2 of these 6 steps, of which 5 are pure versiontracking overhead:

        – clone the local main repo to another directory.
        – do and test the changes. If they are good:
        – push or pull the changes into the main repo, and
        – merge the changes.

        And the error message clearly shows how implementation details dominate. It lists you all these complex options, but does not care at all about what the user needs at that moment: Pushing the changes back. “name your branch – and push it to merge it later” would have completely sufficed. Git could even do that automatically when you try to push into a remote checked out branch. You would still have to delete it afterwards, but at least it would be much less horrible: It would be a brief fix to the problem and would get the user into how everyone else works around the problem instead of wall-of-texting the user.

        As icing of the cake, here’s the list of names for implementation details in that text – with potential answers from new users:

        – /refs/heads/master ← huh? isn’t that just the master-branch? Not if you look at implementation details.
        – non-bare ← what are non-bare repositories? Are there bare repositories? Why?
        – index ← what’s that? (many people always use commit -a, because they find the staging behavior confusing)
        – work tree ← do you mean my files? (though it actually is hard to find a good name for that)
        – git reset -hard ← why hard? Is that special?
        – HEAD ← what’s that? Why is it in uppercase? Is it the most important part of the message?

        And then two paragraphs on changing configuration variables to make the behavior even more surprising.

        This is a very long error message which essentially says that git makes many simple workflows needlessly complicated by putting implementation details before the user interface.

      • Raul Miller September 7, 2014 at 8:33 am

        The biggest problem git has, over hg, is that more people use git, so more people are exposed to its quirks.

        In contrast, hg has a smaller user base, and is designed for smaller projects (which is not necessarily a bad thing, but that does not make it automatically superior, either).

        Consider, for example, what happens in hg when you have a few experimental coders introducing branches to conduct local experiments. This works great, except after a year or so of this you can wind up with thousands of useless experiment branches in your hg repository. And what then? This is simply a non-issue in git. It “just works”. But the “it just works” quip does not really give an uninformed user enough information to make an informed decision.

      • arnebab September 7, 2014 at 9:27 am

        When you have useless leftover named branches in hg, then you just close them. The history why the changes were added is preserved, but they no longer obstruct work. And no, 10k branches is not a problem for hg (I tested that). Normally you will not have leftover branches, though, because most hg developers do not need to start hundreds of new branches for trivial tests. In hg that is unnecessary, because it can cope with multihead branches (which are normally merged quickly).

        I don’t understand, though, why you claim that hg is designed for smaller projects. Both hg and git were started to replace bitkeeper for Linux kernel development. Also hg is the version tracking tool for Firefox, which can’t really be called small. hg and git take a different view of what a version tracking tool has to provide for such a project, but their scope is the same.

        My guess is that you get this impression from the different main target user: git caters more to the maintainer (or more exactly: to Linus Torvalds), hg caters more to the regular developer. Interestingly, large projects have a much higher regular developer vs. maintainer ratio than the typical 1-3 persion free software projects.

      • Raul Miller September 7, 2014 at 9:31 am

        You are comfortable reading through 10k of branch names? That is your idea of an easy to use interface which just works?

        I must admit that I do not actually understand. But I guess whatever works well for you is really your call.

      • arnebab September 7, 2014 at 10:27 am

        when did I say that you have to read through them. The git equivalent of a closed branch in Mercurial is an archive tag (as explained here: http://stackoverflow.com/questions/10242924/how-to-close-a-branch-without-removing-it-from-history-in-git ). That clobbers up the tag namespace in git (try browsing through the tags for freenet one day: https://github.com/freenet/fred-staging/ – now imagine adding more by archiving branches), which it does not do in Mercurial, because closed branches are by default hidden from view and only shown in the commits done on that branch (yes, there’s a commandline switch to show closed branches).

        Also you can just as well use bookmarks in Mercurial, which are more similar to git branches than named branches, but without the single-head limitation of git branches. The bookmark itself adds a namespace when there’s a conflict, and when you push back into a repository, all bookmarks can be moved freely, because they are not part of the definition of the work tree.

      • Raul Miller September 8, 2014 at 12:11 am

        Ok, being able to hide the branch by tagging and closing it does sound address my hypothesis about the UI. But that creates a new problem, which is branch name collision. When there are natural names for a project, you’ll get naming pressure. I’m not sure if that’s a big deal, though, on a large project since you can just use per-developer prefixes to work around that.

        Still, looking further, I am still uncomfortable with the assertion that mecurial “just works” as an adequate summary. I’m seeing stuff about pushes failing because of multiple heads, diverged archives and so on.

        Solvable? yes. But … “just works”?

        Looking further, mercurial winds up being just as powerful as git in many respects. When you add extensions. Which are not designed to work together.

        You are going to have issues. That’s just a fact of life.

        And people are going to make choices which lead to further issues.

        And eventually the crud builds up to the point where people need to just start ignoring such things and find other approaches. Or live with it. Whatever.

      • arnebab September 8, 2014 at 1:19 am

        Mercurial *is* just as powerful as git – and in some aspects more powerful – but that isn’t the point. The core design choices in git make some simple to describe workflows cumbersome to use, and the degree of elitism I get to see from the git community (which is surely biased, because those are the people who go into online discussions) as well as the choice to make low-level commands part of the API for tools make it really hard to fix these problems.

        Just works for example means, that when your push fails due to multiple heads, the user interface gives you concise and easy to understand how to resolve that. And most extensions work together very well – especially the shipped ones (which you really just activate).

        But naturally “just works” is not a complete summary. It is only valid relatively when comparing Mercurial to the troubles git gives. And also when comparing it to every other version tracking tool I worked with or for which people told me about their experiences.

        People might just find better ways to do version tracking in the future – or they might change the existing tools. For example changeset evolution is really awesome, but I expect that it will need a few more years to really become a viable choice for beginners: http://evolution.experimentalworks.net/doc/

  218. max September 6, 2014 at 1:59 am

    Also, “7. unsafe”? I love when people demonize rebase. Going through all that trouble for someone with all that access would be like doing an svn dump, filter and restore to remove commits from people you don’t like.

  219. steve September 10, 2014 at 9:04 am

    i 1000% agree… I was source control admin at my last company for many years. moving from a corporate SC product to git has been a really headache and nightmare for me. the company I am at currently is *not* distributed but ‘git is cool’ so we use it. granted, I have not taken as much time as apparently is necessary to ‘learn’ git but something as simple as ‘get latest’ on a single file is so unnecessarily difficult it requires an hour of googling and ‘messing’ with it for me to even figure it out. ridiculous.

  220. Jorge Orpinel September 13, 2014 at 6:51 am

    Git is so weird… I have my own criticism of it from a different perspective, mostly after trying to use submodules and subtrees (almost impossible). Check it out here: http://rehalcon.blogspot.com/2014/09/i-dont-git-it.html

  221. Robin Jubber September 18, 2014 at 7:49 pm

    I have been using GIT at a new company for a month or so now and I absolutely loathe it. In computer games, if your menu system or interface isn’t understood by all your players, the fault is always yours, not theirs. Make a better interface, don’t blame the users. People who defend GIT don’t seem to understand this. GIT (even when using SourceTree) has an absolutely woeful interface, and I can’t think of a single way to justify it. The package is undeniably powerful, but I don’t care, because the usage model, especially if you’re new to it, is revolting. There are five or six developers here, all of whom have been using it for various periods of time – and none of them trust it. They all stick with the few commands they’re reasonably confident with and pray to god they never need to use any other aspect. I can always tell when somebody is merging a branch or doing anything with GIT or SourceTree by the fearful expression on their face and the way they tentatively tap at the keyboard or mouse buttons as if convinced they’re about to set off a nuke somewhere in the building. I was in prison once (for a crime I didn’t commit) and I was repeatedly raped by a man with a banjo and no teeth. GIT is much worse than that. People suggest if you learn to use it, it becomes better – but seriously – why should I bother? It’s meant to be a tool – I’m busy enough with coding thanks very much, I shouldn’t have to spend a year learning how to use the tools that are meant to assist with coding. I drive a motorbike. Sometimes I need to use a screwdriver in order to fix my motorbike. I don’t want to have to learn Kung Fu to black belt level in order to learn how to use the screwdriver. It takes time away from my biking! I imagine people who have spent ages learning how to use git will end up with a kind of Stockholm syndrome in defending the interface. For anybody else who just wants a version control system it’s maddening. The only good thing about it is that ‘git’ in British slang means ‘absolute bastard’. Was this intentional? Great article by the way.

    • Raul Miller September 19, 2014 at 6:19 pm

      What prison issues banjos?

      • Robin Jubber September 19, 2014 at 7:50 pm

        I’m glad you asked that question Raul. UK prisons allow stringed instruments – as long as they have nylon strings. US prisons, for instance Parchman in Mississippi, have allowed guitars and banjos for decades, usually for better behaved murderers. Prisons don’t ‘issue’ banjos of course, although in the deep south they are a pre-requisite for being in prison in the first place. It also helps if your mother is also your sister and your aunt.

  222. Tomas September 19, 2014 at 6:37 pm

    It is one thing to point out something where GIT fails or something, however most of comments in this thread are just people whining about how GIT is hard to use, has ugly interface etc…
    Well, I believe that if you are programmer, console should be more natural place for you to be than GUI. If it is not, than programming is just not for you. I can’t understand how using console can be hard for programmer, unless one is complete n00b.

    • steveko September 19, 2014 at 6:46 pm

      >I can’t understand how using console can be hard for programmer, unless one is complete n00b.

      Heh. If you read the blog post, and read all the comments, and you *still* can’t understand how Git command line interface is hard to use…well, congratulations.

      • Tomas Novoselić September 19, 2014 at 7:00 pm

        Well, I’m watching this thread probably about a year, and I still don’t see any decent argument other than “This is hard for me”. I mean if GIT is one’s biggest problem in being programmer, then congratulations as well…
        This article has always been just one biased pile of whining comments.

      • arnebab September 19, 2014 at 7:30 pm

        > other than “this is hard for me”

        So, what should people say when the UI is horrid?

        > I believe that if you are programmer, console should be more natural place for you

        Your argumentation about the command line is completely beside the point: Git is HARDEST when you use the command line. If you access it via graphical tools, those tools try to take away most of the pain and restrict you as much as needed to avoid most of the pitfalls of git.

        > if GIT is one’s biggest problem in being programmer

        No one said that git is the biggest problem. First of all, git is an UNNECESSARY problem which makes already challenging tasks harder.

        I shudder when I only think of the mess in which it left the history of one of the projects I contribute to – roughly 20-30 branches in the main repo, some of them merged into production, some not, some of them still experimental, some ready to be merged (but not marked as such – this information is only contained in sometimes existing pull-requests) and quite a few further branches only available on some developers repository where they slowly bitrot away and might disappear at whim. Yes, you can say “you just need to have more discipline”, but that’s just one of the UNNECESSARY complications git adds to a task.

    • Robin Jubber September 19, 2014 at 7:20 pm

      I’m sorry Tomas, but what you believe isn’t really relevant. A ‘real’ coder only uses the console? Doubtful. Git is even less pleasant with the console, as has been covered in the article. I’ll wager I was coding before you were born, on 8 bit machines that were purely ‘console’. Doesn’t mean I have to remain in the past. You wrote “I can’t understand how using console can be hard for programmers, unless one is complete n00b” – this is an argument from personal failure. Your failure to imagine something doesn’t make it untrue, or otherwise. As it happens I still use the console all the time, from powerful command line utilities like ImageMagick to the simpler stuff from Sony and Nintendo, which are part of their SDKs. The console still has its place – but I prefer to code in Visual Studio, Xcode, Xamarin etc, ta very much, just like I buy my lunch from Tescos instead of wandering into the forest with a rock and a pointy stick. You are also trying to distinguish between arguments ‘where git fails’ and ‘whining about how GIT is hard to use’. You fail to understand that a bad interface is a failure. If I made an AI program that could answer all medical questions, but made the interface using ancient Latin encoded in a shifting form of BCD on punch cards that themselves had to be blessed by the pope before use it might be fair to say the overall package was a bit of a failure. GIT’s interface and concepts are part of GIT, even more firmly embedded in it’s DNA than the spurious example I listed above. It’s also worth asking what you think Version Control software is for, if you don’t think hard-to-use is an issue. In the real world, version control is used by coders, artists, designers, sound engineers, project managers all contributing to the same project. The user interface isn’t a minor aspect of the package, it’s the key aspect.

      • arnebab September 19, 2014 at 7:36 pm

        That’s much more stringent argumentation than mine :)

        What I’d like to add: Version Control is about making a task easy. It should alleviate fears of losing work to allow for quick experimentation, simplify cooperation and stay out of the way as much as possible.

      • Tomas Novoselić September 19, 2014 at 7:46 pm

        Well Robin, thanks for answer. I would like to point out that you surely didn’t code before I was born and be sure I have my own 8bit experience as well.
        That said…
        Reason why I’m even arguing here is that “git interface” is not GIT’s interface considering that that it follows same POSIX standards as any other well written UNIX CLI software so when someone is saying that GIT interface sucks it is same as he’s saying that POSIX sucks.
        It is true that some people are having problem with GIT, however that doesn’t mean GIT interface is bad, it just means one should seek for other solution because GIT works good and has great interface for surprisingly high number of people, so if GIT is “too hard”, maybe one should use something more easy and admit to oneself that having problem with git doesn’t mean other people have the same problem.

      • Tomas Novoselić September 19, 2014 at 8:03 pm

        @arnebab You need to understand that like many other GPL software, git is made in order to help his creator to do the job he couldn’t do before. If that mission is completed, then git wins. Having possibility to use git by other people is just one more feature of it. So, one that doesn’t like it, doesn’t need to use it and that’s about it. If you don’t have same requirements as creator, git shouldn’t be used.
        Additionaly, I don’t think git is ever meant to be used via GUI and this actually complicates stuff IMHO.
        For the end, I seriously doubt that git would ever become that popular if it is really HARD to use. I find it awesome, as many other people and I couldn’t care less if someone finds it hard. HARD is personal feeling, not general fact.

      • Tomas Novoselić September 19, 2014 at 8:06 pm

        Don’t get me wrong. I don’t think it is for everybody. I’m just saying that “it is hard” is invalid argument.

    • Tim September 19, 2014 at 7:24 pm

      Its not about console vs gui. I use Mercurial and SVN from both. I also use GIT from both. GIT still stinks.

  223. Robin Jubber September 19, 2014 at 10:08 pm

    Tomas – it’s nice to meet another old 8-bit coder :-). My comment was speculative, based on your position on what a ‘real’ programmer is. No such entity exists. I can’t comment on the POSIX side of things, as I don’t know anything about that. All I can go on is that in my experience, and clearly that of many other people git is a) complex and opaque in use, in terms of terminology and use flow, irrespective of interface and b) has a horrible interface and c) is powerful but d) because of the way the user is supposed to use the software being so badly thought out, utterly crippled for a great many people for whom a simple usage model is an important aspect of source control. I would argue that in *all* cases, a simple usage and comprehension model is what should be expected from any kind of Version Control. Do you think people will be using GIT, like it is now, in thirty years? You also suggest that if one finds git ‘too hard’ ( your words – a deliberate misrepresentation/simplification of the problems people have mentioned with GIT on this site ) one should use something else. Well that isn’t always an option – you turn up at a company and you use what they have in place. That’s still irrelevant to the main point. The Model T Ford is a bad car with terrible brakes. I can use another car. We can all use other cars. The Model T Ford is still shit. The problem isn’t that it’s ‘too hard’, it’s that it’s ‘viciously unpleasant and badly/foolishly thought out’. GIT that is. The Model T is just very outdated. Just because a system is complex or powerful, that’s no reason for the way in to be barred by opaque terminology, a horrible, inconsistent interface and too many steps for simple (i.e. most frequently used) operations. You suggest that people are merely ‘whining’ about a system you personally think is fabulous. Are we to understand that anybody who disagrees with your love of this system is just whining? That seems a little reductionist. We may as well say that you’re merely whining that people aren’t as impressed with GIT as you are. I’m not sure that either position advances the argument. However I think we may agree on more things than you realise.

  224. Tomas Novoselić September 19, 2014 at 10:56 pm

    Robin, I believe that we are talking about different things. Some people like GIT, some people don’t like it and that’s it, however just saying that git is ugly implies that you think every CLI command is ugly if it has POSIX style syntax :)
    Take “ls” for example. It was written in 1971. and it still does great job.
    I don’t want to open some GUI just to be able to do few simple commands to organize my code when I can make it in few keystrokes. I can script it, i can do whatever I want and it is great as it is.
    Who doesn’t like it, doesn’t need to like it, but to say it is UGLY is just personal taste, nothing else.
    Git does have many weird things, however 80% of comments are either “it is hard” or “it is ugly” which in my opinion is not measure of usability.

    • Robin Jubber September 20, 2014 at 12:09 am

      I can see your point, and it’s not unreasonable on the surface. However usability is not an abstract notion. There are real world metrics that can be applied to define how useable a particular interface is. GIT would fail spectacularly on these. That’s not a matter of personal taste, but a researched and well understood field. Nobody is discussing the POSIX model, which I think GIT fails to adhere to – but the fact that the whole thing is non-intuitive. Do all the commands work the same way? No. Please see the original blog post. Does all the terminology fit other VC software or even plain English, the most powerful communication model we have ever created? No. Does all the terminology fit GITs own internal model? No. Or rather, I have no idea. Does it make your code safe to use GIT without full knowledge of how every aspect of the software works? No. Not even close. I’m very glad that you prefer to use a command line for some basic GIT usage – it’s great that you’re familiar with the software and can use it in that way. However I still hate it, and even if in ten years I’m completely familiar with GIT (and am happy with the terrible life choices that got me to that state) I will still remember just how non-intuitive the software is to use, especially at first blush. I don’t use GIT from home, I’m forced to use it in a real world office environment. Nobody here likes it – only one person – the bespectacled autistic bloke who sits in corner, cradling his stapler, can even confidently use the basics. It’s not just ‘ugly’ – it’s objectively an overly complex model, both in terms of use and design. Your liking it is at best anecdotal evidence it its defence. I could be accused of the same thing of course. However I design user interfaces for a living and would be unhappy to have created something like GIT – I could checklist the reasons if I had time. ‘It is hard’ and ‘it is ugly’ – whilst slightly reductionist and unfair summaries of the criticisms on this site, are in fact very real measures of usability. Software is a tool, as are computers. GIT is a powerful tool, like a hammer with 19 hidden functions. However it is hard to use this tool because it is like a hammer with 19 extra buttons, and there are several knife blades sticking out of the handle. Your facility with GIT is to be admired :-)

  225. Atte Peltomäki September 29, 2014 at 10:45 pm

    Very nice blog post that sums up the biggest shortcomings and misgivings of git.

    I might add that many of the described problems plague the GNU OSS world on a much wider scale; users are much too often implicitly assumed to know how a piece of software works, and having well-designed, separate user interface is quite rare indeed.

    A simple example is iptables: I haven’t yet heard anyone adequately explain why an end-user would need to know about different chains. All they care for a packet is the interface, source and destination. I understand chains are how iptables internally works, but exposing this to the end-user serves no purpose.

    • Raul Miller September 30, 2014 at 11:18 pm

      You are correct.

      In fact, there is no need for an end user to know anything at all. In fact, end users do not need computers at all.

      End users need good nutrition, a safe place to sleep at night and adequate water, and they need exercise. Computers are simply not nutritious. This is why you should go out and buy a television set and watch it rather than waste your time reading.

      All sarcasm aside, the fact is there’s simply no choice that anyone can make which satisfies everyone. People like to whine and complain, and the more popular something or someone is, the more criticism it attracts. Some of that is valid, but most of it will not be.

      Sturgeon’s Law: 90% of everything is crud.

      That applies to both git and to hg. Which is why we tend to be a bit suspicious when we hear only glowing praises of something new. And then try it anyways, perhaps until we find things to complain about.

      The grass is always greener on the other side of the fence. For a little while.

      • Robin Jubber October 1, 2014 at 12:00 am

        Look! Look at the strawman! It’s huge! It’s the biggest strawman I ever did see! I think Edward Woodward is waving from somewhere near the top. He looks pissed!

        I enjoyed your post, but it’s still bollocks. We’re not looking for something to be perfect, or that nobody will ever ‘whinge’ about. Those of us who are unimpressed with GIT aren’t a little bit annoyed about the interface and general design or just making a fuss for the hell of it – you’re going to have to grow up and face the facts – GIT is severely compromised (or held back from true greatness, if you prefer), mainly due to the interface and partly due to the design underpinning it. The people complaining (complaining is good – without it nothing improves) about GIT on this blog are not scullery maids, chimney sweeps or carpenters. Everyone here is some form of technology professional – is that a fair assumption? The people here are well educated or at least technology literate. I assume many are programmers. Nobody can know every aspect of technology – there’s too much stuff, too many protocols, too many languages. Most would be keen to embrace a Source Control system that is powerful, easy to use and good at protecting the inexperienced or mistaken against fatal data collision and loss. In some cases we have to use GIT because it is mandated by our companies. Because a few people have managed to embrace GIT, or think like GIT’s programmers, it’s unreasonable to assume that everybody has the time or inclination to do the same thing – nor that anybody who complains about GIT’s manifest inadequacies is merely whinging for the sake of it. I think we’re all quite capable of distinguishing in our own minds at least, the difference between a minor annoyance that is mentioned in passing and a comprehensive deep rooted antipathy towards various aspects of what is in the end still a very powerful piece of software. The blog poster has even provided reasonable analysis including diagrammatic evidence – that’s a little more analytical than a mere whinge.

      • Raul Miller October 1, 2014 at 12:52 am

        It seems to me that the solution for many of our technological failures is better documentation.

        In the case of git, I like to point people at http://marklodato.github.io/visual-git-guide/index-en.html

        In the case of Linux… well, actually, I’ve switched to OpenBSD (and am seriously considering plan9, but I’m not quite up for that challenge).

        Anyways… I am not at all convinced that “good user interface design” is a relevant issue when talking about low-level computational mechanisms. Instead, the challenge is writing good, comprehensive documentation in a context where the coders are involved.

        In my experience what happens is that coders can often radically simplify the documentation by rewriting small parts of the system.

        Now… in the case of git… there’s a nice clean system sitting in there, buried in the crud of lots of contributions. Mostly the right approach here is to ignore most of the contributions.

        In the case of hg, something similar is going on, but the crud is more in the conflicts between addon modules. Since git comes with the equivalent of hg’s modules pre-installed, people can level complaints at git which are analogous to complaints leveled at hg+modules.

        All of which is a lot of fun, I suppose.

        That said, there’s nothing wrong with being a scullery maid. Nor with being a chimney sweep. Indeed, some of them are quite well educated. Perhaps I should look into becoming one. Or, maybe a carpenter.

  226. Zack63 October 11, 2014 at 7:45 am

    I’m having a hard time deciding which I hate more: git or eclipse. Its really a tough choice, but if you put a gun to my head, I’d have to say git.

    • gbutiri October 11, 2014 at 2:29 pm

      I hate having to use git, but I have to be very thankful for the people who made tortoise git. Also, I think the version for Mac is called stash? Or something. Either way, tortoise git, and even tortoise svn are a godsend. It helps us UI oriented folk. Only thing I still have to figure out is to remotely pull on the production servers.

  227. Phil-UK October 15, 2014 at 2:19 am

    Incisive article and mirrors my experience exactly. I add value by creating computer code, every other task is simply cost on top of that basic economic function. My clients dont pay for my specifications, or my unit tests, or my OO concepts – just for solid working software. A tool which gets in the way rather than expediting that added value activity is just extra cost. Concepts and tools which help me deliver working software to the client more swiftly and with less defects than when not using them are extremely welcome. Tools which make this more difficult than it absolutely needs to be are not welcome. Building working software isn’t easy, but its got a lot easier as tools have matured and been adapted based on user feedback. Typically, but not always, this is becasue the tools are purchased and therefore the vendor has a vested interest in making them better.

    There are some developers who revel in tool complexity and opaqueness but in my opinion simply aren’t doing the economic maths and are fetishising complexity to raise the barrier between them, the “experts” and the others, “the noobs”.

    Git is hard to understand, not fail-safe, and unless you actually need distributed source code control (as opposed to geographically seperated team members) is wildly over-complicated for the basic function of building computer systems for clients.

  228. Tapatio Ca October 24, 2014 at 7:40 am

    Excellent post ! About the point:

    ” 6. Power for the maintainer, at the expense of the contributor
    Interestingly, I don’t think this trade-off is inherent in Git’s design. It’s simply the result of ignoring the needs of normal users, ”

    Hahaha, what else you could expect from Linus Torvalds ?

  229. Pingback: Is Git hard? | gerleim

  230. Mad Programmer October 31, 2014 at 12:01 am

    Another good ole time with git. Tech Lead dude (this is the typical “master” in a git project) wants only simple PR’s (code reviews); so, take the 30 file change project and commit and push to A. Then push to B. Now, go back to A and remove 10 files etc. So, now we can first code review A and then later B (based on a diff against A). Sounds easy? Works in theory but in practice the tools do not repull the files for B once you make your deletes in A and push it. So, how to fix? You need to do a fresh git clone -b B … (well maybe a reset hard would have worked. Forgot to try that. But, I checked out B and expected to get B. Not happening with git bash or egit, I still have A. Well, it might be an easy fix to run rest hard or git clone -b; but its user hostile. The point of the OP.

  231. Max Weber November 8, 2014 at 1:34 am

    Ok, so here the main thing. I mean, GIT is user hostile but we all used Unix for years before Linux and survived. That’s a weakness but not a deal breaker. The main problem with GIT is the sociology it fosters. The typical thing is one person gets setup as a Tech Lead. Over time they behave more and more hostile towards the programmers on the team. For example, they will force a programmer to keep changing variable names and other junk to delay that programmer merging into the base (master/whatever). Of course, because of GIT’s process, that programmers branch becomes ever more out of date. He/she can spend time constantly trying to rectify the changes others are making. In specific, the Tech Lead(s) typically form one first class team where they commit+push willy nilly in the master (release branch stream) and the rest of the team is a horde which becomes ever less productive as they are forced to “fix” all the changes the Tech Team does in trying to make them work with the rest of the system. GIT ends up being a great tool for a few team members to bully and pick on the rest. Not really what you want if you want a TEAM.

    • Bernd Jendrissek November 8, 2014 at 3:26 am

      Oh come on Max, git has enough real problems that you don’t have to make up things. A “Tech Lead” cabal can do exactly the same in any other VCS, maybe even more efficiently when it isn’t trivial to clone a project with full history.

    • Raul Miller November 8, 2014 at 9:51 am

      This does not at all match my experiences with git. And I used it extensively in a corporate environment and I was not the lead in charge.

      That said, the issues you describe do seem quite likely to arise when dealing with certain people. So I do not at all doubt the accuracy of your observations (except to note that these problems arise regardless of the technology involved).

      • arnebab November 8, 2014 at 7:02 pm

        I think you’re right that with great people every tool works well.

        The problem Max describes is likely because Git makes it much easier to mask toxic behavior as useful.

        In the Freenet project I saw 3 specific costs introduced due to git: Many not-quite-finished feature branches which did not get merged for months to years, pull-requests which were not merged because they were not perfect and a codebase which changed underneath, making the merges become more and more expensive. This keeps us from doing much-needed refactoring, because that would make the merges even more expensive. The codebase isn’t only entangled internally, but now also between forks with different states of the code which will need to be merged.

      • Bernd Jendrissek November 9, 2014 at 4:25 am

        How does using something other than git prevent features from rotting as they lie unmerged? Using SVN or CVS or hg or whatever won’t magically integrate those features into the mainline code. *That* is the problem – patches withering away in project maintainer neglect (whether benign or malevolent) – not the choice of VCS.

      • arnebab November 27, 2014 at 7:37 am

        The default per-developer namespaces in git as well as renaming branches make it much easier for developers to simply drop in some patches (=commits) and forget them – in my experience they often never even get pulled into the main repository and subsequently get forgotten. I had to remind the maintainer of a project multiple times that there were still unmerged branches lying around when he only remembered the pull-requests. And that wasn’t malevolent: The project has roughly 100 branches from some unreleased feature development here and then some unreleased feature development there – and actually a GSoC project which was only released in a personal github repository and then not pulled. At one point I went in and pulled every single branch from every single fork into my own reposiotry just to have a backup in case users delete their accounts. And this is partly the fault of the tool: Git makes it easiest to work on your own and to ignore the larger project.

        Mercurial on the other hand by default provides a shared view of the branches, and its interface encourages developers to pull and merge often. This makes it easiest to collaborate on a shared view of the code instead of making it easiest to create your own view into which you later integrate some other changes.

        Consider on the other hand subversion: It makes it very hard to do short-lived branches, so people create huge commits with lots of actual merges which aren’t visible, because they happened on update before they could commit.

        The tool has an effect on the culture which develops around the tool. Things which are easy to do will inevitably become more common and things which are hard will become less common over time. And nt git, things which are easy to do even include rebasing, which even Linus nowadays asks people to avoid, because it is a huge smoking foot-gun.

        This does not mean that avoiding git will magically get all features merged instantly. Avoiding git is not a magic bullet which solves all your problems. It just makes life a bit better by avoiding the unnecessary *extra* problems git forces on your project.

        If the alternative were CVS or an unfree VCS, I’d choose git any day. But that’s not the case. There are alternatives to git which provide you with the same features but less foot-guns and less encouragement for behavior which creates problems for the project on the long run.

      • arnebab November 8, 2014 at 7:04 pm

        and all the above without involving bad intentions: All the changes were done to improve the project (I know the people involved). It’s very easy to fall in that trap simply due to “limited time at the moment, I’ll do it tomorrow”.

      • arnebab November 8, 2014 at 7:05 pm

        (yes, that means that people aren’t perfect, so problems of the tool crop into our development practices)

  232. Max Weber November 8, 2014 at 1:36 am

    In summary, GIT is an overly complex tool for people who cannot work well with others. As stated above, it adds 10% to 20% to a project cost versus using Subversion. 1.25 years experience with GIT. Several years with SVN. 21 years with about 8 source control systems total.

  233. vanna November 11, 2014 at 4:34 am

    GIT is not perfect, but I have worked with SVN for several years and that was just a pain.

  234. tronika November 13, 2014 at 4:00 am

    git helps weed out the script-weenies

    • steveko November 13, 2014 at 10:20 am

      Possibly. Is that a good thing?

      • Robin Jubber November 13, 2014 at 11:17 am

        Of course! Here at Terrifying Software Inc we have a Code Stabber, who wanders round the office, checking on code. Your code isn’t up to the same level as Bjarne Stroustrup? You get a stabbing. Hoping to learn on the job? That’s a stabbing. No code weenies here. Only muscular, virile code paragons, albeit mostly autistic and sweating profusely.

  235. Max Weber November 25, 2014 at 11:24 pm

    Thank GOODNESS for TortoiseGIT. At least now I can just about do a decent history analysis to see who did that ____. Funny when you track down freshman code from the person on the project who has playing the role of Architect and runs his mouth and tries to over-ride the conversations when he does join the meetings.

    One more git PITA:

    $ git status
    On branch EPIC_XYZ
    Your branch is up-to-date with 'origin/EPIC_XYZ'

    .$ git pull
    [git proceeds to pull down two changes]

    EXCUSE ME? “up-to-date” is English for no changes. Who wrote this ____.?

    • Max Weber November 25, 2014 at 11:30 pm

      Well, I didn’t mention this happened because I did a merge with Stash then went to Eclipse and did a new branch based on the mainline in eGit. The eGit did NOT get the latest files. Sure, there might be a timestamp issue between something. I’ve documented before and above that git/stash don’t work well across timezones. But, this is not expected and can lead to lots of issues. Basic feature of a source control system is reliable check-in and check-out. This is not.

    • steveko November 26, 2014 at 9:32 am

      Agreed. Git, despite being “distributed version control”, lives in an offline world. You have to manually synchronise the “remote branch” (held locally) against the actual “remote branch”. Maybe this made sense 10 years ago, but it’s really counterintuitive and somewhat bizarre now.

      • arnebab November 27, 2014 at 6:39 am

        I don’t mind the offlineness. What I mind is the horrible message: It should not state that it is up to date with origin/. That’s a total user interface failure, because the actual meaning (up to date with the local branch) is the opposite of what the word origin implies.

      • rademi November 27, 2014 at 8:22 am

        That’s semantic drift for you. You can take heart, though – most of the english language has been subject to the same kind of issue. (For example, a few centuries ago, “genius” meant what we would now term “idiotic”. For example, “sick” can be a term of high praise, in some contexts. For example, sensitive topics tend to be discussed using euphemisms which tend to be replaced once they become well understood.)

        That said, you do not need to understand all of git’s internals. You do need to understand some, but a system which does not require some understanding is a useless system.

        That said, Mercurial proved that it’s possible to build a system with less capability than git and then add that capability back in using plugins. The downside, of course, is that plugins are a horrible user interface experience, due to design conflicts between independent plugins and a need to have a deep understanding of the underlying system in order to isolate and resolve problems.

        That said, a system which does not require some understanding is a useless system.

    • rademi November 26, 2014 at 9:43 am

      origin/EPIC_XYZ is your local image of the remote. You might want to consider doing a fetch before status if you want to compare your system with the remote?

      Or, you know, I guess instead we could wish that there were no actual work worth doing…. And I hear there’s good money to be made in making systems less capable and then claiming that that’s an improvement.

      • arnebab November 27, 2014 at 6:57 am

        I blame it on git that people think that source control has to be complicated to be powerful.

        Mercurial proved over and over again that it is possible to create a simple user interface which allows harnessing the same capabilities as with git – and then some on top with its powerful plugins.

        Git however does not even try to be usable: Implementation details inevitably seep into your workflow and require you to understand all of git’s internals to use it effectively.

  236. Max Weber December 5, 2014 at 7:59 pm

    $ git merge FETCH_HEAD
    merge: FETCH_HEAD – not something we can merge
    OMG!

    • Max Weber December 5, 2014 at 8:13 pm

      Just FYI: work-around for not being able to merge from EPIC (main) branch was to go find last branch merged into that EPIC and to merge from it. Of course, this would not have been possible if the team were truly working distributedly; but, the team is using Stash and putting all bug/feature/issue branches on the server also.

  237. Max Weber December 18, 2014 at 3:51 am

    Here’s another fun one. In eGit create a new branch against an origin branch. Look in the files. They are not up to date. Why? I guess git uses the last pull against that origin rather than the actual origin. So, you have to perform a pull to get the latest file. New branch, one would think, should get the current files of the origin branch. It doesn’t if one has worked with that origin before.

    • Max Weber November 18, 2015 at 1:01 am

      Yeah, this is a BIG user experience design flaw in GIT. No telling how many bugs and how much time it has wasted. What git does is when you git checkout EPIC_BLAH then it does NOT go against origin but actually against a local copy. So you MUST next issue a “git pull”. To get the central code. Yes, I know git is designed for that high-and-might tech lead who feels the code on his/her computer is the golden source; but, in the normal world people work as teams and code gets pushed to a central server. Pulling, by default, from local when user wants to branch from the main (epic) branch is bad user experience design. But, hey, we are talking about git, aren’t we!

  238. Mathew December 20, 2014 at 9:26 pm

    No use and no point ranting off git as git isn’t even targeted at beginners.

    git isn’t targetted at beginners, or author should just find some nice GUI git frontend which can hide the complexity or use something he can understand.

    Linus Torvalds originally developed git for use with the linux kernel development which has a very complex model.

    • arnebab December 22, 2014 at 4:43 am

      I agree, that beginners should use something they can understand. But sadly git-using projects force beginners (of version tracking) to use Git when they want to contribute. You’re saying that any projects which wants people to contribute who don’t *already* know git well, should use another VCS, and I agree. I would add, though, that everyone starts out as a beginner, so if most projects use git, there isn’t any project in which beginners can contribute. But since in free software the turnover rate of developers is pretty high, all projects are dependent on getting new people to join.

      So I’d say, that your assertion that git isn’t targeted at beginners leads to the conclusion that no free software project should use git.

      • Max Weber November 18, 2015 at 1:03 am

        The main beginner here is whomever wrote git. Or, rather, whoever thinks it should be used for teams. Its fine for the two cases for which it is designed.

  239. iva December 24, 2014 at 3:10 am

    This blog reminds me of the blog bashing Raven-DB, where the conclusion was, that the blogger misunderstood the concept of DocumentDB, and was trying to apply relational concepts on a document based database. They were having a bad time…

    Subversion was my first experience with project/file versioning working with it for 5 years and loved it (with it’s faults). But after a go with Git in a couple of years, I would never dream of recommending going back. After migrating to Git the headaches of merging was simply gone. Less time was used on the revisioning system, and more time went to implementation.
    Also had the pleasure with TFS, which tasted like subversion.

    If you wanna make a subversion-like use-case, then why not just ad the developer as a contributor to avoid pull requests?

    To avoid the two-step commit/push, then make an alias. I myself would not do so, since I find it powerfull that I can make partial commits/milestones locally, before pushing to a branch. Never had that situation, where you wish you’ve stuck with your first (un-pushed) solution while refactoring?

    Atm I’m working in a small 4-man group using TFS. And the guys are using a lot of technical-excuses due to the lacks in TFS. Seems like Git is gonna get a go :)

    • steveko December 24, 2014 at 9:17 am

      > If you wanna make a subversion-like use-case, then why not just ad the developer as a contributor to avoid pull requests?

      That kind of makes sense, but you’re speaking as repository manager, not developer. Anyway, it’s been two and a half years since I wrote this post. When I wrote it, my feeling was a very frustrated “I find Git so hard to use, am I the only one?” My feeling, having used it a lot since then is, “No, the designers and maintainers of Git have created a lot of unnecessary pain, and they have made only the slightest improvements to usability in that time”.

      The complexity, steep learning curve, and vast number of edge cases and weird messes that are hard to resolve are a travesty, for a tool which is at the absolute heart of the vast majority of open source software development. The OSS world would be a much better place if they’d got this stuff right.

    • sfkleach December 24, 2014 at 6:57 pm

      Although there is a element of ‘bashing’ in the original post, I think there are unavoidable criticisms: namely, that git’s informational model is very complicated, exacerbated by a messy, disorganised command-line structure, and that its disappointingly easy to get into a confused state where work is lost.

      Unfortunately, the original post made these criticisms relative to Subversion rather than alternative DCVSs, which was a red herring. These points are strong but the comparison with Subversion undermined them because, good though Subversion is, it’s a very unconvincing alternative to git.

      • steveko December 24, 2014 at 7:06 pm

        >Unfortunately, the original post made these criticisms relative to Subversion rather than alternative DCVSs, which was a red herring. These points are strong but the comparison with Subversion undermined them because, good though Subversion is, it’s a very unconvincing alternative to git.

        Yeah, when I wrote the post, I wasn’t expecting 250,000 views. Back in 2012, I think Subversion was still the dominant version control system that people were migrating away from – certainly it was the one I knew best. My complaint was “my experience using Subversion was pretty simple. With Git(hub) it’s a nightmare. WTF?” Definitely not an apple-to-apples comparison.

      • sfkleach December 24, 2014 at 10:16 pm

        Agreed. You argued passionately and captured the ‘WTF’ sentiment that git inspires for many many people. And you certainly have my sympathy for the mere 250,00 views ;)

  240. BAReFOOt December 27, 2014 at 9:06 pm

    It’s simple: If all you can handle or need is MS Paint, and you use Maya, you don’t get to bitch about Maya. Go back to your MS Paint. It’s the right tool for you.
    But maybe you’re not smart enough to realize that either.

    • sfkleach December 27, 2014 at 9:46 pm

      This is an oxymoron of a reply. You’re trying to claim an elite intellectual position while conducting the argument at the level of a child.

    • steveko January 3, 2015 at 9:48 am

      If you reword your argument as “if all you can handle or need is a bitmap paint program, you don’t get to bitch about 3d modelling software”, then sure. But virtually all software can be, and should be, made easier to use – probably Maya included.

      • rademi January 3, 2015 at 10:25 am

        Most software should be documented better. Better reference documentation, better task oriented documentation, and better tutorials, better cross linking between them are all good. And, it’s also good for the person writing the software to take part in the documentation process (because all too often changing the software to be easier to document is better than documenting some arbitrary decision).

        That said, “easier to use” is not actually an “always thing”, even for software. Once software is in use, changing it or replacing it breaks existing uses which makes it harder to use (for some people).

        Worse, easier for task A can often be harder for task B.

        And that, I think, is related to what we are seeing here.

  241. Phillip Hamlyn December 29, 2014 at 5:08 am

    Leaving aside the merits of Git vs TFS vs “the World” I am surprised at the level of unprofessional reaction to what would otherwise be a dry subject about the merits of the functionality and accessibility of a source code control system. Steve’s original comments about Git being hard to learn and hard to master don’t seem (whether you think they are justified or not) to merit the really strong opinions that have been aired. What is it about the assertion that seems to rile technical people to throw their toys out of the pram ?

    I happen to agree with Steve but also realise there are a host of people out there who get on with Git just fine. They are the “happy customers” of Git. There are also a whole bunch of “Unhappy Customers” it seems who find it overly difficult or its strengths relatively unhelpful in their working environment – if our reaction as a profession to our “Customers” is “the customer is wrong, the product is brilliant” as opposed to “If the Customer says they have a problem, then we ought to attend to that” we are in trouble.

    You know, perhaps at the heart of the problem is that there are no true paying customers of Git ? In a true commercial offering, the authors would be beholden to make their product suit their customers (whether they liked what the customer was telling them or not) – you could sell Git on its powerful features, or perhaps TFS on its low friction user experience, but in both cases you would need to be flexible to provide what the customer demanded. Without the pressure of the market to shape the product, maybe vociferous opinion fills the gap ?

    • rademi January 3, 2015 at 3:02 pm

      I will agree that I do not think of anybody in this conversation as my “customer”.

      • Phillip Hamlyn February 11, 2015 at 8:21 am

        But to the authors of Git, we are their ‘customer’ even if we don’t pay. Building for your customer is a mindset where you build what your customer wants and needs, not what you wish them to have. My real thrust here is that because Git lacks a customer focused development team, we get what we are given, not what we want or need. To repeat my point; its perhaps because we are unwilling in the main to sponsor (with money) a customer focused development effort that we get stuck with “hard to use” freebies. Its just a way of looking at why a supposedly “premiere” software development tool seems to generate strong emotions of either euphoria (or defensiveness) or disappointment (or flame). Or put another way Steve Bennet says “gosh this is so hard to use, could it not have been done better ?” to which a reply might be “perhaps if we paid for it, the authors would listen to us because they’d value our opinion, because the opinions of customers are valuable to a commercial organisation”.

    • Richard Cross February 11, 2015 at 5:34 am

      If Git is so painful to use, why is this happening?: http://www.google.co.uk/trends/explore#q=%2Fm%2F05vqwg%2C%20%2Fm%2F012ct9&cmpt=q&tz=

      To be taken with a pinch of salt, as Google Trends hardly constitutes scientific research.

      ;-)

  242. steveko January 3, 2015 at 10:46 am

    Nice comment. Yes, Git could do with much better documentation, and could have done for many years. Better in the sense of “more useful to the average user”.

    >That said, “easier to use” is not actually an “always thing”, even for software. Once software is in use, changing it or replacing it breaks existing uses which makes it harder to use (for some people).

    Git seems to have been unnecessarily conservative in this regard. The porcelain/plumbing distinction was supposed to make it possible to change the command line interface, but that has happened incredibly slowly. Occasionally, you get really useful information describing what just happened and what your options are. Mostly you don’t. There’s no good reason for this. And no reason not to fix it.

    >Worse, easier for task A can often be harder for task B.

    Agreed, but IMHO Git is most suited to a tiny fraction of its actual users.

  243. Pingback: Git | PolyAwesomism

  244. PeterB January 8, 2015 at 2:26 am

    Git vs SVN comparisons are perilous because people rightly point out that distributed version control systems have a lot of advantages over strictly centralized ones, and that turns into an inference that Git is better than SVN because it’s distributed. If Git were the only way to do DVCS, maybe this would hold true, but it’s not.

    Both Bazaar and Mercurial are easier to use and deliver all the benefits of DVCS. Hell, Bazaar can even support the centralized svn workflow while more advanced users can take advantage of distributed features.

    Most of the stash/rebase/squashing commits/etc in Git is busy work you have to do to work around Git, not powerful features. Spend some time with either Mercurial and Bazaar and you’ll see this. Furthermore, Git discards what most VCS users would regard as branch histories whereas hg and bzr do not. Both of these systems map to our mental models of changes better than Git, which is why there’s so much confusion when people attempt to understand wtf Git is doing or how to dig themselves out of a problem.

    See http://duckrowing.com/2013/12/26/bzr-init-a-bazaar-tutorial/ and http://www.cs.cmu.edu/~davide/howto/git_lose.html

    Distributed version control can be a lot better than centralized version control, but there are much better and easier options than Git.

  245. NICOLAS January 14, 2015 at 4:25 am

    I Totally agree that git is overly complex and counter intuitive at the point where it looks “almost” purposely. it is the developer to do ALL THE EFFORTS to learn understand and fix. The confusing and inconsistent command line makes it DANGEROUS too. The system gives no EASY way to actually FIX the problems but just DROPS them in an unfriendly manner to the face of the developer for him to deal with. You can easily as a beginner be blocked in the middle of the river : Cant commit/push/pull cant ‘t solve and can’t cancel and can’t roll back easily ! BROKEN.

    This is a perfect example of a GOOD CONCEPT and a TERRIBLE IMPLEMENTATION that does GOOD – AND BAD because of it might slow down a better DVCS FREE OPEN SOURCE software tool adoption by its popularity.

    I wish it will quickly die and be the seed of a better DVCS that works on same main ideas but a this time DECENT and CLEAN implementation that users can actually use.

    ANYONE should be able to use this kind of tools WITHOUT have to take lessons and read extended manuals first !
    if you need a degree in order to understand and checkin some code in some system something is wrong !

    • arnebab January 14, 2015 at 10:50 pm

      You might want to look at Mercurial. It developed side-by-side with git and they inspired each other, but different from git, it had a strong focus on clean user interface from the start.

      If you’re used to git, the main stumbling block are small differences in philosophy. These have major impacts on branching (Mercurial avoids the need to branch everything explicitly because it easily copes with multi-head branches, but urges developers in the user interface to keep *public* branches to one head), tags (versioned tags as part of the history), history style (Mercurial favors slightly messy history over rewriting published data and in turn provides powerful tools to query the history) and project organization (Mercurial favors sharing history early – focussing at the project – git favors keeping it in private repositories until it is perfect – focussing on the individual developer).

  246. elvis returns January 28, 2015 at 1:52 pm

    I think people are approaching this completely the wrong way. Comparing two tools like this doesn’t really work when both are potentially viable and not one supercedes the other across the entire domain of software development. I can say with full confidence that for my requirements SVN is not only the best choice but superior to git in what it offers. I could talk a lot about SVN to prove this but it’s not all about just SVN. There is a 50/50 split here. The is tool/situation. We really see everyone focusing on tool with little focus on the situation.

    My situation is simple and common but perhaps more hidden than the well known case of public opensource projects. I work on a small closed source project. We have a small team and it’s not likely to become significantly larger or distributed in any unmanageable way. Many projects, even very profitable ones, do not warrant hundreds or thousands of developers, especially not complete strangers.

    Git is geared very much for a number of opposite extremes:

    * Collaboration is anonymous. What this means is that collaborators are untrusted and that we cannot impose constraints or policies upon them, instead we must heavily guard the source tree.
    * Project sizes can be huge an receive great numbers of contributions (ie, the Linux kernel).
    * Projects are individual backed and not backed commercially. The original primary source may go down for example.
    * Projects may be extremely long lived. This may also be the case for commercial projects but combined with the volume of contribution this can become a serious problem.

    This might not be a lot but many problems fork from these facts. In this case the push pull requests make sense, committing locally makes sense to encourage complete submissions upstream rather than several partials (which may never be submitted in completion otherwise and burden a central repository). Local operations can also reduce the burden on the main repo and distribution can offer some interesting scalability benefits. Innate backups are also useful. Clearly, the design of git was very insightful about this situation and tailored to it.

    That is exactly where the problem with git lies. It’s a great solution, but to a particular situation and all the problems that entails. I do not have such a situation or such problems. My situation is different.

    * I am in close proximity to all programmers. They are contracted and employed. They must follow procedure and are trained appropriately. There is little need for hard restrictions either on the VCS front. They are not anonymous and if they do not conform adequately, I hate to say this but it is true and this is in the real world, they get fired. In the absolute worst case that they do something wrong (destructive, deleting files, etc) they get thrown in the dock. The VCS is also not our direct means of public or end customer distribution. While distributions are taken from the VCS, this is by us and is a controlled process. Code does not go straight from VCS to customers or nodes. Very few commercial ventures would use VCS in an uncontrolled way for distribution so this is the norm here. Git is different because people may be pulling straight from the VCS to contribute or build. For a commercial setup we often only need tight control at distribution which is where the hard restrictions go. VCS is a natural sandbox in such a case.
    * From a management perspective, I need to monitor developers. That means that they commit often to a global repository so that I can review and give them the guidance they need as well as monitor progress, in particular to help them if they get stuck in a quagmire. From a close-knit team sync perspective we avoid a lot less collisions being able to see quickly what is going on. There’s no benefit from suspecting contributions or encouraging it. They are assigned tasks and expected to finish and in the rare case they turn out to be a lost cause we simply svn delete the attempts. In this case we have completely the opposite requirement that managing an open source project has. We share frequently, even if something is incomplete and svn makes this much easier as it is the default way to work. We have little need to inhibit developers when it comes to sharing.
    * We need centralisation to manage and keep track of everything. It is both easy and cheap to set up a fast server with regular backup. If it is to be believe that git solved all backup issues then that might save us about 50 pence. When it comes to serious business, although git does have a fairly good chance of causing your repo to be backed up to a good extent by default, I would rather rely on a common place cheap yet reliable and guaranteed means of backup. This also comes at a cost for a large codebase because fetching the entirety of it to checkout is not cheap. Additionally git may encourage practices that result in more loss in failure. For example, a developer is given a large feature to work on. They branch and work on it for a day committing locally. Memory corruption (or any failure) breaks their repo and and they did not push remotely. It should be argued that the policy should prevent this from happening but git does not help much by making the whole procedure more complex. Distribution complicates the situation in general (who has what, where to push to share, etc). It adds an unnecessary element of flexibility and choice where none is needed. This can only result in chaos. There is no benefit in on developer being able to share with another and not the whole group.

    I could add many more things but that should be enough. So, git just does not work out for me. It has a number of qualities that were added to deal with problems that I don’t have and those qualities are not innocuous. They tend to get in the way of things and impose some burden. I receive all the overhead but none of the benefit. With SVN all I get all the time is head and every man likes a bit of that. I think there’s a pretty solid consensus here that git is more complex. The question that leaves is does that complexity always pay? The answer from me is no, it does not.

    I would use git without question if hosting an open source project where I want plenty of contributions and it would be stupid to use something like SVN for that but for a small internal team it makes no sense to me to use git either, given the right circumstances it would also be equally stupid to use git for such an endeavor.

    I receive a lot of attitude from people who don’t really understand varying situations and crossover from the opensource world is not new. For example, I do not use database abstraction layers that offer portability too much. In the commercial world we often have the luxury of control over environments and the number of times I have had to change database for a large product is so infrequent that on probability portability wont pay for its self and has no value in actuality. Many people say these things are free but in reality very few things really are. When making a product to run on random machines portability might make sense. For an open source project it makes a lot more sense. For me it is like getting insurance when I buy a new phone. The chances of me breaking it are so small that after a while I will spend more money on insurance than on replacement phones.

    • Ewout February 25, 2015 at 7:31 pm

      You are quite right ! I fully subscribe to your analysis. For the majority of closed source (commercial) projects Git only offers headaches and solutions to non-existent problems. I use SVN in a commercial project and others (not Linux hacker types, but creative and artistic people) can easily use it, they are productive and are not hampered by the tool. I would never expose them to Git’s model, it would slow down everybody.
      Also, as opposed to all the comments here that state that Git has become the standard VCS in open-source land, there are still very siginificant projects that use centralised VCS such as SVN. One project I know very well is the FreeBSD prjoject which uses SVN for code distribution and control. Perhaps Git and SVN can be seen as the exponents of Linux and FreeBSD – anarchy vs controlled. One only has to look at the rubbish heap that is the Linux kernel source code and compare it to the clean and orderly FreeBSD kernel source code to better understand the differences between Git and other VCS tools.

  247. Max Weber January 30, 2015 at 2:22 am

    $ git push origin HEAD

    hint: Updates were rejected because the tip of your current branch is behind
    hint: its remote counterpart. Integrate the remote changes (e.g.
    hint: ‘git pull …’) before pushing again.

    So, try it:
    git fetch origin devbranch
    git merge FETCH_HEAD
    $ git merge FETCH_HEAD
    Already up-to-date.
    Also tried git fetch issue_branch
    WTH. So, my local branch cannot be behind its remote counterpart as I just had checkout from there 15 minutes ago before I made this change! The message is bullsgit. Who wrote this git?

  248. Richard Cross February 11, 2015 at 5:37 am

    3 years on, and I feel Git’s documentation has improved massively, both on the official website and at the command line. Additionally, there are dozens of very easy tutorials to get you into the Git mindset, of which this is my favourite: https://try.github.io

    • steveko February 11, 2015 at 10:58 am

      I wish I could agree, but I haven’t seen many changes in the command line documentation or man pages. The website is better, but that doesn’t count for much; there have been dozens of good tutorials around for ages.

      My complaint is not simply that Git is hard to *learn*, it’s hard to *use*. Years on, I still constantly have to consult documentation because it’s not intuitive, and I frequently get into messes that are hard to fix.

  249. Mike February 18, 2015 at 10:41 am

    3 years on. .. Why doesn’t git have the equivalent of:
    [svn add]
    svn commit

    It’s really all I want to do..

    • steveko February 18, 2015 at 10:50 am

      git add -A is basically the same as svn add, isn’t it?

      • karlyeurl November 3, 2016 at 10:05 pm

        Incorrect. `git add .` is roughly the same than `svn status | grep “?” | sed “s/^.* /svn add /” | bash`.

        `git add -A` is the same than `svn status | grep “?” | sed “s/^.* /svn add /” | bash && svn status | grep “!” | sed “s/^.* /svn rm /” | bash`

  250. J (@Jedd_Ahyoung) February 19, 2015 at 7:07 pm

    Well, it’s almost exactly three years later, and I feel that things have gotten a lot better. However, I think that a lot of these weren’t arguments in the first place.

    #1 – Any version control system will come with some learning curve. If you’d learned Git first, you’d be complaining about Subversion. It’s just the nature of learning a new tool. Can it suck? Sure, but that’s something you have to deal with any time you learn a new tool.

    #2 – The commands aren’t standard with Subversion. That doesn’t mean they’re necessarily bad. I will agree that some things in Git don’t make that much sense, but again – if you’re coming from an SVN background, you’re going to be a little biased in what you expect. Try hg and then migrate to git. This really goes hand-in-hand with #1 – there’s a learning curve, and that is expected.

    #3 – Yeah, I agree. Man pages suck. That’s not just a git thing, though – that’s just man pages in general. Man pages are designed for a developer audience due to the nature of the UNIX environment. That said, documentation has gotten better in the last three years.

    #4 – This may depend on your usage. Most of the time, you’ll be adding, committing, and pushing. If you’re working in a shared repo, you might be pushing, pulling, and merging (and possibly rebasing depending on what you’re doing). Although I’m sure there are corner cases, I haven’t seen any in my regular usage. Not to say there aren’t any, but this may have stabilized over time.

    #5 – This may have gotten much better over time, or you may be trying to do things that I have never attempted. Quite honestly, for tasks like these (even with other VCSes) I will Google the answer. I suppose that if you are working without an internet connection, this may apply.

    #6 – I think GitHub has solved whatever this is?

    #7 – Git can mutate history, yes. This is stated up front and as such is an expectation. Mercurial provides this functionality via plugins as well. This is a feature.

    #8 – I think that this conflicts with #6, but again – GitHub solves this. If you wanted to do this without a server model (like GitHub provides), you still update and commit – update and commit. It’s the maintainer’s job to pull in nonlocal branches, so this is a nonargument.

    #9 – git reflog.

    #10 – The paradigm has changed – you’re using a non-DVCS workflow in a DVCS. You don’t need to push with every commit. Finish your local work, push, and then submit a pull request. It does take a bit of getting used to, but I personally think it’s much nicer than everyone committing to one server branch (and dealing with diff bombs when you don’t check in for a little while).

    Again – three years late, and I know there have been a lot of responses to this – but I hope that people in 2015 are able to read this article, along with the comments, and realize that the paradigm has changed, not just the tools. I hope that all of these “problems” will be nonissues for current and new adopters. I don’t want to sound like a Git fanboy, but DVCSes are the future – they are the now, really – and progress doesn’t like to go backwards.

    Happy DVCSing!

    • steveko February 26, 2015 at 9:44 am

      Three years on, it’s been a very long time since I’ve touched Subversion, and yet I still find Git unintuitive, hard to learn, and frequently have to consult help pages. So, it really, honestly, genuinely, is not a question of just being “what I’m used to”. I’ve now spent far too time using Git than I ever spent with Subversion.

      >#3 – Yeah, I agree. Man pages suck. That’s not just a git thing, though – that’s just man pages in general. Man pages are designed for a developer audience due to the nature of the UNIX environment. That said, documentation has gotten better in the last three years.

      IMHO, Git man pages are much more cryptic than average. Any examples of documentation that has “gotten better”?

      >#4 – This may depend on your usage. Most of the time, you’ll be adding, committing, and pushing. If you’re working in a shared repo, you might be pushing, pulling, and merging (and possibly rebasing depending on what you’re doing). Although I’m sure there are corner cases, I haven’t seen any in my regular usage. Not to say there aren’t any, but this may have stabilized over time.

      If you’re working solo, yeah, life is trivial. The rest of the time, you’re very likely to be making branches, rearranging them, reconstructing history – and it all gets very messy.

      > #5 – This may have gotten much better over time, or you may be trying to do things that I have never attempted. Quite honestly, for tasks like these (even with other VCSes) I will Google the answer. I suppose that if you are working without an internet connection, this may apply.

      Yep, I “Google the answer”, too. That’s the problem, not the solution.

      > #6 – I think GitHub has solved whatever this is?

      No, not really. It does make managing pull requests much more enjoyable though.

      > #7 – Git can mutate history, yes. This is stated up front and as such is an expectation. Mercurial provides this functionality via plugins as well. This is a feature.

      Calling it “a feature” doesn’t make it a good one :)

      > #10 – The paradigm has changed – you’re using a non-DVCS workflow in a DVCS. You don’t need to push with every commit.

      I find that makes life more confusing. I prefer work to be in one of two states: uncommitted, or committed and pushed. Adding a third state (committed but not pushed) is complexity with no benefit.

  251. Thunderbird March 3, 2015 at 1:30 am

    There is also a very nice and factual blog article by Benjamin Pollack describing the shortcomings of DVCS in general and Git in particular:

    http://bitquabit.com/post/unorthodocs-abandon-your-dvcs-and-return-to-sanity/

    • rademi March 3, 2015 at 10:06 am

      That blog article does hit on some interesting points. But I think he has missed the biggest issue, which is perhaps best summed up by this Alan Perlis epigram: “Dealing with failure is easy: Work hard to improve. Success is also easy to handle: You’ve solved the wrong problem. Work hard to improve.”

    • sfkleach March 3, 2015 at 8:23 pm

      Nothing could drag me back to Subversion, having broken free of it with git. What a breath of fresh air it was and remains every day. Firstly, the use case that Pollack dismisses, which is poor connectivity to the central store is my daily reality. If you need a network connection to use version control, it’s not a viable solution. Secondly, Subversion enforces the madness of maintaining branches in the folder hierarchy; this forces a damaging centralising decision over the folders structure for branches, which has not been done wisely, historically. Thirdly, Subversion lacks the notion of working privately under version control – so you have to do a dance with public versions that are organised by convention to be private – making the workflow more complicated for no real reason.

      Pollack’s best point is the issue of storing large objects. We work in GIS and we need large objects to be versioned. One issue he doesn’t mention is the file size limit. Git has a file size limit of 2GB – so does Mercurial and (in practice) I found Subversion had a different but equally impractical limit. 2GB in GIS work is not a large file. So in reality we fall back on manual version control – which is really unsatisfactory.

      The issue of large repositories that grow with history is an interesting issue – although his examples of 333MB or 1GB made me laugh, as that really seems quite small these days. But combined with large object store, it is a show stopper.

      [It’s not difficult to design a solution to this – and git-annex is clearly not the way forward as Pollack rightly asserts. In essence, the answer is that BLOBs should be managed with a deferred download status. When you clone a repository, some files don’t get locally copied but deferred and the ‘shadow-copy’ that appears on the disk is a proxy for the remote file.]

      Is git a good version control system? No. But Subversion is not a viable alternative and git/Mercurial is the best we have got right now. Personally I believe that a much better way to organise version control is around the idea of a virtual file system rather than a system sitting on top of a conventional filing system (and if anyone wants to learn more, nudge me – I am on a promise to write an article on it anyway.)

      • Steve Bennett (@stevage1) March 3, 2015 at 11:19 pm

        >If you need a network connection to use version control, it’s not a viable solution.

        I agree – this is a must. But personally I could really do without all the manual pushing, pulling and fetching. At the very least, Git could have a constant background fetch process so that at least origin/master always represents the current state of the remote branch, not just the last time you manually synced it.

        >Secondly, Subversion enforces the madness of maintaining branches in the folder hierarchy;

        Yeah, that *sucked*.

        >Thirdly, Subversion lacks the notion of working privately under version control

        This is definitely much better under Git. It would be hard to go back.

        >Is git a good version control system? No. But Subversion is not a viable alternative and git/Mercurial is the best we have got right now.

        What bothers me more than anything is how little Git has improved in the last few years. It went through a rapid development process, then stabilised in a not very good state. If it was “the best we have got right now, but it will get much better soon”, that would be fine – but it’s really not improving significantly.

  252. Paul Johnson March 3, 2015 at 3:10 pm

    Well done

    For our shop, the biggest Git danger is that a user Googles for help, finds some detailed code from a Russian teenager posted in a pirate forum. A few forces, merges, branches, and other efforts folow, and before we know what happened, that person can’t interact with the team anymore and we have to erase the whole repo to start fresh.

    Still, seems there’s no realistic alternative. Subversion is quite nice, but so limiting.

    • arnebab March 4, 2015 at 7:15 am

      Did you try Mercurial?

      • Thunderbird March 4, 2015 at 8:22 pm

        … whose “Definitive Guide” has not been updated in six years???

      • Arne Babenhauserheide March 5, 2015 at 1:40 am

        if you mean the official guide ( http://mercurial.selenic.com/guide ): It did not change much, because it needs to keep working for university clusters and such which ship you an age-old version of anything. And the old way still works well. Mostly it got some footnotes how never versions make it easier to do some stuff.

        If you mean the book: Well, it’s a book, and not maintained by the project itself. Its author nowadays mostly blogs about Haskell. Most information in the book is still valid, though, because the core design of Mercurial proved to be good enough to withstand the test of time.

      • Thunderbird March 7, 2015 at 6:31 am

        Yes, I meant the book. I think that Mercurial is way better than Git, mostly due to its proper accounting also for Windows and its much better command-line user interface.

        But I was used to Subversion’s documentation, which is from a user’s perspective very convenient: one single main book, well written, complete, useful as intro and reference, and usually up-to-date.

        Mercurial’s 2009 book is what keeps me off of it, as it seems that such an old book cannot be a good resource to learn and use a modern and rapidly evolving software. If fact, there is a danger (even if only felt and not real) of learning things, best practices and workflows long outdated. So the book is out, and I’m forced to learn about Mercurial from fragments scattered over the internet. And that unfortunately leaves me in a situation that is, as much as it pains me saying it, worse than with Git.

  253. Bennett Haselton Fan March 5, 2015 at 1:47 am

    He is a frequent slashdot contributor!

  254. Raju Bakthavatsalu March 11, 2015 at 10:31 am

    More than my project I had to work more on Git to understand to get things done.

  255. Neon Warge April 10, 2015 at 3:59 am

    I cannot say I am an expert on Git. I have personal projects and I find Git the best solution for me to keep track of the things I did on the source and keep versions of them.

    But this is unbelievable, during the time of this writing, the code I wrote for months was not tracked by Egit. I am losing my mind since I am doing an android project and wrote myself a content providers and done so many refactoring. I kept on pressing commit and push and none of the new files I created weren’t included in the branch. What the fuck is this? I have not encountered this anywhere else on my other projects. I am in a situation where I have deleted my original files confidently believing that it was tracked and I have my versions backed up. But that wasn’t the case. I am starting to hate this whole shebangs all together.

    Now I need to go back to read a voluminous read-this-all-to-become-a-technological-GIT-GOD and undergo 4 year course understanding Git just to make sure this won’t happen again.

    So far, I am still inclined to use git no matter what, but the gotchas using this technology is very costly. So I warn beginners using this.

    • sfkleach April 11, 2015 at 2:28 am

      @Neon, sorry to hear that you’ve ended up in this situation. Speaking as someone who has been using IDEs for over thirty years, I am not a fan of using integrated source-control tools like Egit for exactly this kind of reason. My guess is the problem does not lie with git but more likely some issue with Egit. I think it is fair to say that sooner-or-later every single integrated source-control tool I have ever used has broken in the kind of way you describe.

      My recommendation is that you use a dedicated source control tool. My favourite is SmartGit (http://www.syntevo.com/smartgit/) but Atlassian’s SourceTree looks pretty nice too. I use SmartGit on a daily basis with Eclipse, Visual Studio and Sublime and it works just the way I want, cleanly separating code development from version management. The only IDE that struggles with file being modified under its feet this is VC6, which I am obliged to use to maintain some ancient legacy code, and even that isn’t a big deal.

      Since I switched to this way of working I have found my workflow significantly smoother as well as more flexible and powerful. I no longer find myself having to disentangle the IDEs bizarre decisions and incorrect reporting using a hopelessly inadequate interface.

      Just my opinion – and your mileage may vary – but it works for me & may work better for you.

  256. Max Weber April 18, 2015 at 4:54 am

    Oh boy, just hit a few more. Forgot the one from yesterday night but today realized doing a “merge” on the Stash website does not actually merge!!!! What the HELL! Had
    epic->A->B->C
    Merged C to B.
    Then merged B to A.
    Then merged A to epic.
    Guess what!! the B and C work is not present in epic. Each has to be merged directly. What the hell. (Stash is Atlassian’s git server. I assume github and others operate the same, equally bad.)
    git – sht that works sometimes and breaks in almost ALL non-happy path cases. But, did we mention it lets one dude lord it over everyone else? :-) Maybe its just a Stash problem.
    (It might be the merge worked but someone over-wrote with old code. Well, the “history” doesn’t reflect the merge having worked.) BTW, there’s a third one. When reviewing history in Android Studio I don’t see any branch info. That sucks. Shows me the date the file was created and that is all. But I know it was created in another branch. And merged, twice. When looking at the history of another file I see similar… shows the date of the change but not the fact it was on another branch. maybe its just Andorid Studio.

    • Max Weber April 24, 2015 at 2:08 am

      Note those are really about Stash and about Developer Studio, two GUI’s atop git; so, not exactly about git. Also, note the merge issue was with the Stash button called “merge” and not executing the command to git from command line.

  257. R N April 23, 2015 at 9:52 pm

    Use recycle bin for local version system: delete a file just before saving it again, and you can always “restore” previous versions from the recycle bin.. ;)

    • rademi April 23, 2015 at 10:50 pm

      @eevee on twitter:

      git people trying to use hg: “WHY WON’T IT LET ME DO THIS”
      hg people trying to use git: “WHY DID IT LET ME DO THAT”

      • arnebab April 24, 2015 at 11:09 pm

        With one main difference: The answer.

        – git people trying to use hg: “WHY WON’T IT LET ME DO THIS” ⇒ hg people answer: “just activate extension X when you really need it”

        – hg people trying to use git: “WHY DID IT LET ME DO THAT” ⇒ git people answer: “that’s how DVCS has to be”

      • arnebab April 24, 2015 at 11:11 pm

        though hg people are more likely to say: “why did that happen? I wanted to do this!”

  258. Max Weber April 24, 2015 at 2:10 am

    OK. So here is one of the top 10 things I hate about git. Having used it over a year now and used it on a medium large project, here we are at the rapid fire phase of the project where we are making changes left and right. GIT is an ABSOLUTE mess for this style of development. Things are constantly out of sync. Changes are hung up in the PR (code review) process so other changes miss them. GIT is simply an absolute mess to try to use for teamwork on a large project because the style of use is lots of branches. Its perfectly find probably for small effort projects where each effort can be one Agile task and is orthogonal to other efforts; and, clearly, this is probably what most teams are doing these days.

  259. Baagad Billa April 29, 2015 at 10:09 pm

    +1

    All I want is to concentrate on my development, and dump the code into a repository. I do not want to waste time “learning” another VCS.

    What is the need for a local repository (which everyone says is an advantage). I dont need one. Unless I push the code changes to a remote, no other developer gets my changes. So why ?

    It was so easy with SVN where my local folder structure would mirror the SVN structure, branches and all. In case of merge conflicts, I had scripts backup my changes, override and update. Then I would manually merge back my changes from the backup.

    • sfkleach April 30, 2015 at 4:58 pm

      Let’s state the obvious: if you do not need a local repository, then there’s no advantage in it for you. By contrast, I am often in places with no internet connection and it is great to still be working under version control. Also, when I am doing work on a several connected features, I like to work with local private branches so my colleagues aren’t exposed to the minute details of how I am putting the changes together.

      As for SVN making your local folder structure mirror the central structure, git does the same – at least the way I am using it – so I don’t follow the point you’re making here.

      • Baagad Billa May 6, 2015 at 12:21 am

        >> By contrast, I am often in places with no internet connection and it is great to still be working under version control.

        I may not have internet for a few hours. After that I need internet connection to share the code. For me, no internet connection = no version control.

        >> As for SVN making your local folder structure mirror the central structure, git does the same – at least the way I am using it – so I don’t follow the point you’re making here.

        I do not say git checkout branchname to switch branches when using SVN. https://svnrepo.mycompany.com/branchOne/src/main/java and https://svnrepo.mycompany.com/branchTwo/src/main/java are on separate folders on hard disk.
        I avoid all that headache of stash and local repos and remote repos. I have a simple view of things. My changes on local versus others’ changes on SVN repository.

  260. Ramesh, Chennai April 30, 2015 at 7:53 pm

    Very good analysis on git software. It should be made even simpler form user perspective and useless commands/duplicates should be removed. I enjoyed a lot especially “Keep using Git, and more concepts will occasionally drop out of the sky: refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces”

  261. Baagad Billa May 6, 2015 at 2:57 am

    I reached this page by googling “git sucks” after a year of struggling with it. This page is one of the top results.

    If a tool involves a much higher learning curve for the benefits of what it offers, I believe it loses in the cost benefit analysis. It is not that I am slow to pick up things. I have to pick up a new framework almost every six months. IMHO, there are many more exciting things I should be spending my time learning, rather than git. I do not see the need to be a git expert.

    Resolving merge conflicts is a pain. With a good SVN Eclipse plugin like Subclipse or Subversive, I can simply see where there are conflicts. In case of merge conflicts, simply save my changes into another location (I had shell scripts for that). Right click and select “Override and update”. Apply my changes from the previous copy at another location. Done. Simple. I have been told that this is inefficient. Maybe it is, but it works well for me. Git may be good at automatically merging – but the day it messes up the merge, it takes away all the time I had saved.

    If I want to create a branch for my development, I can have that in SVN too. The branch will not be private, but it is still my branch for my experiments. If I need a local repository when I am offline, I would rather generate tarballs after each signficant milestone.

    Git is fast – I accept this and count this as a major plus.

    • sfkleach May 6, 2015 at 4:09 am

      If Subversion works for you, that’s lovely. And I agree that the command-line git learning curve is absurdly steep. Which is why I recommend using SmartGit (or SourceTree). These tools make git very approachable indeed.

      Once you have given a tool like SmartGit a go, you might find the cost-benefit suddenly tilts very hard in git’s favour: you can work under full version control without a connection to the repo, you can branch and merge fluidly without worrying your co-workers will go insane or you’ll fill up the server, you can work on your project without having some dodgy plug-in, you’ll not have to suffer said plug-in get desperately confused when you move a folder without saying ‘simple simon said’ first, you’ll be delighted by the speed (as you said), be relived by one-click cleanup and you’ll enjoy not having your folder hierarchy polluted with hundreds of .svn files,

      Subversion was the very first VC system I regarded as usable. It was bulletproof and effective. I loved it. But, now, those days seem dreadfully quaint. I will never swap back to working in such an antiquated fashion, it would make no more sense than starting to program in assembler. It’s not that assembler is “bad”, it is merely that the situations where it out-competes higher level languages are few and far between. Much the same is true of SVN and git.

      • Baagad Billa May 7, 2015 at 1:09 am

        I have tried sourceTree earlier in one of my projects. And I use GitExtensions personally. It did not make anything simpler.

        I agree that SVN isnt perfect either. Maybe we all are still waiting for the perfect versioning system. I have not tried out any of the commercial tools like perforce or Team foundation though.

      • sfkleach July 25, 2015 at 4:18 am

        Do try SmartGit/Hg. It’s my tool of choice. SourceTree is free but I find SmartGit/Hg simpler and cleaner.

      • Max Weber August 14, 2015 at 12:08 am

        “Subversion was the very first VC system I regarded as usable.” Honestly? Perforce (commercial product) is close to identical to SVN except the merge tool in Perforce sucks. There have been good source control systems around for decades. Git is just a complex mess designed for two special use cases:
        1. guy wants to develop locally and keep versioning without installing server software on his/her computer
        2. MAINTAINER wants to lord it over anyone else contributing to that tree in Linux and enforce that all changes are really to be made by him/her.
        Amazingly, people created Windows, Unix, and most all other major software before git was even dreamt. And they certainly used source control systems. Of course the systems costed north of $100k 25 years ago; but they did work. I guess the big brain break-through then was being able to to intra-file merges automatically. Well, git still sucks for that. Sucks big time. You’ll end up doing lots of those manually.

      • arnebab August 14, 2015 at 7:40 am

        I didn’t think I’d defend Git here, but it wins clearly on quickly starting a small project and on projects surviving the disappearance of its maintainer.

        And it is Free Software. That’s a huge enabler for many people. I clearly prefer Mercurial over Git, but even the difference in barrier to usage of complex, inconsistent Git compared to Subversion or any commercial product is striking.

        People created high quality software by keeping backups as directory copies and exchanging plain diffs. Libre, decentralized version control just removes a lot of the error-prone manual steps in that.

  262. arrosado May 23, 2015 at 1:12 am

    Stop making critics and come up with a good solution. Post it and see if you get as many votes. I think git has provided a fair solution to many SVN/CVS/TFS/Perforce/RC problems. Bright minds don’t only see needs or defects, they also come up with solutions. What are your recommendations on simplifying the fundamental problems of source control? Please advice.

    • arnebab May 23, 2015 at 7:15 am

      In the update (August 3, 2012) at the end of the article, Steve wrote a solution:

      > 5. “Use Mercurial instead!” Sure, if you’re the lucky person who gets to choose the VCS used by your project.

      The problems aren’t as fundamental as the git UI makes you think.

      Mercurial also has its issues, but instead of still trying to fix Git after 3 years of failed tries since this article was written, let’s curtail the losses and fix Mercurial together.

  263. derhexer June 6, 2015 at 5:05 am

    You are right! I’,m using version control as backup and for “what have i done and maybe get it back”… (single developer)
    git is different in my case sometimes more complex, so i’m using svn with a notebook server working with visual svn linked to nas. It works, is easy to use… that’s what i want.
    I will never store my source on cloud anywhere (also not at github), why should i? My source resist at my ipfire shielded home… nowhere else…

  264. StevieWander June 16, 2015 at 9:50 pm

    This article is so accurate, however I think it is missing the biggest problem with Git – IDE support (have you tried EGit? Just search on StackOverflow).

    I don’t want to hack a perl script from a file editor. No, I want to have access to diagrams, integrated test tools, user story correlation tools and search tools whilst I develop to make sure I do it right as quickly as possible. You need an IDE for that.

    For us that write proper industrial-strength software for a living, I would suggest the tools required to use Git do not yet exist, so stick to SVN.

    • rademi June 17, 2015 at 11:36 am

      Yeah, it’s really nice when you can just sleep because someone else is doing all the work for you.

      I guess the point is that none of this stuff is really necessary. What you need to get something done is a willingness to invest the effort. If you don’t have the will, none of the bells and whistles help the slightest bit. Fortunately, at this point there are millions and millions of programmers. So 80% of them can just whine and complain and the remaining 20% can still get a lot done.

      (I actually have nothing against SVN, … nor against Mercurial, … nor against Git. I think they each have roles where they are best suited. But I *do* have a problem with the social thing where people overgeneralize these kinds of issues. If you’re bored there’s plenty of problems which need to be solved.)

      • StevieWander June 17, 2015 at 9:22 pm

        Assuming you write software for a living as opposed to bedroom coding (is that why you are focussing on sleeping?), then maybe you ought to think about what you are being paid to do: Write Software. Not administer a version control system.

        Then again some of us programmers are not blessed with the ability to focus on what matters…. maybe 20%?

        “What you need to get something done is a willingness to invest the effort”

        Sorry, I forgot to mention that I am not training for an ironman triathlon, I am trying to write good software quickly, which is what I was doing before I was told to use Git.

        “problem […] where people overgeneralize these kinds of issues”

        OK, let me be even less general…. I am trying to assert that when you are working on a large, complex product in a demanding environment, e.g. you have a browser client, a server with hardware access, and maintain a multitude of services for many diverse clients – which is what I meant by “industrial strength software” – it is difficult to do it well without a good IDE. From my experience one can’t have that and Git at the moment.

      • rademi June 18, 2015 at 12:02 am

        I have worked with IDEs and without. My best work was done without – but I don’t find it difficult to get work done in either way.

        But frankly at this point, I have mostly ceased to care – largely because I have begun to recognize that no one else cares, either. They’ll offer strong opinions, mostly about stuff that doesn’t matter.

        However… since you sort of asked: I write software because it pleases me and I enjoy that. But I don’t get paid to write software. I get paid to solve problems and to help other people get their jobs done.

  265. Pingback: Git repo created | Cognitive Dissonance

  266. Daniel Sokolowski July 14, 2015 at 12:38 am

    I agree with this article. To use GIT safely you simply must learn it inside out to avoid screw ups and that is something I do not want to waste my time on but must.

    Can anyone comment if Mercurial has less ways to ‘shoot yourself in the foot’ ? I understand the history is immutable.

  267. Alexander July 14, 2015 at 11:56 pm

    So why not using aliases for git commands, if you like writing less text so much?

  268. Santiago July 16, 2015 at 7:37 am

    I just want to say, that when I use SVN and commit my changes to my branch in the remote repository; if my hard drive goes bad, nothing is lost.
    If GIT is local and my hard drive goes wrong, I lost all my job.

    • Daniel Sokolowski July 18, 2015 at 12:11 am

      Or your co-worker forgets to ‘push’ and just commits locally.

      • sfkleach July 18, 2015 at 3:46 am

        I think the point that @Daniel is making is that git has a marginally more complex model of code submission, as it distinguishes local check-in (commit) from shared check-in (push), whereas subversion only has shared check-in. However, this does not eliminate the need for a version that is local/private to a developer and, if you are working in subversion, you typically end up simulating this through branches that the team agree are private to developers. Having worked in both situations, the git solution is better in every respect. So, for a marginal increase in complexity, you get a tidier shared workspace, an improved workflow, plus the ability to work offline with no loss of functionality.

        Although there are plenty of valid criticisms one can make against git, this is not one of them.

    • sfkleach July 18, 2015 at 3:36 am

      This is a particularly weak point, confusing version control with back-up. SVN can be used locally and the same issue arises. We have >100 SVN repositories used in this way. Our solution is to back-up our drives.

      • Daniel Sokolowski July 18, 2015 at 11:58 am

        I think GIT is at best it’s moderately more complex. GIT gives you too much ability to shot your self in the foot. Fast forward `–force` push anyone – at lest Mercurial got this part right by making history immutable.

        The more I learn GIT the less elegant it gets – but I do recognize it could be just a case of grass is greener on the other side.

      • Santiago July 18, 2015 at 3:35 pm

        Normally, no one will use SVN locally: the point of using SVN is to have the code secure in a different location – again, normally a more secure location than your local hard drive. If someone uses SVN locally, by definition is doing something risky, and sometimes, just wrong.
        Backing up the drives is a lot more complex than having a SVN central repository in a secure place and do a click to perform the commit.
        So I don’t think that this is a weak point: is just the way that SVN works, and the way that GIT works. Obviously, this GIT “weakness” can be compensated easily (and without the need of backing up hard drives): just ask to GIT users to Push their work more often.

      • sfkleach July 18, 2015 at 4:37 pm

        @Santiago: “the point of using SVN is to have the code secure in a different location” – this gives a high priority to an incidental benefit. Surely the main point of using SVN is to control the evolution of code. The fact that it can be a low-tech recovery strategy may be, I agree, a benefit for solo developers if they haven’t got a backup strategy sorted out – which can be relevant while you are a student, for example. But you can’t use it exclusively as a disaster recovery solution and, unlike thirty years ago, there are so many really good “zero-config” solutions. I use Apple’s superb Time Machine for my personal work and my company uses a well-known distributed backup solution.

      • sleary78 August 25, 2015 at 5:31 pm

        I think there is a general confusion with the term backup here. I’d like to split that into History and Disaster Recovery. When talking about DR you are absolutely correct. This is something that needs handled by some other means than a VCS. GIT acts like a time machine in that it can change history. This is something i fundamentally disagree with. A VCS should be able to give you the code as it was at any point in its history. History is essential to version control. I dont accept the “thats why you tag” argument.

        Its essential to be able to audit/account everything that ever happened in your VCS.

    • Jan Stoker July 20, 2015 at 3:11 pm

      On the other hand, if the server goes dead, at least with git you still have a local copy of everything. Less relevant in a corporate setting, but for open source it can be a lifesaver.

      • arnebab July 20, 2015 at 5:52 pm

        You have a local copy of many things, but most likely not the branches of you co-workers. That’s my main qualm with the very private branching system in Git: People forget pushing, or forget to push the relevant branch, or they only push to their clone and don’t file a pull-request, and so on. Then they close their Github Account and all their work on the project is lost – as in permanently lost.

      • Santiago July 21, 2015 at 1:55 pm

        Jan, I have more than 10 years working in IT, and I have never see a server goes dead and lost the repository. It may happen: yes; but it’s easier to lost a HD in a desktop or in a laptop that a corporative server.

  269. Daniel Sokolowski July 18, 2015 at 12:15 am

    Am I wrong to think of ‘Pull requests’ as a mechanism to bring some centralization back to GIT? The problem with them is they are part of the hosting provider not the control system.

    • arnebab July 18, 2015 at 5:41 am

      You’re right with that. This meant for example, that it was necessary for workable interaction with scheme requests for implementation to provide alternate workflows. See http://permalink.gmane.org/gmane.lisp.scheme.srfi.announce/120

      • witiko92 August 11, 2015 at 8:29 pm

        Pull requests are not a feature of Git, but rather of GitHub, which is a Git hosting service with additional features thrown in. In Git, there is no mechanism for issuing pull requests, although you can generate a pull request e-mail via the `git-request-pull` and then manually send it to the upstream maintainer.

    • witiko92 August 11, 2015 at 8:30 pm

      Pull requests are not a feature of Git, but rather of GitHub, which is a Git hosting service with additional features thrown in. In Git, there is no mechanism for issuing pull requests, although you can generate a pull request e-mail via the `git-request-pull` and then manually send it to the upstream maintainer.

    • Max Weber August 13, 2015 at 11:57 pm

      You are right. git pull is the ubiquitous way to merge in changes from other trees, basically from the central repo. You could do merge and stuff to effect bringing down the code if you don’t like the word “pull”

  270. Santiago July 18, 2015 at 3:22 pm

    sfkleach: Since SVN was created before GIT, I would not say that Subversion is “simulating” a private version of the code. Is in fact, giving to the developer a private version of the code.
    However, after have compared both tools, I couldn’t find a real benefit of using one over another; as usual, the best tool is the one that works better for your project.
    In my specific case, I always work online and I don’t have the need of working offline. Also, I prefer to do only 1 click to perform a commit and know that the code is secure in my branch, that give 2 clicks.
    Could you please tell me more about “tidier shared workspace” and “improved workflow”, I’m very interested in this subject.
    Thank you.

  271. wideeyedpupil July 20, 2015 at 5:04 pm

    So i’ve had a couple of attempts using online learning to get into GitHub and without a workgroup around me using it just end up giving it away. I’m the opposite of an expert although no a bit about UI/UX as a designer and can’t agree more. I still like the idea of learning GitHub because it’s become ubiquitous in open source world but the learning curve has steep early steps. I can understand why pro-devs don’t care, they don’t have to sell Git to anyone at all.

  272. Max Weber August 14, 2015 at 12:01 am

    Oh shgit. More git shgit.
    So, disk was getting low on space. What does git do? It totally shgits itself. Your GUID references become all fubar and git cannot recover. Couple of SO’s on it.
    http://stackoverflow.com/questions/18480174/git-stash-fails-error-unable-to-resolve-reference-refs-stash-no-such-file-or/19409320#19409320
    http://stackoverflow.com/questions/20663239/git-pull-fails-error-refs-stash-does-not-point-to-a-valid-object
    In their case they were LUCKY. Git only messed up the stash references. In my case, git messed up the references back to head. I’ll have to re-clone and resetup. Another day wasted due to using git instead of a solid source control system (NEVER, EVER, EVER, EVER have seen such shgit with SVN, Perforce, or any other of a 1/2 dozen source control systems I have used heavily.) Out of disk space is a computer programming problem. Instead of just shoving shgit together the GIT programmers should have properly handled that error case. (I am running Android Studio; so, one might argue the bug is in that.) GIT? SNAFU.

  273. sleary78 August 23, 2015 at 8:02 am

    I used to contribute to a few open source projects. Since the demise of google code and being forced over to git i don’t bother anymore. When the source control system is more complicated than the coding you’re doing you have a problem. Yes you could make the argument that I’ve not tried hard enough to learn/understand git but for me VCS shouldnt need a Ph.D to understand (which i have ironically). And it should never, never, ever lose data.

    I get the problem its trying to solve but for me its like using a Saturn V rocket to go buy milk down the street.

    • sfkleach August 24, 2015 at 4:36 pm

      I can understand that. As I have several times in this blog, may I again recommend SmartGit/Hg. It’s free for open source contributors and makes git a pleasure to use; I doubt I would ever have taken to git without it. (As for losing work, all I can say is that every single version control system I have ever used over the past 35 years has lost me work – usually by virtue of entering a confused state from which I could not figure out how to recover. Git has by far the best track record for me and is the most enjoyable to use.)

      • sleary78 August 26, 2015 at 5:39 am

        The SmartGIT stuff looks like a GUI application.. which is again more heavyweight than I want. The operations im performing are simple.. Why isnt the git syntax simple for simple operations and becoming more complex as you require the complexity (probably because it was written by a Kernel programmer).

        I just want to edit, check the edits with a diff tool and then commit my code *directly* to a repository. If I have conflicts then *I* resolve them before committing. The whole pull/push request workflow is too much overhead for me in OS projects and if I cant see the changes hit the CI right away its a risk in commercial ones.

        The other thing that bugs me with GIT is the re-basing stuff which changes history. For me that discards a critical audit trail.

        Git looks like it was based on the idea a set of patches which could be reshuffled (like quilt) but extended to work in a distributed way. In reality it is a distributed patch-set maintenance system not a version control system.

      • sfkleach August 26, 2015 at 8:25 am

        Yes, SmartGIt/Hg is a GUI application, so if you really want a command line tool then it’s not much help. It does nicely support the workflow that you have described, so I do think it is worth taking seriously. To the best of my knowledge no one has tried to put a friendly command-line front-end on git, so I would guess that you are out of luck. I can only recommend switching to Mercurial, which seems like a good alternative with a fairly sensible set of command line options (and you can use it with SmartGit/Hg too, if you ever fancy having a nice GUI tool as well.)

      • Bernd Jendrissek August 26, 2015 at 10:33 pm

        sleary78, your local directory *is* a repository. When you do ‘git commit’, you *are* committing code “directly to a repository”. To get that repository copied somewhere else too (maybe you have co-workers, or you don’t want to lose your work if your house burns down), then you can use ‘git push’ (or ‘git pull’ for the opposite end of that – getting your co-workers’ work). If you don’t have co-workers, you can also simply use rsync or burn a CD or whatever.

        But it does read like you personally see no value in having a local repository (I think you’re mistaken), so you’re probably better off just using SVN instead.

        Nobody forces you to rebase patches. My preference is to never rebase, for similar reasons as you have: it rewrites history, creating historical states that never existed (or were tested in any meaningful way, including merely “does it compile?”) for the sake of “clean history”. I’d rather have merge commits making things “messy” (IMHO they’re easy to ignore) but accurately reflecting the changes that happened – and importantly also *how* those changes got integrated.

        FWIW patches only exist in git’s internals as an optimization – an implementation detail. git’s fundamental concept is the *tree*. Patches only emerge in the (command-based) UI as a *representation* of differences between two trees.

      • sleary78 August 27, 2015 at 6:59 am

        My local repository is not something the CI servers can see and build from. So its not really a repository. Its just a store of my local changes. Which is franky worthless. SVN does this just makes slightly less fuss of it. Its precisely this push/pull request stuff i have an issue with. It should be mandatory not optional.

        I use SVN for my own local work. Since the uptake of GIT by open source projects i no longer have that option so i dont contribute.

  274. Richard Cochrane August 26, 2015 at 8:19 pm

    #7 has an additional little delight (although I can’t knock it too much since it came in handy the other day). If you commit stuff to a repo (like a folder with some JS library like Mathjax and it’s 1000+ files), you can’t simply remove the folder later and make the repo lighter and cleaner – both the file additions and removals will be recorded, even if if this commit was on a feature branch. For this you use:
    git filter-branch -f –tree-filter ‘rm -rf [folder to be deleted” HEAD

    This will go through all of the commits on a given branch and rewrite them with the change, in this case, removing the folder from every single commit. Very useful but if you stuffed it up, you would seriously be destroying your code base. This is followed by a “git push –force” to push this rewrite to the remote repos.

    It’s useful and not necessarily a flaw with git but it is hellishly dangerous!

  275. MyBossLikesShiny October 14, 2015 at 7:01 am

    So many people latch on to whatever the new shiny is in tech/coding and it often ends up being not so shiny.

  276. Michael (@85michi) October 15, 2015 at 7:40 am

    Well, the output of your “useless” “git remote” is ideal to feed it to a for loop to push to all remotes. (for example to update a dot.git repository on all connected machines)

  277. SavageTwinky October 22, 2015 at 1:27 am

    One if your revisions is wrong,

    git checkout file
    Does NOT checkout a file to its committed state. It checks out a file to your index’s state, which could be a combination of committed/added

    git reset file
    will unstage a file

    git reset file –hard
    Will always reset a file to its committed state

    This is probably one of the harder things I’ve had to try to explain to people that a working directory isn’t always your branch HEAD, but also an an INDEX which is like a “commit in progress”

  278. Assarte October 27, 2015 at 10:32 am

    Git is a curse in its every meanings. That’s happening when not an alpha, nor a beta, but an omega-stage (nearly a proof of concept) sotfware hyped over on an entire profession world-wide and nobody stands for say that “guys, it’s looks fine, just make it usable for the future”, most of the professionals swallowed it unhindered and immediately without any practice-based research and experiences, only by fashion. Then this hype started to grow ’til most professionals getting felt themselves too stupid. Noway. It’s just probably the worst documented, most highly over-engineered hype I ever seen in my entire 19+ years long career. Even worst than Symfony 2. There are no people who ever can use it confidently excepted by its developers (if except). I hope that something good-practice will break this hyped dead end as soon as possible. Its simply anti-practical, which regularly harms production, consumes a lot of time and resources without giving anything back which equals that. (for those fellows who would want to name me a moron I should tell: i’m using git more than 3 years over, previously used svn twice time more, previously used cvs – i know what is versioning, what is maintenance, what is revision-management, what are branches, what are tags, etc., these are theories and methods more than softwares which are clearly goods and needs for production-ready software development)

    ps.: when a software reports too many messes, there is a good chance for that those messes probably occurred by the software itself.

    • Alan Wendt March 27, 2016 at 4:08 am

      This is the 9-command script I run to do the equivalent of “p4 sync”, IE merge master changes into my local copy. Except with git, every time I run it I have to resolve the same merge conflicts again. So I’m actually supposed to do something called “rerere”. You can’t make this stuff up.

      currentbranch=`git status | head -1 | awk ‘{print $3}’`
      git add -A
      git commit -m “work”
      git push
      git pull
      git checkout master
      git pull
      git checkout $currentbranch
      git rebase -i origin/master

      • savagetwinky March 28, 2016 at 9:34 am

        What?

        If i read you’re comment right, you’re trying to do a git fetch && git merge origin/master

    • maxweber April 30, 2016 at 2:42 am

      Thanks Assarte. Really brightened my day man. Happy coding.

  279. prof_braino October 27, 2015 at 10:44 pm

    So far git seems to work just fine, better than the other options; the user interface just needs work.

    I think I’m going to list out the contradictions as I find them, and figure out how they should look/work in a sensible manner, and fix them. Of course this will take time, but git is not going away any time soon, and I’m not going away any time soon, and the soon I get started the soon it will get done.

  280. tniles09 October 29, 2015 at 3:44 am

    Would like to see you do a similar article on (exploring) mercurial!

  281. Stashek October 30, 2015 at 9:14 pm

    I don’t mean to offend you, but I think your problem is that you don’t really learned git. Instead, you remembered some commands found on the Internet (stackoverflow maybe?) and hope they do what you want.
    Re “A few bonus command inconsistencies”. The “inconsistency” comes from you not knowing that “git checkout” and “git reset” do different things. I initially wanted to respond to all points, but who cares… ;-)

  282. Git Sucks November 12, 2015 at 8:00 pm

    Git sucks.

  283. Max Weber November 18, 2015 at 12:51 am

    Two years of time wasting with this bulls”git”. Latest retarded bug:
    Commit failed with error:
    pathspec ‘application/libraries/filename.ext’ did not match any file(s) known to git.
    Discussion:
    http://stackoverflow.com/questions/28189880/why-am-i-getting-commit-failed-with-error-pathspec-did-not-match-any-file
    WTH! I can’t rename a file by changing a character from lower case to upper case? I have to rename it to some other name. Commit. Then rename to the desired name? WTH. More “A day in the life of using this git sghit”. I have about 40 files to rename. Let the time wasting begin!

  284. max November 27, 2015 at 3:17 am

    I hate git too;
    and after three years still can’t understood why so much people use such stupid thing if exists good svn and super old ms sourcesafe;

  285. adrianc December 3, 2015 at 8:23 pm

    Interesting to see that the post still receives comments almost 4 years after it has been published :-).

    I think it is useful to look at the problem also from the perspective of what Fred Brooks called essential complexity vs. accidental complexity.

    Some of the complications in the commands and git workflows are inherent to the task is sets itself to solve. Working with a DVCS is inherently more complex than a centralized VCS. Add to that the possibility of having local commits and your local copy acting as a repository and the result will be a more complex interface and workflow.

    The social model of contributors and maintainers is another point of essential complexity or at least complexity that is not imposed by the tool or its interfaces. As someone pointed out before me, the social organization of the project has nothing to do with git itself and cannot be solved by the tool either. Some people complain that git allows such project structures to exist and that is, probably, not an unfair comment. Myself, I lean more toward the school that advocates programmers to take an active role in the code maintenance, so I see value in simplifying the job of the maintainer, even if it means adding to the programming workflow things like rebase or commit squash/edit. rebase could have better interface and documentation, but there is essential complexity in those operations that cannot be hidden by the interface. I agree with your observation that contributors having a more active role in maintaining the code creates a high overhead for casual contributions to a project. I do think that those contributions are important and I do not have an answer on how you can have the best of both worlds.

    On the other end of the spectrum you have also accidental complexity, with git reset and the stash model being prototypical examples. There is nothing essential that requires those to be so messy. The stash, in particular, is a nightmare and I advocate staying away from it to whomever cares to listen. The good thing is that the stash is always a local environment option, so one can live a happy git life without ever touching the stash. I have seen some examples of using the stash in build or deployment scripts, but in those cases I just put on my garlic necklace and refactor the scripts to a non-stash version. I have not yet encountered a case where it would not be possible to do it.

    • steveko December 4, 2015 at 9:53 am

      Insightful post, thanks! I think we probably disagree on how much of the complexity is “accidental”, or what behaviour is inherent to DVCS, compared to what happened to be implemented in Git and similar. For instance, I think all of these could probably be eliminated with more careful design: the index, stashes, management of remotes, fetching, explicit management of remote-tracking branches, etc.

      Another big source of complexity comes from the unfortunate fact that Git pre-dates Github. Git is designed for a world which never happened: where most people are running their own Git servers, and there is enormous variety in the places where commits are shared between. Instead, the vast majority of open source development happens on Github – and yet, Git is not even aware of its existence. It’s kind of staggering that NPM, for instance, has shortcuts for Github repos (“package: username/reponame”), yet Git itself requires a full Github URL. Git could have been much simpler (“git checkout username/repo/branch”) had they assumed that most people were working on Github, and moving commits between sites was the unusual case…

  286. Blink December 3, 2015 at 10:47 pm

    Good article. I will be experiencing a few of these issues
    as well..

  287. Larry December 7, 2015 at 6:41 am

    You can add one more (major) issue to your list. I just started learning Git a week ago and was stunned to discover that it doesn’t store timestamps (last modification date). So you run “git checkout whatever” and all files in branch “whatever” now have the current date. Are you kidding me? I already wrote my own hooks to circumvent the problem but it’s potentially brittle. Lack of native support for this is a serious problem.

    • SavageTwinky December 7, 2015 at 7:59 am

      The last modification date is based on when you checkout on purpose, and should only change files that change when checking out a new branch. Most build systems won’t work properly without this behavior.

      • larry999999 December 7, 2015 at 8:33 am

        The behavior is broken. Example. You have a file “Test.cpp” in master. You then create and checkout a new branch and update “Test.cpp” on that branch. You then commit that branch and checkout master again. “Test.cpp” is correctly restored to the master version of that file, but its date is now the current date, even though it hasn’t changed. That’s a serious problem. I’ve read the (apparent) reasons for this behavior, because it would wreak havoc with compilers (make files, etc.) that need to detect what to re-build based on updated source files (most do of course), That’s a lame reason not to record the file dates in the repository at all (they’re completely lost), and allow users to choose whether to re-apply them via some simple checkout option (which can even be made the default in the config file at the user’s discretion). It’s also very simple to re-build your entire app after doing a checkout. Losing the last modification date makes it impossible to reliably check when a file was last updated (by inspection based on date). Not to mention it also affects backup programs.

      • SavageTwinky December 7, 2015 at 11:22 am

        I don’t think that the behavior is broken. Its not intended to work in tandem with file system backups or if you want to get the last change, just do a git log on the file. Git is used for source control so its intentionally designed to work for compile systems first. I don’t think its reasonable to expect everyone to rebuild their projects because you don’t want to use git log/blame to see when it was last changed.

        What your saying is like saying a hammer is broken because its not screwing in a screw… its not designed or intended for that usage scenario.

      • Larry December 7, 2015 at 1:23 pm

        Are you really saying it’s ok to check out a branch only to find dozens or hundreds of files are now all showing the current date, even though they haven’t changed. You consider that acceptable behavior (one that other source packages don’t have BTW)? It’s setting your files’ modification dates to something that’s incorrect, even if it’s being done with good intentions. Your files haven’t changed, but their modification dates have been updated anyway, so they now contain the wrong value (literally). That’s broken behavior in my book, even if a side effect of this situation fixes some other problem. It’s only able to do so by breaking something else (my files’ dates, and anything that depends on it). The situation is completely absurd IMHO, and would be very easy to fix with a few simple options (so we can all have our cake).

      • SavageTwinky December 7, 2015 at 2:01 pm

        The last modified date is kind of irrelevant, its not part of git, or gits tracking. The files are modified because when you change branches, the index changes. The index has the revision for every file in working space and it changes each file if they need to be changed. It does not change all of the files, only the ones where the revision differ with the index on checkout. This works directly with build systems because they see the those files have changed and the next time you build it will recompile. It doesn’t care that the user saved the file this morning, it commits the changes with a commit message, hash value, time, and author. Everything important about the change is tied together.
        Thats not incorrect or broken behavior. Its not designed to work with file system tools like backup software. Its designed to work with build systems because it was designed for software source control. The git developers probably didn’t feel like last modified date was really that necessary to keep. What matters is the commit time.

        I’m not sure what you doing with the last modified date, but it sounds like your doing it wrong. And if you really want to do it that way, the source for git is available and you can go fix it to your liking.

      • Larry December 7, 2015 at 3:13 pm

        It’s setting the file’s date in the OS itself an *incorrect* value. This has nothing to do with Git and its needs. Outside of Git, people still interact with their files. The last modification date is no longer correct. If I look at my files outside of Git, or any program does, I (they) expect to see the real modification date, not today’s date. The file wasn’t modified today so it’s wrong to tell me it was. This is clear cut. The file wasn’t changed but the date claims it was. I’m not doing something wrong. Git is. We’ll have to leave it that. We clearly don’t agree.

      • SavageTwinky December 8, 2015 at 8:14 am

        lets say you have a revision 1.7. you commit something today to file x.txt. Than you make serveral other commits to y.txt. And then tag it 1.8. All of the checkouts between 1.7 to 1.8 should have x.txt at the same revision and the file shouldn’t be modified, because you never modified it. Checking out those revisions should only write to y.txt and change the modified date because git wrote to it, x.txt should be left unchanged, and shouldn’t need to be recompiled because of this. Any new checkouts you do are based on the checkout time. Your working copy is not a reflection on the history, thats what git blame/log/diff is for. For example, if I’m on 1.8 and want to see what changed since 1.7, git diff 1.7 will show me.

        I don’t think it was intended to work with a backup program, probably because they designed it to be light weight branches, commit/push often to a backed up server. I’m not sure if there is a solution for you. Your choice is don’t use git, fix git to your liking, or make sure your backup programs ignore your working copy and use git to figure out which files have changed.

      • arnebab December 8, 2015 at 3:52 am

        The file *was* modified today: by git.

        Git tracks as little as possible: content, name and executable-bit. All the other metadata differs between filesystems.

      • Larry December 8, 2015 at 5:53 am

        The file *wasn’t* modified by Git. It simply fails to reapply the original date because it doesn’t have it, so a new file is presumably created with the original (unchanged) content but the latest date (regardless of how this is implemented). Your build system is therefore tricked into thinking the file itself has changed because it’s now newer than the target of the build, thus triggering a re-build. The file’s content hasn’t actually changed however and that’s what the last modification date refers to. The new date is completely wrong, and this is a dirty technique even if it has some positive benefit (since it’s only accomplished at the expense of breaking the file’s real modification date). People and other programs rely on these dates all the time to see when a file was last changed. Yes, this is required *outside* their source control program and any argument to the contrary is ridiculous. Git has no right to foul this up without the user’s permission. It also has no idea what your files may be for. Not all files are involved in compilation – your repository may contain many extraneous files or may have nothing to do with a software project at all – so it’s updating the modification dates with the wrong value for nothing (which it shouldn’t be doing anyway, even for source code files). Dates can easily be stored in the repository in a universal format regardless of file system, and even (optionally) shown in local time on whatever system you’re running on (based on some time zone setting). As I emphasized, a simple checkout option would allow the user to decide if they want to reapply the original dates or not, but most shouldn’t in fact, since the last change time is lost otherwise (regardless of re-build issues). It would never be allowed in my shop. It’s a no-brainer.

      • SavageTwinky December 8, 2015 at 6:13 am

        If git is modifying the file on checkout, that means its at a different version. If the revision in the index is different from the checkout target, git modifies the file by creating a new one over it. Git is modifying your file, its completely designed to do this. Your build system in turn knows the file has changed. It does not change files if they are at the same revision. Your problem seems more likely that someone doesn’t know how to merge and is copying/pasting files into different branches.

        The dates are stored as part of the commit, the file system data. The fact that git can store hundreds of branches with dates ranging from the start of time to the end of time means matching the time on the file system is kind of useless. For instance the backup program you mentioned that doesn’t work with git, how is it supposed to know that a change made today on branch x vs a change made on branch y a week ago can be completely different. Most other systems are not designed to work with git, a back up program can’t be aware of branches/tags when checking out older revisions that you never had available yet. Without that extra data, that date become superfluous.

      • Larry December 8, 2015 at 7:25 am

        I’m not the only one to complain about this situation. Honestly, I don’t follow your logic, or maybe you don’t follow mine (respectfully). If a file in branch, say, “V1.7” is committed with last modification date X, and I later check that branch out after working on some other branch, I get the same (unaltered) V1.7 file back but with the modification date now updated (assuming it was updated in the new branch as well). Not sure about all the possible scenarios where this can occur (very new to Git still), but that situation is definitely wrong. If it was committed in branch V1.7 with modification date X, it should still have date X when I later check it out again, not the current date. Nothing’s changed, nothing’s been merged, zero, nada. It’s the identical file I might have committed a mere 10 seconds ago, whose date was X at the time (when I ran “git commit”). I now run “git checkout” a few seconds later and its date is now showing the current date. The file was never changed though. It’s amazing more people don’t complain about this (or don’t recognize it’s a problem, or just choose to live with it). If you take a directory of your files at the OS level, and even sort it on date, do you really want to see files with the wrong timestamp. It’s wrong and misleading, and you can’t tell when something was really updated. As for backup programs, I’m talking about 3rd-party backup programs that have nothing to do with Git. They do backups of all files on the machine based on the timestamp (at the OS level). If file Y hasn’t changed since the last backup (in the OS itself), it can be safely ignored by the next backup. Because Git is modifying file Y’s date however, even though the file hasn’t changed, it needlessly triggers the backup program to process file Y again. Sigh.

      • arnebab December 10, 2015 at 8:34 pm

        The core question is: does the file differ between that other branch and branch “1.7”? If yes, and if you used a build system, that build system would have to consider the file as changed.

        Also if you backup the content (working copy) of any kind of DVCS repositories, you’re always getting unnecessary copies in your backups. If you checkout branch 1.7 and run the backup, then you checkout the other branch and run the backup and then switch back to 1.7 and do the backup, should the backup record the current version of the file or keep the “newer” version from the other branch?

        All that while the history is also backupped and contains all different versions of the files which ever existed (compressed efficiently).

        The solution for your case would be to use a backup system which is based on the content of the files, not the modification date.

        If you really want the modification time, you can create a hook that runs on update and adjusts the modification times to the time when the commit was made.

      • Larry December 11, 2015 at 3:49 am

        Your core question and response ignore the crux of the issue. If I’m working with a modified version of “Test.cpp” in, say, V2.1 and then checkout, say, V1.7, the last modification date of “Test.cpp” is updated to the current date and time. If “Test.cpp” hasn’t been modified in V2.1 however and I checkout V1.7, its last modification date is *not* updated. Do you believe this is logical? If you do then you must believe that in the first case, I updated V2.1 of “Test.cpp” to V1.7, simply because the content of each version is different. So I’m now looking at V1.7 whose date is the current date because I modified V2.1 and it became V1.7 (huh?). So someone looking at the working directory sees V1.7 of “Test.cpp” and says, “ok, V1.7 of that file was last updated today”. If “Test.cpp” wasn’t modified in V2.1 however, and you then checkout V1.7, they’ll now say, “ok, V1.7 of that file was last updated 2 years ago”. So which is it. Was it last updated today or 2 years ago. When you checkout V1.7 and many files now have today’s date, do you really claim that they were last modified today, because someone was working on a later version of those files, and then restored the earlier version. Technically there was a change in the file’s content because you were working on V2.1 of the file and now V1.7 is back on your machine. They differ so you’re arguing that it’s ok to update the modification date as if V2.1 was really updated and became V1.7. It’s a temporal issue. V2.1 didn’t even exist when V1.7 was committed, so when you check out V1.7 again, you should see V1.7, including its last modification dates. Those are the dates you would have seen when V1.7 was originally committed so when you check it out again, you should see the exact same dates. How can V1.7 of “Test.cpp”, now on many customer machines, have today’s date when that version was released two years ago. This is what the modification date refers to and how anyone looking at it will interpret it. Setting it to today’s date makes it appear as if V1.7 was updated today when it really wasn’t. The issue surrounding re-builds is completely independent of this situation. Changing the file’s date to trigger a re-build does so at the expense of breaking the file’s modification date. The new date is erroneous, and correcting this using hooks is very brittle (and not even possible in all cases based on what I’ve seen so far). Fixing this in Git itself would be simple in theory (storing the last modification date is easy), and can be done without breaking the existing (current) behavior (based on a few trivial options)

      • SavageTwinky December 11, 2015 at 9:52 am

        Modification date of your working directory does not, and is not supposed to reflect the commit date. Your working directory is not the history, its your working local copy. Git writes to the files when on checkout that differ in changeset updating the last modified time. So when you change your working copy in any way, it updates the files it needs to. The history is in the git metadata. Git is storing the dates and all relevant meta data. and if you need it for a build or something its easy to extract. This just happens to work with build systems really well. Did any files since I last compiled ? Yes so compile them. You checked them out at a different date, you compiled them at a different date.

        We’ll have to agree to disagree. I’m assuming you either are using the wrong tool for your needs or unwilling to change your process/expectations for different tools. Not all tools are designed same or have the same use cases. This isn’t a fault with git. Git has many faults but its does exactly what its designed to do, primarily for using light weight branches, and software development. If your worried about backing up your working copy, commit often to a branch, push often. Git also has tons of utilities for cleaning up the messy history after the fact.

      • Larry December 12, 2015 at 12:15 am

        Yes, we’re definitely not in-sync and many others support my position. Here’s one assessment that summarizes much of what I’ve said:
        http://stackoverflow.com/questions/1964470/whats-the-equivalent-of-use-commit-times-for-git/13284229#13284229
        Note that manually correcting the situation using hooks is insufficient for several reasons, not the least of which is that there aren’t even enough hooks to cover all situations. It’s just a hack anyway, and a poor one.

      • SavageTwinky December 12, 2015 at 12:33 am

        Right but that doesn’t mean its wrong behavior. Its doing whats its designed and supposed to do. Its working with the tools its designed to work with. Because you and others are trying to use it in ways it wasn’t intended for doesn’t make it wrong behavior.

        If git works poorly in your environment, maybe choose a different tool or adapt your process to work with it. My work machine I keep all of my files in synced drives with a back up server. I ignore all of my git repositories since they are backed up separately on our git server. I commit and push often. If our dev machines go down it takes all of an hour to set up a new one. It might take a while for the files to sync. And our build servers pull all of the info like dates and other things out of git.

      • Larry December 12, 2015 at 2:39 am

        You consider the situation innocuous because you feel that the program is within its rights to change the date for some greater purpose, which you claim is part of its design, but if so (and Linus Torvald would presumably concur), then it’s poorly designed (referring to this issue only). Its purpose is to store and track files (and related features), not make mandatory assumptions about what the user may be doing with those files after checkout. It implicitly assumes that the user will be recompiling these files, will always want the dates updated (frequently untrue), and completely ignores that files may not even involve compiling, even if they’re compilable source files. Someone may be checking out a C/C++ project for inspection only, and needs to see the original modification date (not commit date). There’s absolutely no need to change the date in these cases. More to the point, even if you do need to recompile, the source file itself hasn’t changed regardless, so the modification date is being updated for its side-effect only, i.e., to get your compiler to rebuild its target. The date on the source file itself is now *wrong* though, because the file hasn’t been updated, and that’s the core of the issue. You keep ignoring this but it’s the central tenet of the argument. It’s outside the jurisdiction of Git or any other program to change a file’s modification date unless it’s really modifying the file (without your permission). It’s not a pedantic argument. The date your OS uses to track the last modification time of a file is literally being corrupted, even though the date itself represents a real date (today’s date, but that’s wrong, because the file wasn’t modified today so it’s corrupt for all intents and purposes). The user therefore loses the history of a file based on its modification date, and are misled into thinking it was last changed today. You make the point that “… others are trying to use it in ways it wasn’t intended for ..”. That’s just not true. Git itself is guilty of that, by changing a file in a way that its own users weren’t intending for, violating the principle of least surprise (many are). My only expectation is that any 3rd-party program will function as a good citizen of its environment, and not (quietly) update a file’s modification date unless it’s really changing that file (unless there’s a special case like this, and you give it permission to). Just because Git is a source control program, and many users will be re-compiling, doesn’t give it license to unilaterally set your files modification date to a bogus value without permission (again, bogus even if you are recompiling).

      • SavageTwinky December 12, 2015 at 3:18 am

        The file isn’t stored in git, a change is. The file is created in your working directory. When git modifies your working directory it updates the files leaving your working directory with times of when they locally were checked out. Git writes to the files, the vast majority of tools that work alongside git know git or you, have changed your working copy.

        Regardless of what linus said, This is the design. If the vast majority of git users felt that the modification time was too important to leave out it would have likely been added by now. Linus isn’t the maintainer for git any more so what does it really matter what he thinks?. Like I said, the git history, and working directory are really separate things. The modification time without other git metadata is incredibly useless, except for dealing with external tools that probably shouldn’t be interacting with your working copy any way. Checking out different branches will have completely arbitrary and random dates going forwards and backwards in time.

        Its a different tool. If you don’t think its the right tool for you, don’t use it. If you have to use it, find a better way to work with it, or modify it to do what you like. You can’t claim a tool for being wrong when nobody that is designing it, and vast majority of users using it, use it differently than you.

      • Larry December 12, 2015 at 7:25 am

        > When git modifies your working directory it updates the files leaving your working directory with times of when they locally were checked out.

        By this logic you could claim it’s ok to copy a file at the OS itself, or restore a file from some backup program, and have the target of the copy assume today’s date (instead of the original file). I doubt you would find that acceptable and the situation with Git is effectively no different.

        > Regardless of what linus said

        Agreed, it’s irrelevant

        > The modification time without other git metadata is incredibly useless …

        Just the opposite. It stands on its own (no other metadata required) and is probably the most basic (universal) piece of data you can capture about a file.

        > … except for dealing with external tools that probably shouldn’t be interacting with your working copy any way.

        So the OS itself is an external tool? Apparently so, since I shouldn’t even take a directory listing to inspect a file’s last modification date because the OS is “interacting with my working copy”. It “probably shouldn’t be” so I (probably) shouldn’t expect the date to be correct (really?)

        > Checking out different branches will have completely arbitrary and random dates going forwards and backwards in time

        A file’s last modification time is completely independent of Git, so concepts like branches have no bearing on the situation whatsoever (unless Git is modifying the file itself, during a merge or whatever). Your OS stores the date knowing nothing about Git branches. A file is always modified on some specific date. There’s nothing arbitrary or random about it.

        > You can’t claim a tool for being wrong when nobody that is designing it, and vast majority of users using it, use it differently than you.

        Show me a programmer who hasn’t checked the modification date of a file at some point and I’ll show you a programmer who just started their career this week. This issue has likely affected far more programmers than you realize.

      • SavageTwinky December 12, 2015 at 2:05 pm

        > Show me a programmer who hasn’t checked the modification date of a file at some point and I’ll show you a programmer who just started their career this week. This issue has likely affected far more programmers than you realize.

        All of them that I know. No one I’ve ever worked with has needed to know the modification date based on the file system because they know how to use git/svn/perforce/mercurial to retrieve when, along with what and why. These are the 4 version control systems I’ve worked with extensively and there has never been a point where I needed to know the last modification date without what the changes were or why they were changed. In fact when a file changed is literally the least of my concern, knowing what files were changed, why they were changed, and the changes were made are all the most important things. I might need to know when to fill out some stupid ISO documentation or something… but again its documented in source control.

        The dates on the files are almost completely irrelevant by everything that views file systems. A developer can’t make any meaningful conclusions about the dates on their own (well unless a file was changed 6 months ago… you can conclude it was changed 6 months ago), file system tools will likely get confused over timelines jumping forward and backwards in time since branch checkouts use the same working directory, build tools will never know the working copy changed…. Alternatively the information you need can be retrieved from source control very easily which is what its there for. Who care’s that the OS perceives your file as being changed today instead of 6 months ago. The OS won’t do anything with that data and if it does (file history on windows) you can easily disable it for that folder. I completely understand your point of view but its a view that in practice is completely useless.

        I think you have to realize git isn’t designed for you or for someone with your needs. Find a better tool or fork git. You can easily use mercurial instead. It doesn’t support time stamps out of box but there is an extension for it. The vast majority of source control use the same default behavior as git so unless you found a super abnormal use case for source control, just use source control to figure out when things changed… Git even has a lot of tools to change the history so you can end up with file stamps that don’t follow a normal timeline, dev1: “Why does the time stamp from a commit that happened a week ago is newer than the 10 commits after it that start from 3 weeks ago…” dev2: “rebase”

        For everyone else along for this ride, I’m really sorry I let this conversion get out of hand like this. I can’t stop though!

      • arnebab December 12, 2015 at 8:22 am

        Let’s take a step back: How would this look without automation.

        I would open a file with a text editor. Then I would look into the branch specification to see what content it should have in a given version. And change it to hold that content. The modification date becomes “right now”.

        Later I change back to the other version. I look into the branch specification and change the file back. The modification date becomes “right now”.

        This is what git does (and what most other version tracking tools do).

        You want it to do not less but more: To adjust the metadata to what it was when the file was stored. At least in Mercurial you can do that with hooks: Create a commit hook which stores the metadata when committing and create an update hook which restores that metadata when updating or reverting (Mercurial update roughly corresponds to Git checkout).

        You might want to look into etckeeper which extends popular version control tools in ways similar to your needs: https://etckeeper.branchable.com/ https://github.com/joeyh/etckeeper

      • steveko December 12, 2015 at 10:54 pm

        Interesting debate here :) For my part, I consider many parts of Git’s design broken, but this isn’t one of them. I don’t know anyone who looks at file modification dates of source code files. Those dates are a kind of very primitive source control telling you something about the history of the file – but you have a much better tool right in your hands, so you use that instead.

  288. Larry December 8, 2015 at 6:03 am

    Correction, “but most shouldn’t in fact” -> “and most should in fact”

  289. chemiko December 30, 2015 at 11:34 am

    You know, as someone working on a git all-purpose user solution, my only real problem with it is how trees are just deltas, and file movements are not tracked properly. The conflict resolution for moves and renames becomes a mess as a result. Regarding any complaint about hard resets, or resets in general… stay away from that interface – it just messes up the trees, and is of no consequence if you are a typical contributor. I would label resets as an administrative artifact that is best used to prune repositories at the end of a “stream” of users… or potentially along the way, depending on how the agreed to workflow is defined. Same thing regarding fast forward issues – and I know, sometimes this is a *required* thing that we must deal with via server side triggers. Workflows are another matter entirely… that is where this architecture really complicates things. My two cents: this thing is flexible, use at your own discretion, and avoid where you think it will cause more confusion than good.

  290. LordHater January 3, 2016 at 7:29 am

    It looks to me that some points on this page were also inspired by your post: http://svnvsgit.com/.

  291. Pingback: Ivan Krivyakov's Blog » A year of using Git: the good, the bad, and the ugly

  292. Pingback: Why git ? | Sagar Hani

  293. Pingback: Do you sometimes hate Git? You're not alone. - GitGut

  294. onigetoc February 19, 2016 at 11:06 am

    I’m starting a new project, i use SourceTree, and i never remember how to begin and commit this first damn projet. why can i click send and send it without doing zillions of unusefull things?

    • maxweber April 30, 2016 at 2:35 am

      Because you are using Git. (Send my prize to the local orphange. :-)
      Also, git is not able to rename a remote branch. What crap. Sure, tell me its a feature. What crap. Features do what users want, not what some nerd thinks should be the rules.

  295. irakli February 19, 2016 at 9:49 pm

    you can use aliases.
    instead of add, commit and push, you can use one command.

  296. Harald-René Flasch February 23, 2016 at 12:55 am

    Missing keyword expansion feature from SVN ;-) Also committed to #7! Using TortoiseGit under Windows and recently found an issue when folder name only differs in case. Locally only one folder, in the repo two folders … (containing duplicates of source files and depending who checks in source code the are committed to AAA\name.cpp oder aaa\name.cpp ….. Bug or feature?

    • SavageTwinky February 23, 2016 at 9:53 am

      The case issue isn’t really a git issue. Its a “don’t do that” sort of situation if you’re going to use linux/windows cross development Any kind of situation where you’ll have the files on either type of filesystem you need to take care when naming/creating paths.

  297. chok February 28, 2016 at 8:22 am

    Agreed totally with the article, thanks for writing it. In short, git is a powerful tool with a substandard user interface. I think this will improve over time when software companies create git apps to try to make money from git. And I think svn can totally beat git hands down by adding some new features.

  298. Joe Bloggs March 8, 2016 at 7:06 am

    Git is like the story of “The Emperor with no clothes”, with legions promoting its brilliance while deep down wondering “WTF is this so complicated?”

  299. Gary Mize March 19, 2016 at 12:55 am

    I HATE Git and I LOVE Git – but a good illustration on how poorly it’s designed ( especially when it comes to command line operations, syntax and nomenclature and lack of clear documentation ) is if you EVER ask or google a question on how to do something you open a venerable hornets next of replies and arguments on the right way to do something with a plethora of caveats of “however”s almost to the point of an uprising….so I’ve had to create my own documentation ( which isn’t unusual in the software world anyway ) and have leaned some very painful lessons mostly on how NOT to do things…but now I can’t live without it…

    • arnebab May 1, 2016 at 7:15 pm

      You could just try Mercurial — get the same features (and then some) but with a sane interface.

  300. Rogerson March 22, 2016 at 3:57 am

    Long Path Fixer presents you with a simple list of files and folders in the current directory (including “hidden” files and folders). You can drag and drop files or folders onto it and it will navigate directly to path of whatever you dropped.

  301. Pingback: Critics of Git | Git Advanced

  302. Alex Von April 8, 2016 at 10:17 pm

    t..t.t..turtles anyone?

  303. Pingback: Beginning Version Control with Git & GitHub | GeekProbe

  304. Tim Mc May 3, 2016 at 1:23 pm

    Thank you, thank you! I knew I wasn’t the only one! I am a very knowledgeable source control user/admin and “I DON’T GIT IT!” For over a year and a half I have tried… and I hate it. I will probably not leave SubVersion. I use TFS at work but for personal stuff SubVersion is super easy. I understand what they are trying to do with GIT, but Developer-Fu is taking difficult concepts and making them easier to understand – not, like you said, throwing everyone a big “f@ck you”!

    • sfkleach May 4, 2016 at 5:08 am

      I’ve posted quite a few times on this long thread. Can I recommend SmartGit from Syntevo – I have no connection, I just think it is the best source-code control software I’ve used. Not only does it make Git fun to use (!) but it works with Subversion and Mercurial too AND is cross-platform. And, honestly, the advantages of Git over Subversion are compelling.

  305. maxweber May 5, 2016 at 1:10 am

    I didn’t use to have turrets until I started using git. Now I have this strange habit of cursing out loud every so often and appears to happen every time after I use git. :-)
    I have a totally fubar example now. So, we have the typical pesky lead person wanting everything to be in the githole for them to approve before it merges. So, every (I mean _every_) change has to be a branch. Process overhead crushing us; but, that’s a side story. So, plodding along OK with this setup for a few weeks. I do:
    git checkout TARGET_FIXES_BRANCH
    git reset –hard origin
    git pull
    I do that last one to get any other commits and merges having gone into the TARGET_FIXES_BRANCH.
    make my code changes
    git push origin HEAD:bugxyz_fixes
    Go great a pull request and it gets reviewed and eventually merged into TARGET_FIXES_BRANCHES.
    soooo…. wait for it …. we are orwking thiw git here:
    That no longer works. Can’t get the most recent code from the TARGET_FIXES_BRANCH.
    http://stackoverflow.com/questions/1125968/force-git-to-overwrite-local-files-on-pull
    has a list of ideas. They don’t work.
    when I do the git pull then I get an automerge and even some conflicts. What?!!?!?
    I git checkout onto some other branch. Then I git branch -D TARGET_FIXES_BRANCH to delete the local copy of the remote branch (been burned and cursed out loud on that one before).
    So, no local branch. So, I
    git checkout TARGET_FIXES_BRANCH
    git reset –had origin
    git pull
    !!! Still have automerging and conflicts!!! What! I am trying to make a clean project.
    I know there is some git recipe here. What worked for weeks no longer works.
    Its git.
    Its a research project.
    Doing the work takes less effort by fart than git.
    Its git.
    Its a research project.

    • maxweber May 5, 2016 at 1:30 am

      Figured it out. The head on the origin had changed. At such time, needed to be more explicit on the reset command. Needed to do:
      git reset –hard origin/TARGET_FIXES_BRANCH
      Doing this was resetting to a different branch altogether.
      git reset –hard origin
      I had made the wrong assumption the “origin” was the branch I checked out from; but, its some headmost branch on the server, which changes.
      So obvious. Works now.

  306. Pingback: What Does Rebased Mean In Clearcase | Razeeti1

  307. /dev/ammo42 May 16, 2016 at 7:29 am

    “Reset/checkout

    To reset one file in your working directory to its committed state:

    git checkout file.txt

    To reset every file in your working directory to its committed state:

    git reset –hard”

    Except that:
    -such a change in command is not necessary: you can actually do ‘git checkout .’ or ‘git checkout — .’ to reset every file of the directory to commited state;
    -‘git checkout .’ and ‘git reset –hard’ don’t do the same thing: if you ‘add’ a file without committing it, checkout will keep it while reset –hard will delete the changes you ‘add’ed.

    I found the following webpage useful to understand how git works, even after having used it several times:
    http://marklodato.github.io/visual-git-guide/index-en.html

    • steveko May 24, 2016 at 4:24 pm

      Heh, I think your comment proves my point. I’ve spent a lot of time since this post trying to form some sort of coherent mental model around ‘git reset’, but totally failed. It doesn’t make any sense to me.

      • SavageTwinky May 24, 2016 at 8:51 pm

        git reset changes you’re branch head to a commit, –hard throwing out all changes. It just seems to be overloaded since file operations do something different. git reset SomeFile.txt will remove it from the stage… Not specifying a commit assumes HEAD as the commit for all operations.

        The people that made the interface deserve to be slapped. The commands surrounding the stage/index I don’t think were ever really thought through. git add will stage changes, git rm will also stage changes, reset will unstage things.. checkout will keep the stage intact and modify the working directory, reset will blow you’re working directory + stage given –hard. Everything surrounding the stage is really hard to understand because you can’t make a mental model for it. Different commands operate on the stage differently and even change given the context the command is run in. Even the term stage seems to be redundant with index since there’s no actual stage/unstage commands and its actually working with the index. Realistically there’s probably a commit called stage or something to represent the changes to you’re index from you’re last commit.

        They call it “organic” growth but from where I’m sitting its a nice way to put unplanned mess that happens to work really well.

  308. Ryan Jentzsch May 22, 2016 at 6:55 am

    I’ve been developing software for over 25 years, and Git is driving me nuts. I typed in “git is driving me crazy” into Google and ended up on this page from 2012. It’s now 2016 and git is still just as bad.
    Git is not based on a client/server model. Back in the dark ages connectivity could be uncertain. Linus designed git as a means of letting multiple people in diverse places on the planet contribute and sync (even via email). It’s growth has been very organic (need to do something similar but different? OK, add a new command switch, or a new sub-command parameter and tack it on to the existing command, or maybe make it it’s own command — doesn’t matter there’s no need to be consistent).
    I had to deal with Microsoft’s abominable VCS called SourceSafe, to which git is an improvement. So, I should complain so much.
    I was just trying to flatten a bunch of commits in my branch to a single commit — which I did following a tutorial and ended up DESTROYING the remote master branch that became the branch I had flattened (thankfully my friend had a recent clone so we could recover).
    A good VCS shouldn’t let you perform a nuclear meltdown on the Master branch EVER!

    Thanks for the article and for giving me an outlet to vent a bit :) I feel better already.

    • sfkleach May 23, 2016 at 6:17 am

      Firstly, as I have for many of the posts on here, if you find git on the command line unfriendly (as most of us do), do yourself a favour and try SmartGitHg from Syntevo – and no I am not connected with them in any way. It’s just a very good, highly portable interface to git, subversion and mercurial. It turned git from being a problem to being a pleasure for me and I can’t recommend it enough.

      Secondly, not being based on a client server model is essential. If you haven’t understood why that must be true, then you haven’t really understood the package of benefits git brings. Working with your own repository is liberating – once you ‘grok’ the peer-model of DCVS. (There are better models than the one git offers but client-server is no model at all.)

      Thirdly, the whole idea of editing revision history is controversial – I am not a big fan of it myself. Unless there’s a clear need, don’t muck about with your repository in ways you don’t fully understand. It is very unlikely that you destroyed a remote master branch rather than made it incomprehensibly confusing.

      However I have managed to “meltdown”every VCS I have ever used – losing source code when using Microsoft’s SourceSafe and Team Foundation Server is a regular occurrence. And I do remember getting my Subversion master into such a confused state I had to delete it and start again. No, it shouldn’t happen but the root cause is very deep – and a story for another post.

  309. Gerry Beauregard June 27, 2016 at 12:57 pm

    Linus Torvalds probably knew that git was awful to work with, and chose the name accordingly. According to the Dictionary app on the Mac, in British informal English, “git” means
    “an unpleasant or contemptible person. e.g. that mean old git. a warped, twisted little git.”
    I’ve rarely encountered software that so perfectly lives up to its name.

  310. gato barato June 28, 2016 at 3:41 am

    Thanks, your points are completely valid as you said “in your experience”, i never had problems learning and using git, but is very useful to know others points of view, i learned something new today. Thanks again.

  311. Richard E. Silverman June 28, 2016 at 8:14 am

    Steve,

    I agree with much of your criticism, but disagree with these sections:

    “unsafe version control” — The examples you give here of unsafeness all involve a remote repository configured to allow removal of history. It is easy to turn this off. You might argue instead that the system should never allow it as a matter of design, or that it ought to be off by default… but with just the examples you give, I don’t find the argument compelling.

    “Git history is a bunch of lies” — This I disagree with entirely. Since “git rebase” does a number of things, let’s focus on the feature I think you mean: using it to edit your local commits before making them part of the permanent history by pushing them elsewhere. The claim here seems to be that once you make a local commit, you should be forced to push it, even if it’s wrong in any number of ways. I cannot see why this would be an improvement — and if you call this “lying,” then why is it not also “lying” to fail to push every version of a file you write to disk by hitting “save” in your editor? The work you push consists not only of the file contents, but also the commit messages, choice of commit contents, merge structure, and other VC metadata, which are all important to the project (when you ask whether history is important enough to bother so much about, my answer is “yes”). I see no justification for referring to editing your work before publishing it “lying.”

    Sincerely,

    Richard E. Silverman

    • steveko June 29, 2016 at 10:14 pm

      >The examples you give here of unsafeness all involve a remote repository configured to allow removal of history. It is easy to turn this off.

      Oh? How do you do this in Github?

      >The claim here seems to be that once you make a local commit, you should be forced to push it, even if it’s wrong in any number of ways.

      Not exactly. One claim I make is that if an actual sequence of work goes “I did X, you did A, I did Y, you did B”, then the history should look like X-A-Y-B. Or, conversely, that if the history reads “X-Y-A-B”, then that should reflect the sequence of events.

      I’m fine with amending a bad commit. I’m not fine with it being routine to reorganise commits, especially when it’s so easy to get things catastrophically. wrong. I’m really, really not fine with the safety of pushing amended/rebased commits relying on whether or not anyone has pulled the old commits in the mean time, and there being both no way of detecting that situation, or recovering gracefully if it does happen.

      • pseudometric June 29, 2016 at 11:38 pm

        > Oh? How do you do this in Github?

        GitHub calls it “protected branches,” a feature they added last year: https://help.github.com/articles/configuring-protected-branches/. Although even if GitHub lacked this it wouldn’t be directly relevant; your article is a criticism of Git, not GitHub, and this has always been in Git (the receive.denyNonFastforwards property, which is set by default for shared repositories).

        > I’m fine with amending a bad commit. I’m not fine with it being routine to reorganise commits, especially when it’s so easy to get things catastrophically wrong.

        I suppose we will continue to disagree about this; as I wrote, I simply don’t see the problem either in principle or in my experience. “Reorganizing commits” is just “amending” more then one commit. Your local work before you push it — both the file contents and commit factoring/structure — are yours to edit until you push. I don’t find it more likely that I will make a “catastrophic mistake” on some later edit than the first time I make a commit — and if I do make a mistake, I want to fix it.

        > I’m really, really not fine with the safety of pushing amended/rebased commits relying on whether or not anyone has pulled the old commits in the mean time…

        I agree — but this is a completely different situation. This is not about whether you should be allowed to edit your work before publishing it; it is about whether you should be allowed to discard history from a central, shared repository. That should almost always be turned off.

      • steveko June 30, 2016 at 12:56 am

        >Although even if GitHub lacked this it wouldn’t be directly relevant

        Heh, you claimed that it was “easy to turn off”. Since Github probably accounts for the majority of the world’s server-hosted Git repositories, that claim would basically be wrong.

      • pseudometric June 30, 2016 at 1:15 am

        > Heh, you claimed that it was “easy to turn off”. Since Github probably accounts for the majority of the world’s server-hosted Git repositories, that claim would basically be wrong.

        I’m not sure what you mean by this. It is, in fact, easy to turn off right now in GitHub, using the feature I pointed out. One might argue that it should be off by default, but that’s a different point. It is true that apparently this feature didn’t exist in GitHub until last year, which is after you made your initial blog post. However, I stand by my second statement: your article is about Git. Git != GitHub. Git supports the feature you want, and always has, and it is in fact on by default for shared repositories. Blaming the Git designers for an implementation decision made some company that uses Git in its product — however popular that product may be and however much people may confuse the two — is simply wrong.

        I do agree that many people make this confusion. Multiple times while I was writing the Git Pocket Guide, I had to correct even my editors at O’Reilly who would occasionally refer to it as “the GitHub book.” :)

    • arnebab July 1, 2016 at 5:48 pm

      Short comment: The article is clearly not only about git, but about the collaboration schemes people actually use. You can use Git to send patches to a mailing list and discuss them there. But that’s not what people do.

    • arnebab July 1, 2016 at 6:13 pm

      The “lies” are less about whether it is possible, but more about whether it is easy and used. The index actually promotes lying about the state of the repository: You commit a state you never ever had.

      I know that it is tempting to do that to show a clear progression and easy to follow story, and I do it myself with the record extension, but essentially it means that you never tested any of the intermediate commits.

      You only get out of this, if you make it a policy to ensure that when you create multiple commits from a given working directory state, the last of these commits must match the working directory state. So before you push, you should always do git commit -am “anything I missed”. Then at least the head will be the code you actually ran.

      • SavageTwinky July 1, 2016 at 10:15 pm

        Those aren’t lies, committing partial or not commuting correctly what you just ran is entirely up to a developer to do properly. Git actually enforces this policy a little bit better at as you commit the entire state of the repo.

        Something like SVN/Perforce you can easily end up running committed code without updating some files. For instance If someone updates a file and commits in from revision 10, and you commit and get revision 12, you’re running state at 12 that is missing 11. There was no merge resolution even showing that 11/12 were done independent of each other. Revision 12 is a lie in svn/perforce depending on whether or not you remembered to update and test.

        Git on the other hand either forces you to merge or rebase. It commits at the entire repository. So you have to be explicit about how you integrate with other changes before you send you’re commits to the server. Git will never have multiple local change sets that look like a clean repo.

        The problem you’re describing is not a problem with git, but a process problem. No tool stops developers from doing it wrong and can force a developer to commit only working commits.

      • arnebab July 2, 2016 at 6:33 am

        You are comparing Git against Subversion. What you describe in Subversion is essentially an error condition. Subversion cannot easily fix that. But it only happens in your interaction with others.

        What happens in Git is that this error condition would not be necessary, but the interface suggests recreating it by promoting an active add-step before committing: Committing only partial changes is the default (git add and git commit are separated), git commit -a is a deliberate change to the interface.

        In Git this error condition already happens in the interaction with yourself.

        Interface matters. It provides a constant pressure towards the process which is easiest to do with that interface. If that process is dangerous, then the user interface promotes dangerous behaviour.

        Sidenote: For svn if you commit from 10 and get 12, there is an auto-merge. If that merge fails, you need to resolve it manually. You never run 12 without 11, however you might run an automatic merge of 12 and 11.

  312. Baagad Billa July 1, 2016 at 8:54 pm

    What would happen to github, atlassian, assembla, etc if programmers start focussing on their code and stop fighting with git to get the job done. So they will keep promoting git even though they themselves might be knowing that it frustrates programmers.

    It is amazing that a small fix requires more work to commit and push with Git than the fix itself, particularly if someone else has modified the same file and pushed to the origin before you.

    I always take a backup of my code (I wrote a program to do that, actually) from the command line before attempting any git operation. I just dont know if it will do something incompletely and leave me with a mess to figure out. Git made a simple “what I have, what others have” and revisions into a mess of index, local repo, remote repo, stash, working dir, pull requests, cherry pick, blame, blah blah.

  313. David July 13, 2016 at 11:57 am

    Git is like so much out their today– absolute fucking mess. It’s this spaghetti on the wall crap and the primadonna’s thinking that nothing old works and they have to build their version of whatever because it’s “perfection”. Not true. Most desktop computers today actually don’t do any more than they did 20 years ago, but somehow now it takes Gigabytes of RAM and massive Ghz processors and cores, and blah blah blah. It doesn’t. Programmers are absolutely lost and github is a perfect example. It’s an absolute fucking mess.

    I have a background in assembler, have worked with microcomputers since they were invented, have written compilers, interpreters and very complex non-homogenous communications systems. I am fluid in numerous contemporary languages at all strata and I have an analog and digital electronics background and know how the computers actually work inside and have built and etched my own cards, etc. The one thing that the Apple Mac had that nobody seems to get is “consistency”. If github used the same commands and syntax as other VCS for the initial 50% of it’s operation and then _added_ new options or commands for new functionality it would be adopted easily by everyone because they could use it immediately.

    The old VCS “CVS” worked extremely well and was safer to use than SVN or Git and that’s why it’s still supported today, but github has become very poplar. Yet every single person I know who uses it has experienced major disasters. After a while you should realize that is not the fault of the user. That’s the fault fo the git/github designers.

    And worse, even after all this time with tens of millions of people using it, if you run across a problem it’s unlikely you’ll actually find a step-by-step how to do it or fix it on the web because nobody else has figured it out or cared to share what they did. Everything is written from the perspective of “I’m creating my first repository”, not “I’ve just been asked to do… with an existing repository”. And everybody assumes you have ‘git’ access, which you may not and are forced to work exclusively through github.

    And if something goes wrong, someone you don’t even know is backing up your data. How do you recover?

    • sfkleach July 13, 2016 at 4:22 pm

      I don’t suppose I can persuade you to like git, given the strong tone of your post, but I think I have a few helpful remarks. My first comment is that the final line of your post conflates version control and backup. Although version control to another system is a form of backup, that’s not its main job. The idea of using version control as backup doesn’t sit well with nice things like gated commits, for example, or even shared branches. But if you use it as a way to help protect your work from disaster, git keeps not only a copy of your local repository but also the remote one. This is much better than CVS or SVN because your local backup is much more useful.

      Secondly, you mention ‘CVS’ and compare it with SVN and git. Being fairly long in the tooth I remember CVS well and it doesn’t really stand the test of time and here’s some issues that would each be complete showstoppers in their own right today: binary data handled poorly, non-transactional commits (argh!), no change-set representation (only files are tracked) and no support for renaming. People aren’t using CVS for sound reasons, not faddishness.

      Lastly, if you find yourself obliged to use git but you are afraid of getting yourself in a mess, which is a position I have complete sympathy with, then I strongly recommend not using the command line git client but a GUI client. I can’t praise SmartGit from Syntevo highly enough in this regard, which changed git from a misery to a pleasure for me. There are also two open source clients (SourceTree and GitKraken) that I’ve briefly checked out and although I can’t recommend them from experience, they certainly seem like they are worth a look.

      • David July 13, 2016 at 5:14 pm

        I appreciate your perspective. All good points. I recognize that once a person can get their head around git (or any system) in a way that makes sense, suddenly the rain stops, the light shines, etc… but it shouldn’t be that way. We have been working with microcomputers for 40 years this year and they are a mess. I love *NIX and use it all the time and have for decades and I like having CLI, but I recognize the value of a GUI and VCS is something that _does_not_require_CLI_. I’ve been working with IntelliJ which many praised and it works great with CVS and SVN, but I can’t tell if it’s limited interface to git is the issue or if git is the issue. I will certainly take a good look at SmartGit and hope the “light will shine”. Thanks for the input, I will look at that first thing.

  314. Loup Vaillant July 24, 2016 at 7:33 am

    > consider Subversion: you have files, a working directory, a repository, versions, branches, and tags.

    Actually, subversion doesn’t even have branches and tags. There are the branches/ and a tags/ folder, but they’re mostly *conventions* build on top of an otherwise arbitrary file tree. To create a new branch or to tag the current version, you *copy* every file from the trunk to the appropriate branches/ or tags/ sub-folder —then you commit the operation to the repository. Note how the whole operation increments the version number of the whole thing, even though the main branch didn’t change one bit.

    > Versions are linear, with the odd merge.

    Strictly speaking, versions are linear, *period*. Remember that a merge in Subversion is really a smart way to copy a branch back into the trunk. As always, it increments the version number by 1, in a perfectly linear history. Really, it’s a hack.

    > Now Git: you have files, a working tree, an index, a local repository, a remote repository, remotes (pointers to remote repositories), commits, treeishes (pointers to commits), branches, a stash…

    Actually, that’s too high level. Fundamentally, Git, has files, a working tree, a local repository, commits, and tags. The index… well… the index is mostly a special kind of commit. There is no remote repository, just pointers to those. There are no branches. They’re just moving tags just like master. There *are* merge commits though.

    > Unsafe version control

    This section is false. Those are 3 ways to make a big mess, but they’re *not* a way to lose information. Those mistakes are mighty inconvenient, but they’re not unsafe.

    You *can* lose information in Git, mind you. Mind your working copy whenever you do fancy stuff with your local repository, or check out a new branch, or whatever. You might lose all uncommitted changes in a snap. But when you commit something, it’s very hard to lose that commit by accident.

    • arnebab July 25, 2016 at 12:16 am

      > Actually, that’s too high level.

      > Those are 3 ways to make a big mess, but they’re *not* a way to lose information.

      You’re almost right — on the low level.

      Once commited, you have approximately 30 days to revert any error, as long as you know the low level reflog plumbing. This, however, is not the normal usage of the VCS.

      I consider having to drop down into the lower abstraction layer to be an error state, because users who just learn to use the system have a really hard time reaching them. The most common solution I saw to fixing an error state is “just reclone and copy the working directory from the other repository”.

      As an analogy: there’s little chance to lose a file on a FAT filesystem. Even if you delete, you can still recover most content with basic file recovery tools which scan the unreferenced data. But few people would say that FAT has an undelete function.

      • Per October 11, 2016 at 10:46 pm

        I find this comment comical because it tries to picture the fact that Git does come with a very easily accessible and understandable repository history mechanism as something of a low level dark secrets feature whom only the initiated expert would use. In fact it isn’t so.

        The analogy is then drawn to FAT, saying that that is its equivalent and that you need recovery tools and so on you might not be able to get your file back.

        How is that a comparable solution? FAT wasn’t designed for that, tools exist as an afterthought and provide a recovery mechanism where people lucky enough might be able to recover what they lost.

        Git on the other hand was designed to offer that. The “I screwed up, reclone and redo” pattern is an example where users have not received any proper training to help them use this tool, and that goes for anything. If it is free, it doesn’t mean learning to use it is free.

        So, what would have been comparable?

        Why don’t we start by explaining how to recover a fault, error and problem in Subversion?

        Here is an example. Search for administrator in this guide:

        https://ist.berkeley.edu/as-ag/tools/usage/svn-user-troubleshooting-faq.html

        Note that it doesn’t say what you need to do. It’s black magic of course and you are not the initiated.

        How about: http://stackoverflow.com/questions/8841796/repair-corrupted-svn-repository

        Does it strike you as being easy?

      • SavageTwinky October 14, 2016 at 7:45 am

        you’re complaining about gits command line interface. Something like SmartGit shows you commits without branch names easily. So if you use the more advanced features where git will edit history, then everything is recoverable very easily.

        People need to stop acting like git is complete voodoo there aren’t that many commands. The issues I see are mostly just reset and pull. ( which are very widely used unfortunately, and tools like smart git have little check boxes that allow you to use pull in a confusing way.

        git add – to add files or changes stage
        git rm – remove a file, and stages the change
        git mv – moves a file, and stages the change
        git commit – commit the stage
        git checkout – checkouts out a branch or changes for the current stage
        git fetch – get remote changes
        git push – push local changes
        git clone
        git merge – merges a branch into working directory.
        git branch – create a branch
        git cherry-pick

        The vast majority of git features do not lose information at all, are not really difficult to understand, and are really easy to use on a day to day bases.

        Reset is BS and I will agree its meaning is incredibly obscure with all of the nonsense it can do
        git reset – unstages changes OR changes what commit you’re branch head is at
        git reset will remove changes from the stage
        git reset will ruin you’re day if you don’t intend to completely change what you’re current branch

        git rebase – Takes a set of changes and gives them a new parent, effectively making w/e series you want to rebase have a new start point (the only time theirs/mine view swaps). It’s confusing because you have to merge every change into you’re new starting point. The simple way to look at it is a way to automate cherry picking several changes into a branch.

        git pull – fetches and merges, or if you clicked a little check box use rebase instead, rebases (changes history)

        git reflog, used to fix mistakes you made with rebase/reset or find a deleted local branch.

        Git really isn’t that difficult to get you’re head around, but a few subtle changes can save people from getting into situations everyone complains about. The commands for add/rm/reset should be clear they only work with the stage and reset should be split into a second command removing the dangerous aspects of it. Git pull also should have rebase removed from it, its a convenience but one that often leads to a wtf scenario. Something that I do see mercurial doing better since the dangerous commands are split out into extensions a user has to enable. Commands that alter history or change a branch in a dangerous way should really be separate and clear about what they could potentially do.

        The biggest issues I’ve seen with git, are people that are in the industry for 25 years expecting to just understand everything about it without taking the time along with lots of tools putting dangerous commands in front of that user without any sort of warning (rebase in particular).

      • arnebab October 14, 2016 at 8:07 pm

        @Per: Strangely most of the things in the “Fixing” section of the svn faq you linked refer to the tool documentation. That’s a pretty good sign: they trust their tools documentation. The other sections are not part of the user workflow in SVN but account problems (similar to: how to set a SSH key in github) or server-part features which users in SVN never need to touch (different from git). Reflog is used for user-errors and intended as a user-tool – that makes a difference, because developers can avoid doing stuff which can be done with reflog.

        The corrupt repository is the equivalent to having corrupted the data in every git clone. It can happen. It can also happen to git. The filesystem is not perfect. What do you do when revisions in your physical git history files are corrupted?

        However I’m a Mercurial user. When I compare git UI to something, I compare it to Mercurial: Mercurial has the same feature-set as git, and it shows how those features can be exposed in a much saner UI

        For example the stuff for which you’d use reflog in git either do not happen in hg, because when something removes data it directly shows how to get it back (it stores a bundle and gives you a path from which you can simply `hg pull` as from any other bundle or repository) and because when you move a bookmark, unreferenced commits are still shown in the history: you simply use the normal `hg log`.

        People should not need to receive “proper training” to use a tool. A 15 minutes basics explanation should suffice for everything except the maintainers tasks. If you’re the VCS integrator, merging stuff from hundreds of contributors, your core task is your VCS. If you’re a programmer, your core task is programming, not fighting with the VCS. It’s nice if you can do wizardry with it, and others will be grateful from time to time, but it should not be a requirement for regular work.

      • arnebab October 14, 2016 at 8:17 pm

        > a few subtle changes can save people from getting into situations everyone complains about

        I’ve been waiting for that to happen for years.

        What you show is that 3 of 15 commands are dangerous (I’d add checkout, which already shows 6 different ways to use it in the first paragraph of its help page). These 3 commands are also needed pretty often.

        What I see is that during a given stage in their life people are not willing to accept tools which require them to go deep when they are not their core task. They want to concentrate on the things they specialize in, not on stuff someone else puts between them and the task they want to do.

        And if people have to do new stuff, they assume it works like the stuff they already know – which is a reasonable assumption for any well-designed UI: designed for the existing users instead of expecting the users to re-learn everything (except where the other way to do things is vastly more efficient). Anything else creates lots of re-learning work – and needless re-learning equals wasted time/money.

      • SavageTwinky October 15, 2016 at 8:59 am

        Checkout is not dangerous, I’d say the only confusing part about it is whether or not you’re switching a branch or just checking out a specific folder and modifying you’re working directory. Its another overloaded term but one that does not change the state of history or branches, only you’re working directory.

        “they assume it works like the stuff they already know” This is a dumb assumption for people that will likely never learn anything new. If its new and different why would it work like things you already know? Almost every source control is the same, except when you start looking them in detail and they all do things a little differently. Git is not a tool you have to go insanely deep to learn. It’s a fairly trivial, with man pages that are unclear. In my experience training developers once they get around the rebase/reset it becomes business as usual.

      • arnebab October 15, 2016 at 10:49 pm

        > Checkout is not dangerous, I’d say the only confusing part about it is whether or not you’re switching a branch or just checking out a specific folder and modifying you’re working directory. Its another overloaded term but one that does not change the state of history or branches, only you’re working directory.

        What you described right now sounds pretty dangerous. For many people it’s a “just delete and re-clone” situation.

        > “they assume it works like the stuff they already know” This is a dumb assumption for people that will likely never learn anything new. If its new and different why would it work like things you already know?

        Because it fulfils almost the same usecase as that older tool.

        > Almost every source control is the same, except when you start looking them in detail and they all do things a little differently. Git is not a tool you have to go insanely deep to learn. It’s a fairly trivial, with man pages that are unclear. In my experience training developers once they get around the rebase/reset it becomes business as usual.

        The hard part about git is that when something goes wrong you suddenly have to go pretty deep, especially to understand the solutions in tutorials.

      • SavageTwinky October 16, 2016 at 1:47 pm

        How would deleting a repository and cloning solve probelms with a branch change or discarded changes? Again youre answer to the issue with git checkout is you have no clue as to whats going and unwilling to figure it out. Svn, perforce, mercurial… can get you into similar situatios with a similar command… again this isnt a git specific gripe but where you want the tool to understand and presict you want to do.

        And non one should expect something that solves the same use case in a slightly differnt manner to wok exacly like other tools. No source control is identical and they all do things slighly different. You dont have to go “deep” with git. Its a really simple tool, hard to memorise (which all source control clis are reasonably hard). You just got to find a more reasonable guide than the official docemtation.

      • arnebab October 16, 2016 at 8:14 pm

        > deleting a repository…branch change

        you get rid of the change.

        > discarded changes

        there git just destroyed your work.

        I know that you’ll say “the user should have known how to do it”. You’re partly right – but only insofar as the UI couldn’t have made this failure harder.

        > hard to memorise (which all source control clis are reasonably hard).

        that’s where you’re wrong. Git could make this much, much easier.

        1. Do it like tools people already know wherever that’s not strongly misleading.
        2. Make help brief and to the point, and design the functionality of commands in such a way that help can be brief and to the point without omitting important parts.

        For Mercurial I can tell people: “just use `hg help` followed by `hg help `”, and they can answer all their questions by looking briefly at the help pages. For git the same advice can get them hunting for answers for hours (literally – I saw that happen).

        Part of this is documentation, another part is bad design which leads to unnecessarily high complexity of basic usage.

        > You just got to find a more reasonable guide than the official documentation.

        That’s again a failure of the tool.

        Git could be much easier to use. But it is not, and all the work the past half decade did not make that better. Maybe smartgit is an answer, I don’t know that, because where I have to use git, I can only count on having the official client.

      • SavageTwinky October 17, 2016 at 5:13 am

        Again i agree that git can be a little more complicated than it needa to be to understand but your acting like their arent simple solutions to fix the problem. And i can completely balme the user for behaving stupid when they dont fully understand something.

        The checkout example.. so you checked out a different branch. How does deleting the repo and recloning get you onto the correct branch? It doesnt. Its a stupid thing to do. Especially if you have unsynced changes. Thats failing to understanf how distributes tools work (i’ve seen this with mercurial)

        Discarding changes? Well all source control tools have shortcuts for Discarding changes on checkout. You really have to ask why are you trying to checkout on modified files. The process is flawed and all source control tools will lead to discarding modifications.

        Again you have to take a step back, git isnt wrong for being different. Some of your compaints with it arent flaws in the tool itself, as it depends on what you knew first. Other issues are excusing people for not knowing how to use a tool they depend on and approaching it mindlessly. You end up a burden on the team and cant be trusted with any really comlicated issues. Ive seen users that spend hours with hg and p4. You know why that happens? They arent aware of what they are doing and looking for a solution to a problem they dont understand.

  315. Jodes August 5, 2016 at 5:29 am

    I agree with this blog 100%. I want subsets. Subsets of commands that perform operations a developer in some situation might need. For arguments sake, even catering for the absolute beginner who just wants a linear save history. How hard would this be, for those who are so clearly comfortable with git, to create sets of commands that effectively acts as simple Subsets of the features? It would enable less git experienced devs to easily contribute to projects, leaving the complexities to the people who actually need it. Use principles of OOP abstraction: why have collaborators deal with unnecessary details?

  316. dh37 August 10, 2016 at 1:17 am

    “Specifying filenames completely changes the semantics of some commands…”

    Yeah, I noticed that too, and agree that it’s poor UI design.

  317. marnes August 12, 2016 at 5:26 pm

    This post is a great example of why no sane person actually uses the commandline for git unless you’re working on a headless server or something. Everyone uses a gui, not just because the cmdline is annoying, but because there’s too much information involved that a tui could never show properly. With a gui you can instantly see everything you need to see and more, with no effort or deep analysis, like branching, diffs, etc. I pity the people who use a tui for it: either they’re masochistic or they don’t realize how much better they could be off.

    • sfkleach August 30, 2016 at 1:34 am

      I love this comment. I have found SmartGit to be a fantastic tool over the years – working on Windows, Linux and Mac. And GitKraken impressed me too – and is free. SourceTree is free too but somehow I found it visually a bit busy.

  318. Ron Deijkers August 27, 2016 at 1:08 am

    I am so jealous. I wish I was able to actually determine the exact things I hate about Git. At this moment I am not even sure if I hate Git or Git hates me. I think understanding what you hate about git is the next stage…

  319. Holly D. August 28, 2016 at 10:41 pm

    I’m afraid I’ll have to break the 2nd, 7th and 8th ‘most frequent comments’. As a developer, I started with Git. I never heard of Subversion or anything else until a year later, and still haven’t used anything else.
    3 years later, I still cannot figure out how to do some basic things with Git. In fact, I know I can just follow the man pages but those are incredibly fucky and issues that can outcome of this mess are barely covered, or even less explained.
    I like Git for what it can help me to do but it’s a pain in the ass. It takes too many commands to do basic stuff, the terminology it uses is sometimes impossible to understand if you don’t have a fucking master’s degree and even tutorials over the Internet don’t cover rare issues you can have.
    Though I’m not against the fact to keep a ‘clean history’ (that is, not keeping purely useless commits, not to confound with removing the commits that ‘don’t seem professional’ because this is what’s unprofessional), Git is a piece of shit to work with this. How many times did Git tell me to merge branches just to do a simple fucking rebase of two pretty much identical commits? Two commits just being two parts of the same edits (because I like to play it safe) that I could not squash together via git-rebase! And the error message didn’t help; in fact, it indicated a third older commit as the error cause! After getting mad to eat my dick on the man pages, I just had a look at Google. It was because there were common editions of the same lines between ‘at least one of the two latest commits’ and the second one. ‘At least’, guys, means ‘one up to infinity’. I checked, I think both newer versions were in conflict with the previous. Since I had other shit to do than:
    1. waste my time with many, too many, oh-so many commands (that could lead to more errors) and
    2. make a temporary branch for just one squash,
    I decided to let it this way. Okay, maybe it’s a bad practice (while I keep thinking it’s a matter of view), maybe I’m still unexperimented, maybe I lack knowledge to understand Git’s man pages but frankly, out of this classic elitist thinking, the first question that pops in my head is: ‘Who, in the world, that needs a tool like Git quickly, wants to give a shit with all this nonsense?’. Sorry but even if a good programmer has to take time to learn its tools, Git simply just takes plain too many time to learn, there seem to be way simpler alternatives and we’re at an era where alternatives aren’t what we can call ‘uncommon’.
    Git is not all bad. It is just far from being great.

  320. Max Weber September 7, 2016 at 2:15 am

    git checkout -b newbranch origin/epic_branch
    git reset –hard origin epic_branch
    uh, use a / or use a space when referencing origin branches? You just gotta remember which one works for which task. Or, try the wrong one and at least you do get an error message. :-) git, designed by someone with no user interaction experience.

    • Max Weber September 7, 2016 at 2:17 am

      Typed it wrong.
      git reset –hard origin/epic_branch
      does use the / syntax. But,
      git fetch origin epic_branch
      does not. So, git fetch breaks the pattern of git reset and git checkout. Reminds me of the designers of Java at the turn of the century with one set of methods for vectors and a whole other (which do the same tasks) for arrays.

  321. Bryan September 9, 2016 at 3:19 am

    Is it really necessary to use socially unacceptable language? I consult blogs like this to become informed, not to be exposed to lower forms of communication.

  322. Ayverie September 9, 2016 at 12:17 pm

    I’m a new developer. I haven’t learned much yet in the ways of coding and the tech universe, but git is the only thing so far that has almost made me cry.

    • sfkleach September 9, 2016 at 5:09 pm

      For anyone struggling to use git effectively, I recommend picking up SmartGit/Hg. (No, I am not associated with the product in any way.) It has a clean and simple GUI that is exceptionally helpful when using git. I found it amazingly helpful and years later I use it every day. A FOSS git GUI client that also looks to be very good is GitKraken, although I haven’t used it in anger like SmartGit.

  323. Chris Zahrobsky September 23, 2016 at 10:54 am

    Thanks for this blog! Great comments!!

    Please put ” git add * ” into the useful command column. It’s one of the missing magic bullets. My biggest problem with GIT is that is like an automobile without any doors. You can see all sorts of stuff inside and obsess over the time and place the upholstery was fabricated, but how about getting people (your files) into the car??? Some posters have suggested GUI options, but I have yet to find a single one that allows you to add files. That’s, um, you know, what we’re really CONTROLLING in version control…

    The problem with ” git add -A ” (yes, the A is case-sensitive) is that it adds EVERYTHING you never realized was altered way out in other folders. Okay, you can .gitignore stuff like the Backup Visual Studio made when it “upgraded” your solution, but that takes extra effort. Delete the files at the wrong time, and they end up added AND modified for delete!

    For big refactoring jobs, I have resorted to a “safe” method of add + commit.
    1) Zip up everything you really need, preserving the folder structure, and put it somewhere else, because a) you might lose it, b) you might accidentally add a bunch of extra garbage that you can’t seem to get rid of, and c) it will come in handy in step 6.
    2) Attempt to git add just the things you want to commit.
    3) Stash / Undo those things that aren’t part of this feature (with git checkout)
    4) Commit, but don’t push it, then stash it all if it worked.
    5) Use a variety of commands to undo everything back to its unaltered state and/or the version that might be updated with potential merge conflicts.
    6) Unzip the changes elsewhere, and do a folder-based compare and merge.
    7) Add the merged file changes with ” git add * ” from the command line, then commit and push the reviewed changes.

    I personally like to review file change sets in a REAL merge program like WinMerge or Beyond Compare BEFORE I check stuff in for the world to see.

    Maybe I’ll get better at this, but I personally never thought I’d have to work with a version control system that made me appreciate the merits of Visual Source Safe!

    • savagetwinky September 23, 2016 at 2:39 pm

      what? All the GUI tools let you add changes… and they are much simpler to use. Git-Gui, smartgit, sourcetree… all alow you to stage or “add” files, or single lines to the stage, then view the stage. You can even use git add -i interactively add lines/hunks to you’re stage before commiting. From the command line just to git diff –staged to see what git commit will commit. Smartgit allows you to select the files and commit them directly without having to even fuss with the stage.

      I feel like not many people struggle with git add/commit it’s about the only thing people understand about git when they first approach it. Somehow you got off the trail and are completely lost in the woods, trying to blame git for a blind add all files also is a mistake in process not the tool. Like how is git supposed to know that you add a specific folder without you specific folder, generally the commands are for the entire work space unless you specify a file/folder.

      There is a little nuance with these commands… but you’re process you described is totally batshit crazy. You went down the wrong trail my friend for a solution like that, and its not entirely gits fault.

      • rjubber September 24, 2016 at 12:23 am

        My god – that is the *very definition* of badly designed software. If somebody can go astray in that fashion then that proves that Git is poorly implemented. It’s worth repeating for software designers who don’t understand the basic concept – software is its interface. Any piece of software with a bad interface is bad software. If the poor chap has, according to you at least, been pulled along a nightmarish track that has lead to even bigger complications with using Git then that means Git is itself fundamentally flawed.

      • savagetwinky September 25, 2016 at 9:23 am

        But its not badly designed. To me the stage was a new concept, there’s no “right” way to handle the behavior here because the design is slightly different than other source controls. Git add stages modifications. It can’t determine if an untracked file is a modification you need to add or an artifact of you’re build system so the design is to explicitly call them out. Is this design bad? No.

        But the developer’s solution shows a failure on his own problem solving skills, Git add didn’t do what he assumed it would do (likely add the current working directory), found an arg that didn’t do what he needed and than extensively worked around it. What he needed was a very trivial and basic explanation of how to use git add in common scenarios, which there are thousands of online tutorials he could of used to easily find a solution or explain how git add works with/without a path given.

        Git didn’t make him work around a problem in a nonsensical way instead of figuring out what git add -A does and find a solution. And no one ever will know how to use anything this complex right off that bat, that’s true for all source controls. They all have their intricacies and behave a little different, so depending on what you’re coming from you’re presumptions about how it should work are different. Could the documenation be a little better, yes, could some of the names of the commands be simpler, probably? These are just tools and if you don’t know where to put the nail don’t blame the hammer…

      • arnebab October 14, 2016 at 8:24 pm

        I could start to say exposing the stage to every user was a bad idea. And that’s what I will do: Exposing the stage to every user was a bad idea. It is bad design and people stumble over it. There’s .gitignore to get rid of artifacts. The stage replicates that and adds something more on top.

        > These are just tools and if you don’t know where to put the nail don’t blame the hammer…

        If the hammer has a big hole in the middle of the head so you have to hit the nail with the corner, then it’s the problem of the hammer when users don’t manage to hammer in nails (or rather: it’s the fault of the person who told the user to use this kind of hammer). The hammer is then not designed for the majority of users but for the small minority which need to hammer in nails around a nose which should not be hit.

    • sfkleach September 24, 2016 at 7:01 am

      Tryt SmartGit. It does everything you need.

  324. Andaluz September 24, 2016 at 1:25 am

    Hahaha I like this post. It’s indeed not easy to learn, but don’t you overdramatise? I don’t consider myself a git expert, but to use git in terminal, I first make some aliases, like: git checkout = git co, git branch = git br and so on. This way I reduce the amount of typing.

    When I work on a project, I regularly do:
    git init .
    git co -b test (I use small names like: test, alpha, beta, fix, bugs, …, so I don’t have to type a lot)
    git co master
    git merge test
    git co test
    …add another feature/page/whatever…


    git push
    or
    git push origin branch-name


    create patch and mail to the maintainer…
    I think some coordination is just necessary. You can’t just work together on the same file and expect Git will make it all fit your code in the right place. It’s like two men share the same steering wheel.

    The coolest thing with Git is, to checkout an old commit, analyse the code and go back to the HEAD with a few simple commands. Where I work now, they still use VSS (SourceSafe), how about that!

    Git rebase is like an emergency tool, but if you do it the correct way, you don’t need rebase.

    The Git commands are confusing yes, let alone the documentation. My documentation is SO, google and so on. But the official Git document is like abracadabra to me, English is not even my native language.

    I like git because you can mess around with code, if it’s too messed up, just go back to its finial state: git reset or git reset –hard. Even if it’s just one file, git reset –hard is just so easy to type. I don’t even use git checkout file. You can also make an alias like : git resh (for reset –hard).

  325. Leonardo Quenta September 26, 2016 at 10:15 pm

    Hey, very interesting you criticism against git, i mainly understand it, but i think you don’t touch the most important thing in any version system that any version system has resolved so far, the merge’s hell, as far as i know it’s practically impossible to two or more devs work on the same file without rebasing and stomping badly the changes of another dev at the same time.

  326. Norbert Somlai September 27, 2016 at 9:31 pm

    If GitHub were called SVNHub, Git would be dead by now.

    I used Git on a one-man project between my laptop and desktop and the repo was on a local NAS. I always committed and pushed, never even had to merge anything. Still after a month I noticed I somehow managed to get a single file of a multiple-file commit go out of sync. Git happily reported everything is fine, no matter what. I spent a few hours trying to restore that change, as a beginner (with 25 yrs of experience with every other VCS) I didn’t stand a chance among the million commands. Finally I copied the changes manually from the diff report. I’m lucky it was just one file. Because of this data loss, I lost my confidence and went back to SVN.

    I feel that most of the concepts are renamed from well-known VCS concept names to something else for no real reason, just to yell the difference as loud as possible. This makes Git like the 90’s command-line Linux with the weird key combinations and ever-changing command names.

    As a programmer, I have enough complicated shit to learn and deal with. I don’t want to fight with my VCS, too.

    • Andaluz September 28, 2016 at 7:13 pm

      The fact that you said that you never had to merge anything, makes clear that you don’t understand how to use Git.
      Maybe you should look at this:
      https://www.atlassian.com/git/tutorials/comparing-workflows/centralized-workflow

      • arnebab September 28, 2016 at 8:57 pm

        Did you actually just blame the user for not making the workflow more complicated – as a reply to git failing to do in the most basic workflow? That’s seems surreal…

      • arnebab September 28, 2016 at 8:57 pm

        s/to do/to do its job/

      • Fbasm Hole October 25, 2016 at 5:23 pm

        GIT is obviously a joke, the documentation of git (your link) is so big, how many hours i need to spend to read it and *fully* understand it, just because i want to add something in server whereas i’m the solely developer right now ? i just upset right now because i have commit/pust failed the ask me to rebase or merge, then rebase failed again and i need to abort rebase. Then commit/push faield again due to merge unfinished. “merge unfinished” ? So now i merge and get fatal error and no idea how to fix:

        “0 files committed, 1 file failed to commit: Merge remote-tracking branch ‘origin/master’ # Conflicts: # build.gradle error: commit is not possible because you have unmerged files. hint: Fix them up in the work tree, and then use ‘git add/rm ‘ hint: as appropriate to mark resolution and make a commit. fatal: Exiting because of an unresolved conflict. during executing git -c core.quotepath=false commit -F /tmp/git-commit-msg-.txt –author= — cannot do a partial commit during a merge.”

  327. Oksana October 6, 2016 at 1:16 am

    git is ridiculously hard to learn. Developers who learn git inside out have spent tens of hours which they could have productively used on their *actual* work. Even after all that, when asked to do simple operations, they have to go to stackoverflow to figure out if “ours” and “theirs” are the “usual” meaning or reversed meaning in this scenario.

    git is a religion, not a piece of software, and git fanatics’ top competency is not git, but attacking people who say anything bad about git. git fanboys show cult-like behaviours.

  328. yyz October 13, 2016 at 9:39 am

    The fact it has 778 comments tells me that I’m not out of touch or too old when I state: Why is this so complicated ? I’ve developing real time systems since 1993 – on my current project I had to finally get a grip on “git” .. it totally looks like they didnt know what they were doing in the first place, and all the —- ( git stash -u .. ) the “-” .. cli options that actually fix and make it normal, should have been not an “–” but the default. What really makes me not ok with it, is not the learning curve – is the INCONSISTENCIES of failed procedures. Black Holed commits. not okay.
    I design stability systems for Aircrafts; right now we find ourselves (wasting time) building an interface to safely integrate open-researched-systems (using git) into proprietary systems, by “safely” we mean “taking care of all the absurdities that ‘git this, git that’ can bring into one’s project, in this specific case, to a zero level, .. ” .. else “Ladies and Gents, we wont be able to land the plane today because the landing gears are telling us that they were not commited, ever” ..
    it’s okay if you are coding Tetris part 5 .. but not okay really. I am interested on learning
    how others rebutted this insanity and if any other framework to interact open source systems into proprietary ones, with an actual safe factor/filter” .. Open Source could be even wider into private projects, but as the article well states, .. who has time to read instructions in Greek ?

    • SavageTwinky October 15, 2016 at 9:59 am

      First, the stage is completely fine, its simple, easy to understand, easy to use, its not dangerous. Second the stage isn’t intended to get rid of artifacts, clearly don’t understand what its for. One just hides files making it easier to find modifications you do want to add. The other adds modifications/files to be committed later. Git add does exactly what it means. Where most version control systems on commit will not commit new files unless they have been added. The stage only adds file modifications to that barrier, which to me seems more consistent. I want commit a new file add it, I want to commit a line add it, I want to commit all changes in a file…

      I think you don’t understand my analogy. The hammer is a fairly small part of the big picture, how you tackle problems, how you’re team works. If we are looking at just git… Git is not that specific of a tool. Its is a very simple change control system that is distributed. There are details in how git works that users should be aware of. The same could be said about every tool though, especially how complex version control systems are. The problem is documentation, git itself is fine. But the documentation problem is easily remedied by 100’s of guides you can find online. The other problem is a couple of commands that do things a user might not be aware of. That is also easily remedied by a user taking 20 mins to understand how it works before attempting to use a particular command or checkbox. These are options you or a user has to choose to use. In fact I’d say a good rule of thumb for almost everything is, if you don’t know exactly how it works, spend two or 20 minutes and look it up before wasting hours and another developers time saying git did something stupid, I don’t know what I did to cause it.

      I agree a lot of what was said in the article, although there are additional non git related work flows that cause additional head aches for people. My biggest gripes with using git is users that throw there hands in their air immediately after a git problem happens, and complain about git not doing what they want it to do and then unraveling bu bu bu I don’t actually know what its supposed to do. This other tool I’ve been using and know intimately does everything I expect it to, why doesn’t git. I’ve had to change source controls on a regular basis, I think people have a hard time separating real issues with git and their own problems adapting to changes in process and tooling.

      • arnebab October 15, 2016 at 10:46 pm

        The inherent problem in the index is that you encourage users to commit a state they never tested. Sometimes you want to do that, but it’s not the default for new users.

        I understand your analogy, and I think it’s wrong: Git isn’t simple and it is not a hammer. It is as if you needed to understand 10 tools just to hammer in a nail – because someone else on your team needs all these tools.

        Requiring users to take 20 minutes before selecting an option is a plain user-interface failure.

        And git makes the adaption unnecessarily hard – without a hint of trying to get easier over the years.

      • SavageTwinky October 16, 2016 at 2:25 pm

        Thats not true. The index only matters if the users work flow requires them to commit selectively. But it allows them to avoid lots of commits, modify > test > add. If you make bad changes you can clearly see what you did. Ive known plenty of developers that dont know how the stage works but completely still use the commit everything once ready method. If you take 30 seconds and read what commit does with a couple swtitches… you never need to know about the index.

        My analogy is to stress the larger picture, where you work flow and problem solving skills are much more important.. Even stated that all sorce controls are complex… but if your unsure or ran into a problem… take a deep breath and tackle the problem sensibly, its very easy to find a solution then. Git isnt that difficult to blame nonsensical behavior on it.

        Also no interface is comlpetly understable if its different. Ive worked with several teams that mived from centralized source control to distributed with a centralized. No one will understand why they have to sync based on the ui without some additional ui. Or going from git to svn why are all branches like web links. And this is especually true with more unique features like index, rebase, patch mq, perforce reconcile… expecting a user to understand a command by the ui alone is unrealsitic. Techlogy and tools have moved so fast that willingness to admit you dont know something and take 20 mins and learn something new its ALWAYS the right choice. Especially if its a tool your not used to using while trying to use it.

      • arnebab October 16, 2016 at 7:58 pm

        My experience with teaching SVN users Mercurial is that I tell them “update is split into pull + update, commit is split into commit + push”, and all the rest works. Right away.

        For commit: The obvious action for new users (commit everything) is hidden behind a flag (commit -a). That’s almost a guarantee that people will get it wrong, because they (sensibly) assume that the default actions are well-chosen.

        But with git the default options are partly historical (can’t change what’s used in scripts) and partly optimized for experienced maintainers – the people who could most easily adapt options for their use-cases.

      • SavageTwinky October 17, 2016 at 3:17 am

        Your explaination to users for mercurial us insufficient.its actually not that simple and users that dont have the capacity to figure it out will end up running into similar questions, why am i merging? Or run into simalilar issues, get confused on the log display. Or take someone thar learned git first. Doea that make svn’s interface and features wrong? No that would be stupid to make that assumption. They are different, get over it. Neither is more of a right work flow or default action. You cant blame git for users assumptions.

        Secondly your assuming git is worse because of the differences which is also wrong. It doesnt have to behave the same way. The stage is an additional feature . If you run git commit without a flag and no staged changes it will let you know its an empty commit. Its a quick look up and you can move on with your life. The stage is a trivial concept with some changes to the interface that are necessary. And source control like svn and perforce dont protect you from untested changes. You need to remember to update on a regular basis or you could be testing your changes with an out of date environment.

      • arnebab October 17, 2016 at 6:55 am

        In practice they do not (or rather: once they do advanced stuff, most are already comfortable with the basics without having had to get taught explicitly). But many do with git, and that’s the point.

      • SavageTwinky October 17, 2016 at 9:24 am

        See my experience is different than yours. Most developers ive helped transition from centralized to distributed end up struggling with understanding what makes distributed different. This is especially true if you trie to dumb down the workflow a few commands to a centralized work flow. When they deviate all hell breaks loose. And this is from the perspective of the command line is a last resort. Unless you have to learn via cli and day to day tasks is really clunky.

      • Alex Neundorf October 17, 2016 at 8:03 am

        This discussion here with SavageTwinky actually kind of proves the point.
        Of course if I have a problem with git, I can find multiple answers how to fix it on the Internet. Usually all of them consist of multiple steps, all of the suggested solutions (for the same problem) are different, and they are often accompanied by an explanation why these commands are perfectly logical.

      • arnebab October 18, 2016 at 7:09 am

        That’s something with which I did not see big problems. For that it normally sufficed to tell people “every repo can be a server”.¹ I taught people either how to use the cli or how to use TortoiseHg – the cli was easier for all those who were already used to terminal programs. I myself use the commandline or emacs vc-mode (with the cli for anything more complex than just committing what I did).

        ¹: For git that’s not that easy, since you have to take care that you don’t try to push a branch which is checked out in the serving repo.

      • SavageTwinky October 18, 2016 at 10:38 pm

        Well either way, the differences in commit behavior are trivial for most users, if you try to commit with nothing staged, it basically tells you. The real big problems where people may want to delete an reclone are always around using reset incorrectly, or stumbling on rebase because someone told them to use it. Everything else is relatively minor issues to figure out. The learning curve for git isn’t so much worse than mercurial but there are a couple of clear improvements so people don’t completely fall over themselves.

      • arnebab October 19, 2016 at 6:47 am

        > there are a couple of clear improvements so people don’t completely fall over themselves.

        I’ve been waiting for these to happen for years, now. But they just did not happen, so at some point I stopped hoping that they would someday come.

        You can do great stuff with git, but its problems simply don’t seem to get fixed, and all of these great things are possible with Mercurial as well – and the problems of Mercurial do get fixed one by one.

      • SavageTwinky October 19, 2016 at 6:49 am

        well thats a problem with open source in general, the people that fixed the issues renamed it mercurial, or started from scratch instead of fixing a few issues.

      • arnebab October 20, 2016 at 12:22 am

        Mercurial is not a fork of git. Mercurial is a feature-equal version tracking system which was started at about the same time as git but is much easier to use and easier to adapt and scale (yes, easier to scale, just ask the folks at facebook: https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/ ).

  329. Smitty October 14, 2016 at 11:40 pm

    And here I thought I was the only idiot that was struggling to make sense of Git. I have to refer to a cheat sheet cross referencing subversion vs git commands every time I want to do anything more trivial than a git clone or a git commit.

    I must say, the whole model of distributed revision control looks like a mistake to me. I really haven’t heard a good argument for it that can’t be solved with the staging/golden subversion repository model (with branches of course) – which is (to my mind) much much easier to understand, and work with.

    I wholehearted agree, it seems to me, git was designed to make Linus’s job easier, and nothing else. I have absolutely no problem with that, it’s his right to manage his source tree however he wants. I’ll stick with the KISS principle and continue to use subversion until something better comes along – and git ain’t it.

    • arnebab March 31, 2017 at 7:39 am

      Looking at the usability of Mercurial compared to Subversion, I consider distributed revision control to be much better than having a centralized repository. But then the difference between actual usage of Mercurial and Subversion boils down to

      1) “you split svn update in hg pull -u and hg merge”,
      2) “you split svn commit into hg commit and hg push” and
      3) “conflicts are no problem. They do not block your work”.

      The core advantage is that you always have Mercurial available anywhere in your filesystem: Just run hg init to start a new repository. That’s it. It’s available instantly and you can synchronize from and to it as if it were on a server. It’s almost frictionless — and that’s neither the case for subversion nor for git.

  330. Pingback: Buy WordPress Hosting In Grand Forks – Web Hosting Guru

  331. steveko October 19, 2016 at 4:35 pm

    Have you tried Gitless? http://gitless.com/

    • arnebab October 20, 2016 at 12:41 am

      Not yet, but it seems saner than git.

      The paper about it is pretty interesting ( http://people.csail.mit.edu/sperezde/pre-print-oopsla16.pdf ). If nothing else, it clearly shows the massive disconnect between git experts and all other git users.

      The approach in the paper might also be interesting to improve the user interface for Mercurial (where the required changes to improve the workflow should be possible to do with an extension).

    • arnebab November 8, 2016 at 7:33 am

      Status: I exchanged some lengthy emails with the authors. Two of their purposes seem split due to inherent limitations in the implementation of git. I think they could reduce the number of purposes from 6 to 5 if they implemented gitless on top of Mercurial instead of git – and with that further reduce the complexity of their interface.

  332. Pingback: 10 Things I Hate About Git Far More Than Steve Bennet Does | State of the Machine

  333. Kimball Johnson October 22, 2016 at 12:21 pm

    I really appreciate the effort you have put into erecting signs that point at this despicable situation that GIT and its designer have created for development teams worldwide.

    The primary value-proposition defect that GIT has caused is to lead a generation, maybe two, of developers into believing that ‘personal productivity’ will ever translate into enterprise value.

    Developers who are aware of and appreciate the difficulty that managers face of translating the value of the work-product recognize that the value of their work must be evaluated within the context of how that value can be translated and transferred into the value store of the enterprise.

    It it is that context that the value of GIT to developers must be considered and evaluated.

    Regarding the overall and specific challenges that GIT as a ‘situation’ presents to all of us, I have posted a blog containing my perspective on the very valuable work and insights you have provided thus far on this topic, which I believe is a very critical topic.

    https://stateofthemachine.com/2016/10/21/10-things-i-hate-about-git-far-more-than-steve-bennet-does/

    Thanks,
    Kimball Johnson

  334. karlyeurl November 4, 2016 at 2:55 am

    Very good article. I indeed believe that the UI of git is lacking.

    I am convinced that the reason why there is such a split between git gurus and the rest of the world is that, once you’ve learned the plumbing, you experience a shift in paradigm. As you know what git can and cannot do, you understand what git needs to do to get you to the state you want.

    Then the challenge is narrowed down from “google your problem and try random things until it works or clone a clean repo” to “find out what the right git commands are to do that stuff”. It becomes easy yet cumbersome, and that could be made better.

    I however love git for what it can do, unlike most commenters here who are just ranting.

    • steveko November 4, 2016 at 8:11 am

      >I am convinced that the reason why there is such a split between git gurus and the rest of the world is that, once you’ve learned the plumbing, you experience a shift in paradigm.

      I don’t really agree. There are certain conceptual challenges to grasp that fit into this category (for me, the fact that there is no special relationship between your local repo and the original repo it was cloned from). But there are lots of things that remain painful and broken, years later. I’ve spent a long time trying to wrap my head around the reset command’s various options (even wrote a long stackoverflow answer on it), and yet it still makes no sense to me and I can’t remember any of it.

      Much of Git is just too far removed from what my brain is willing to accept. The real difference between “Git gurus and the rest of the world” is how readily your brain accepts completely arbitrary structure.

      • karlyeurl November 8, 2016 at 4:37 am

        I think you misunderstood what I meant.

        I am not saying that the git commands make sense as a whole. I don’t think they really do (hence my complaint about the interface being cumbersome). Sure, it would be worse, but it could also be a lot better.

        I am saying that, once you have found a command on StackOverflow that might just solve your problem, checking (e.g. in the official doc) what it does is easy and understanding what will happen beforehand is easy.

        Another example: understanding the state in which your local repository exactly is is a huge step forward to solve any problem with git. I am willing to bet that most people who complain about git being hard don’t understand that.

        Maybe that’s just me, but I feel that understanding what a tool does (really, really does) makes the difference between the sorcerer’s apprentice with educated guesses and the true master. As we use to say, assumption is the mother of all screw-ups.

        Again, the interface of git is… meh. I’m not too surprised you don’t know the git-reset too well. Neither do I. But from the doc, I can craft the command I need, as long as I completely understand what needs to be done.

      • arnebab November 8, 2016 at 6:53 am

        @karlyeurl: What you describe (crafting the command from the doc) sounds terribly cumbersome. To me the wizard level is not even having to think about the tool: the commands just flow naturally. It’s the state I sometimes attain when hacking on a problem I see completely in my head while using a library I know by heart.

        It’s also what came pretty easily for Mercurial when I still did complex tasks with it (nowadays there is rarely anything for which I have to do more than consulting the built-in help for less than 30s to get the exact option I need, since I just don’t need complex version tracking at the moment).

        I think one reason for this is that after using Mercurial for a while, the first assumption is correct most of the time. Because it’s not assumption which is the mother of all screw-ups: it’s wrong assumptions. And the core of bad UI is violating assumptions (which isn’t easy to avoid completely, since assumptions change over time, but it can be done worse or better, and git does pretty badly at that).

      • Savagetwinky November 8, 2016 at 11:50 am

        I think cumbersome is something I’d agree with. Git is incredibly cumbersome, and open source projects fork/pull request model just adds a additional steps to the entire work flow.

        I don’t think the index is particularly hard to understand, its just not in the normal workflow for most people and you have to take the time to understand what reset/add will do to the index. Expecting tools to work like other tools you know I think is an unrealistic expectation. Granted I don’t feel the index add’s any value over other source controls.

        I think there is a difference between actually being difficult to understand or a bit of a nuisance to work with.

  335. steveko November 8, 2016 at 9:41 am

    >I am saying that, once you have found a command on StackOverflow that might just solve your problem, checking (e.g. in the official doc) what it does is easy and understanding what will happen beforehand is easy.

    Sorry, I just don’t agree with this at all. I’ve run into quite a few situations where I couldn’t decipher the documentation. The only solution was essentially to backup the whole directory, try something, and see if it worked. Reset, Rebase and Rerere are all in that category, for me.

    >Another example: understanding the state in which your local repository exactly is is a huge step forward to solve any problem with git. I am willing to bet that most people who complain about git being hard don’t understand that.

    Maybe this is the root of our disagreement. I completely agree with your first statement, and consider that as evidence that Git is hard. You shouldn’t need to spend effort “understanding the state” of something in order to do something productive with it. The tool should assist you in telling you what you need to know, and guide you towards the things you want to do. Git does neither.

  336. wimarschippers November 22, 2016 at 2:17 am

    Don’t take this the wrong way buddy, but if you feel too incompetent to use git … then don’t! You do not have to, nobodies forcing you so why put yourself through the pain if you are happy to use Subversion?

    If you feel that “Most of the power of Git is aimed squarely at maintainers of codebases”, and you feel you do not fit the bill, then don’t use it.

    You can be cool and not use git ;).

    • SavageTwinky November 22, 2016 at 9:49 am

      That doesn’t work that well if you’re on a project that uses git. I’d argue any other method of converting a repo to another source control and working with both simultaneously is a worse solution than just using git…

      • arnebab November 22, 2016 at 10:08 pm

        Except if you know the other one really well and don’t need advanced features of git. But you’re right to some degree: git special cases have a way of creeping into workflows which makes it pretty hard to operate as a cross-tool project (there are even projects which don’t accept standard patches anymore).

  337. :Jeff F: (@jaFideler) December 15, 2016 at 9:50 am

    My biggest gripe about git is (and will always remain) that it’s way too easy to do something you wish you hadn’t…and then there is no way back.

    IMHO, a source code management system is the last place something like that should be true.

  338. aluckygit December 19, 2016 at 6:05 pm

    I’m very happy that I no longer need to struggle with Git, as I switched the company and here we’re using Perforce. \o

    I worked with so many other version control system and I really never had such a hard time as I had with Git. As someone already said the most simple actions need too many steps (as compared to e.g. Subversion) and the risk to get your local or remote completely messed up is way too high for a version control system.

    • Max Weber January 18, 2017 at 2:33 am

      Been a few years since I used Perforce but it was about as good as svn. The merge sucked from what I recall; but that mega-corp had a team devoted to doing merges and the team was not the programmers. How retarded was Bank of America. Very. This Functional Organizational Architecture was just the tip of the iceberg.

    • afinnell March 31, 2017 at 9:31 am

      If one turns off Force Push I don’t see how a remote repo can ever be messed up. I’m truly curious what you experienced? Rewriting the Git Log history is the fastest way to break a repo. Which sadly something like Rebase and Squashes can do and it’s not obvious. However, no pushes ought to be allowed if Force Push is prevented. To be even safer one can force all Pushes to be Fast Forward pushes. Then you’re really safe as it means no remote discrepancies are allowed.

  339. Yevgeniy Ivanov December 27, 2016 at 11:27 am

    I really love this site! I love item 6 the most! This is so true about this Git stuff. Thank you for writing it, now I know that I am not crazy, this is just the way things are.

  340. Gaetano December 27, 2016 at 7:23 pm

    That’s why exists gitless http://gitless.com

  341. Pingback: 10 things I hate about Git | thechrisshort

  342. GitSucks ForReal December 30, 2016 at 2:55 pm

    git can kiss my ass. has caused more problems than being helpful. f git right in the ear. seriously.

  343. Pingback: 10 things I hate about Git — Steve Bennett blogs – Afiuw Zumala

  344. Max Weber January 18, 2017 at 2:30 am

    git pull
    ….
    Unlink of file ‘.git/objects/pack/pack-00a5424497c8a88f6d91a212f8ec8bc707f50aa0.idx’ failed. Should I try again? (y/n) y
    Unlink of file ‘.git/objects/pack/pack-00a5424497c8a88f6d91a212f8ec8bc707f50aa0.idx’ failed. Should I try again? (y/n) n

    At least git reset –hard works.
    If I have to do git reset –hard all the time then why am I using this for a source control system. git reset –hard is analogous to just wiping out a directory with a new copy/checkout/pull. But, hey, don’t let any common sense fade the blind devotion of the “mid-career” geniuses. :-)

    • afinnell March 31, 2017 at 9:26 am

      You post an error that occurs because another processs is holding that file open (eclipse, intellij, another shell, or your paths are too long) and it’s Gits fault? This happens with SVN and any other SCM system when it tried a locked file is attempting to be removed. I don’t understand your perspective or context to the common sense statement. Is the error message bad? Should it go out and find what’s locked the file and tell you to stop the process? You shouldn’t have to use it.. It’s like installing a bad third party device driver and blaming Windows for blue screening, or even faulty RAM and then saying Linux can’t load. This is a strawman argument about nothing.

  345. Max Weber January 18, 2017 at 2:43 am

    Another Nth thing I hate about git is the risk it introduces into quality. Merging a truck load of streams at the last minute just before some regression test simply is bad SDLC management. Yes, it is done. Most “leads” and managers never took a single graduate course in Test nor SDLC. It wasn’t that persons in SVN/whatever did not realize the complexity of merging code together – they did; but that they knew this increased time to find bugs. A typical git project produces lower quality code (or is more expensive to test) due to inherently less “SIT” testing.

    • SavageTwinky January 18, 2017 at 8:57 am

      wtf? This has so much more to do with bad process then the tool people are using…
      SVN doesn’t prevent you from creating feature branches and merging them in all last minute. No source control can stop users from doing stupid things. The only thing git add’s is a layer of additional possible stupid with the stage (managing the index should not be imposed on users, its a bad way of handling selective committing). Open Source projects with git just have an additional layer of stupid on top of the tool itself. Bad processes are not git’s fault.

      • Max Weber June 3, 2017 at 12:22 am

        Actually it does. Having worked on at least a dozen large projects with SVN and around the same with git, I can 100% tell you SVN projects front-load testing and git projects rear-end testing. That’s the nature of the beast. If you read my other comments then you will know I observe GIT is chosen often so one person can lord it over everyone else, rather than participate in a team effort.

      • SavageTwinky June 3, 2017 at 2:42 am

        We chose git because it integrates with continuous integration servers like teamcity on a branch level almost effortlessly, we can build/release from any branch at any time and testing is done on specific feature branches as well as our main integration branch.

        If your apart of projects where people use branches to isolate their feature and do not integrate/test often, that’s a problem with people in your project. I’ve been on projects with SVN where people would not commit often and wait until the last minute to do so, causing similar rear end testing (or losing tons of work…). Not to mention SVN still has branches and allows for large or small features merged in last minute and an regression nightmare.

        SVN or GIT has nothing to do with how people work on a day to day basis, you can make both types of workflows work on either tool with little trouble. And blaming the tool seems to me a complete misunderstanding of what the problem actually is when your talking about work flow. I get it, git can be a bit difficult to use at first. But its not rocket science and its not to blame if a bunch of people choose to use it with poor workflows.

      • arnebab June 3, 2017 at 5:28 am

        @SavageTwinky: that you observed working git usage while Max Weber observed it to be broken just means that both of your experiences cannot be generalized — likely there are hidden variables in which the groups differ who you observed.

        Note that Max Weber gave pretty clear numbers: around a dozen large projects with either system. You however gave unclear information: You have been on projects where people … ← most people or some? How many projects? Were they of similar scale as the git projects?

        If many people chose a given system for bad workflows but fewer do so with another system, then the system might actually be at fault. One reason could be that every system has specific operations which are easier than others which in the end achieve the same goal. This way it favours these operations and pushes people to use them instead of others. Individuals can still decide against it, but on average people will move towards these easier operations, if there are no clear and continuous deterrents against that (like regular warnings).

      • SavageTwinky June 3, 2017 at 6:29 am

        I’ve swapped tools on many project to solve issues with workflow that… did not solve the problems. At some point you can take a look at the big picture and git/svn/hg/performce/cvs/ts… all do the same thing in slightly different ways.

        So committing on git generally takes 2 steps. Commit your files, and then sync with the server. Committing will push immediately. But it doesn’t keep your local workspace up to date, it only updates the files being committed and leaves a mixed rev working copy. Your trading one issue for updating for another. Both require manually updating and while one has a strong history of the state of the entire workspace, the other publishes changes immediately. It can lead to other issues but both require manually fetching/updating on a regular basis so you can integrate with the latest changes cleanly.

        Without git we wouldn’t be able create the quality of code we do at the pace we do. We use CI to build all branches and run unit tests, branches can be deployed in labs immediately for system integration testing safely without the instability of an integration branch. Then be merged into the main branch and tested again for integration. This was just not possible with svn because of how it integrated with teamcity. Maybe Jenkin’s can do it better? I don’t know, but lets not conflate the issues with a bad user interface with poor work flows with a powerful tool. I’d give up git in a heart beat to move to mercurial but I do not think it will make my day to day work any easier. It’ll just allow me to use remotefilelog from facebook and have many more lightweight work spaces, and save a bit of time fetching/cloning. But its not a work flow change. SVN can be beaten into this model but again just rearranging inconveniences.

        I don’t think more examples of good/bad developers serve any purpose regarding a tool… If your trying to use svn’s overhead in branch management as a reason why its better and keeps your workspace up to date then I’d say you haven’t learned how to branch correctly and that argument is a red herring. Or why git’s lightweight branches are superior to SVN in almost everyway. When branching is made easier on developers and they fail to adopt a workflow to use them properly I’d recommend just not bothering with them.

      • arnebab June 3, 2017 at 7:31 am

        I did not say that the branch overhead is an advantage, though it’s definitely possible to read my post like that. I also did not mean that changing the tool will instantly change the workflow (workflows have quite some momentum which takes time to change).

        What I mean is: The tool shapes how people work. There are quite a few things which do not work well or reliably when you start with git. One example is quickly whipping up local clones to test something in a clean environment and to push back from them if the test worked (or maybe even if it did not, just to record the result). Git can be made to do that, but that requires you to stray from the defaults (which will make your workflow incompatible to that of your colleagues, or even worse: You’ll all do some changes and nothing will work the same for anybody).

        This goes further: The tool even shapes the imagination of people. If you look at gitless, they published an abstract list of actions for version tracking software (in two academic publications). Yet they split up the task “provide changes” following the git split of a bare and a non-bare repository — a split which just isn’t necessary with Mercurial. So their level of abstraction was limited by implementation details in Git, and they did not see outside this box. This caused them to add an additional command to their list of “necessary actions”, which complicates the user interface for all users (they need to actually keep track of the state of the repository).

        I personally would prefer Git over SVN (if I had only those two to choose from), because I can make Git work purely locally, but given that I’ve seen great programmers work with plain directory backups and meld to exchange code, I would not base my judgement of the quality of people on their use of VCS (though I would prefer using Mercurial).

      • SavageTwinky June 3, 2017 at 8:20 am

        I think I’m more commenting on max’s explanation.

        The differences in tools lowers the trouble of using branches which allows for more branches on a team. And it seems that max’s argument was more against poorly developed branch work flows… and blamed the tool for lowering the effort to access those branches. He may also be complaining about the difference in updating leaving your local copy stale if you fail to update. You still need to update SVN manually to update your working copy or suffer writing code to api’s that no longer exist or were modified, and other subtle bugs in behavior potentially. GIT works on workspace atomically so it requires a developer to merge when syncing, not when committing, slight difference but not something that should encourage radically different work flows. Branching allows for more isolation but again any one just using branches for permanent isolation need to rethink their strategy with branches.

        Also… why can’t you have more local clones? Unless you have a repository that’s like 10+ GB history, its not a problem with the interface. GIt may have a scalable issue, which is why I pointed out mercurial and remotefilelog… but Microsoft is actually attempting a solution for this, GVFS. I think this is going to be a problem with any distributed version control that doesn’t support some sort of shallow cloning.

        I’d just like to point out that mercurial is a better version of git. It has better abstraction, extendable by plugins, and a sane user interface. Comparing the two I don’t think is relevant when the conversation is about svn vs git. Once you get past the interface challenge (and its easy if you just get smartgit)… then you just have to remember to manually publish/pull changes, and get easy branching. The differences of svn vs git related to workflow vanish.

        And I’d like to point out I’m talking strictly of git, not open source git work flows.

  346. realraven2000 January 31, 2017 at 12:46 am

    Problem with git: it’s everywhere and now the built in default alternative to TFS in Visual Studio. svn is so much easier and more productive with one-man development environments, but apparently not cool enough to be offered as alternative.

    • afinnell February 16, 2017 at 8:32 am

      I could never imagine wanting to use SVN for a single person environment. What does SVN provide that makes your life easier than Git? Git was BUILT for the single person environment. That’s the whole point of Git. Every one is in their own single person environment and all you do is share your transaction log with others, if you want.

      • realraven2000 February 16, 2017 at 10:02 am

        *I could never imagine wanting to use SVN for a single person environment* well first of all it integrates into Windows explorer and both submit and update are one-click operations. Then if you accept patches you can involve other people who do not know much about source control and it deals with merge conflicts in a reasonably graceful way. I really like thee way I can push up a build or a website with a singlee mouse click and do diffing and meaningful commenting in the same operation. Git seems like it puts an unnecessary step between publishing (backing up) and saving to the local repository. It is simple to see the local copy as the local repo and the remote code as the “branch”. And it is simpler than TFS as (by default) it does not lock files when you check out. This could present a problem with many users but I hadn’t got much problems with 2 users.

  347. Guster Flannegan February 7, 2017 at 10:16 pm

    I’m having a hard time with Git. My background is TFS source control in Visual Studio, which was simple and easy. With TFS, I could easily see my pending changes and compare differences MUCH easier. I would typically shelve my changes regularly to keep them safe, then create a final shelveset for someone to unshelve and review. They would then check in the changes (creating a changeset) to the main branch. After testing it would (easily) be merged through various branches to the live branch, manually resolving conflicts if necessary. I could view the history of any branch really quickly and easily showing me what files were added, changed or deleted. Now I’m in Git hell and it is so hard.

    • afinnell February 16, 2017 at 8:33 am

      This typically happens when an organization / team decides to replace TFS or SVN with Git instead of replacing the entire process. Git is not a good replacement for a Process that used to use TFS. You have to rethink your entire methodology here in order to get out of the ‘hell.’ My best guess is that the Dev Ops team has decided to ‘cleverly’ masquerade Git as TFS in order to keep the same work flow instead of adjusting the workflow itself.

  348. Adrian February 16, 2017 at 6:28 pm

    Agree. I hate the most is the documentation. It is so true. Some IT people nowadays like to complicate things and tell others they are so called geek. Some people switch to new stuff due to herd behavior

  349. Craig Main (@jimmymain) March 2, 2017 at 7:42 pm

    git is not too complex or too simple. it’s exactly as complex as it needs to be :-)

    • arnebab March 5, 2017 at 5:14 am

      This is the argument that what exists is the best which could ever exist. It could only be plausible, if there weren’t tools which provide the same functionality with much less complexity forced on the users.

      TLDR: The existence of Mercurial proves this argument wrong.

  350. uscareme March 4, 2017 at 6:44 am

    I came from a primarily SVN background and struggled a bit with Git. Ultimately I came to like it, including (some of) the features I thought were counterintuitive at first. Nevertheless, I agree. Git is packed with great stuff, but the docs are awful (not in the way most docs are, because they’re complete and detailed and explain both rationale and syntax) and really need a “git for users” version. And I think a different interface design would have made those first few months of mangled commits and stashes and merges much smoother.

  351. Cj March 21, 2017 at 1:48 am

    The statement: Git pull is exactly the same as git pull is completely incorrectly and should be changed or updated so as to not misinform readers. Git fetch only grabs the commits from remote and places it alongside your own commits if any exists where as git pull fetches from remote AND merges your current commit if you have something ahead and advances the head to this newly merged commit. Other than that I liked the article

  352. Thomaz March 23, 2017 at 12:21 am

    Im using git but it is so hard and complex to use. I recognize that it is very useful, but also is a real nightmare.

  353. mwithi March 24, 2017 at 7:53 pm

    That “git-arrows” diagram is the best explanation I’ve ever found on the web! Thanks!

    IMHO: I agree upon all points, expecially on the fact that is not the tool to be “so bad”, but its user experience.

    Best Regards (and Thanks!)

  354. Dave March 31, 2017 at 1:37 am

    We just recently went from using SVN where my life was easy and uncomplicated to the complicated mess that is GIT. Agree completely that simple tasks are overly complicated in GIT. We have of guys who relish the complexity where the rest of us just want to commit our code and go on with our lives.

  355. Talal Shoaib April 14, 2017 at 12:59 am

    I totally agree with the post…GIT is a mess…

  356. wavemaster April 18, 2017 at 5:21 am

    GIT is an epic time waster!

    I have no experience with revision control beyond the USB drive and my scenario is very simple: one developer, one tester.

    Started using GIT because of the VS plugin and the amount of hours wasted trying to understand what was going on is epic.

    Those responsible for GIT and the VS plugin should all be removed from their current position and be made to work on something a little less harmful, like a new DOS version.

    A new team can clean things up.

  357. Pingback: Installing enhanced bash autocompletion on macOS (aka restoring command line mojo) – taskUdo

  358. David Lloyd May 17, 2017 at 6:09 pm

    What does Git rhyme with? That says it all really.

    Having used pvcs, source safe, perforce and Git, and home rolled version control software, I am 100% certain that Git is:
    * The worst excuse for version control software I have ever used – by a country mile.
    * Massively over complex.
    * Software which virtually guarantees that someone in your team will mess up a commit really badly (probably every week) and waste lots of valuable time while the mess is untangled.
    * Software which makes it harder to see the ‘big picture’ view of what the current snapshot of the working piece of software actually is.
    * Software which makes developers want to avoid making changes.
    * A disaster.

    The few advantages it has for offline work are utterly destroyed by it’s problems.

    • SavageTwinky May 18, 2017 at 12:43 am

      “Massively over complex” is a massive overstatement… its index management is sort of unnecessary and complicates things, but most of what you are saying is completely untrue. And tools like smartgit pretty much nullify all of your issues, some of which aren’t even real issues…

      * Software which makes it harder to see the ‘big picture’ view of what the current snapshot of the working piece of software actually is.
      Like this is just false. Command line git status shows everything in the working directory that has been changed…

      • sfkleach May 18, 2017 at 2:17 am

        That’s absolutely my experience. If you are struggling to make git with for you, download smartgit, sourcetree or gitkraken and give it all a second try. I found that made all the difference.

  359. Smitty May 22, 2017 at 10:48 pm

    Aaaaarrrrrgggggghhhhh!!!!!!

    I just got introduced to the *sh*it concept of submodules. For the uninitiated, submodules are almost as good as svn externals, except they’re nearly unusable. You have to know they exist before you can even check out a repo.

    Want to :

    git clone ? You had better use this form instead
    git clone –recusive (because otherwise you won’t get the externals)

    How stupid is that ? It means you have to know that the submodules exist – throughout the source tree. Unlike in subversion where you explicitly ignore externals, the default in git is to ignore them.

  360. Smitty May 22, 2017 at 11:40 pm

    Oh My God !!!

    Ever had git refuse to fetch a source that you know exists. Then you realise it’s a proxy issue, so you decide to set up the socks proxy. So, add a line like this in your HOME/.gitconfig

    gitProxy = ~/bin/git-proxy

    and you set ~/bin/git-proxy according to this: https://gist.github.com/sit/49288

    Only to discover it doesn’t work !!!!

    Try replacing ‘~’ with
    as in
    /home/someone/bin/git-proxy

    It seems that a tool originally developed in the middle of 2005 (git) is still struggling with 1970s invention of ~ as $HOME

  361. John Simmons May 28, 2017 at 3:48 am

    Been forced to use GIT for a new project. Is the real reason developers have to put up with it is because it is a free tool?

    • sfkleach May 29, 2017 at 1:55 am

      The reason developers have to put up with anything is a matter of authority and not much else. Git has become a pre-eminent system, despite its shortcomings, because of its great strengths. I think Git is an excellent system but, sadly, I am “forced” to use a less modern version control system at work for perfectly good (if disappointing) reasons. I don’t blame that system though.

    • arnebab May 30, 2017 at 5:47 am

      As far as I can tell, being free is one of four reasons: the other three I see:

      * features: It wins against CVS, SVN and any unfree tool (though not against Mercurial).
      * authority: Linus uses it and git has lots of zealots.
      * company- and platform-mediated peer pressure: Github established itself as a community-leader, despite re-centralizing git-based development, and github stayed alive (the major platforms which provided free Mercurial hosting went away, except for BitBucket which was bought by git-zealots¹ at Atlassian and added git as their new focus).

      ¹: I stand by that claim and will happily provide references if needed.

    • AM April 29, 2018 at 8:57 am

      Git is pretty easy to learn compared to the other version control systems. I put together a tutorial if anyone else has to catch up on it in a short amount of time: http://codersfocus.com/git/the-gif-git-tutorial-top-twelve-most-used-commands/

  362. Smitty June 1, 2017 at 6:05 pm

    Want to do something like this ?

    svn export URL/path/single_file.txt

    It appears impossible in git without the use of a fairly complicated command line with at least three options. Or, use this helper script https://github.com/dasch/git-export/blob/master/git-export

    You know a tool sucks when you need to build a bunch of helper scripts to use it for basic functionality.

    • Smitty May 4, 2021 at 5:49 am

      Here it is 4 years after I first found this site, and I am STILL struggling with git.

      *SVN*
      svn copy URL/trunk URL/branch
      svn checkout URL/branch

      *GIT* equiv.
      git clone URL
      git remote -v
      git checkout -b
      git push -u origin
      git remote set-branches origin –add
      git fetch

      Verify that your remote name is “origin” or hurt!
      it’s possible that you dragged down a local configuration (PROJECT/.git/config) when you cloned and that set the remote to a totally confusing name like “local” or something equally stupid.

      What a joke !

      • Igor May 4, 2021 at 6:42 am

        Don’t talk about something you don’t understand. ;-)

        With SVN:
        svn copy URL/trunk URL/branch
        svn checkout URL/branch

        With GIT:
        git clone URL

        That’s it.

        Nothing else is needed to start working with GIT.
        Every other command you used is to actually perform changes to the code and push them out to the remote. Which I’m sure SVN also has the capability of. But to compare of what SVN and GIT doing for getting the code from “remote” – this is what needs to be done.

        Now I’m curious – how hard is it to create you own branch in SVN?

        In GIT its:

        git checkout -b .

        With GIT you don’t have to checkout/checkin the code – you start work immediately. And therefore no stupid messages, like

        “Hey this file is read-only”. Do you want to checkout this file?”

        And then how do you commit you changes in SVN?

        In GIT its as simple as:

        git add
        git commit -m “Commit_message”

        And then with SVN you also have to push you changes out to the remote server, right?

        With GIT it’s just:

        git push

        GIT will automatically crrawte the branch you were working on and wil make the changes.

        All in all – you compared apples and oranges.

      • Smitty May 5, 2021 at 4:58 am

        @Igor,

        it’s quite clear that *you* don’t understand.

        The two lines of subversion perform the equivalent of the six that are required to do it safely in git.

        Hell , I even explained why the “git remote -v” is really a necessity. Since you may pull down a local config (in fact, it’s guaranteed you will pull down *a* local config) which might have defined an absolutely rediculous alias instead of the default “remote”, and theoretically has aliased “remote” to something you really don’t want, you had better check how to push back to “remote”.

        Then, in order to have your local branch appear on the remote, you have to take a few more steps (unlike the single “svn copy URL/trunk URL/branch”)

        In short, as far as I can tell, everything I said is correct, and all the steps I indicated for git are *required* if you want to work safely.

      • arnebab May 10, 2021 at 8:09 pm

        @igor: You did not actually replicate the SVN task. It creates a new shared remote branch and sets up the local repository to auto-merge changes into the remote branch on commit.

        Smitty actually understands both subversion and Git, while you’re lacking the understanding of svn to actually replicate the task.

        What Smitty left out is that git requires you to do a pull before pushing to the remote branch, but only if there are new changes on the remote branch. That can be a good thing, because it makes merging explicit, but it makes git look even worse in comparison.

        @Smitty: did you already try Mercurial? That has shared named branches which make your workflow much cheaper than with git without sacrificing decentralization.

        hg clone URL
        hg branch [branch] # will be created at the remote during push

  363. gitisthebest June 8, 2017 at 12:02 am

    I think you are a noob. Simple like that.

  364. Elhanan Maayan July 4, 2017 at 4:58 am

    Persnally i feel (by look at this debate and comments) that this whole git debukle has turned into a bad remake of linux vs windows all over where svn users (i.e windows) are happy as a clam using it while they are looked down by git (master) users with a mix of pity and contempt as though they were mentally disabled children who no longer considered to be named developers. Unsurprising who invented git in the first place.
    as someone who’s working in a closed company and NEVER required the services of a DVCS if you cannot answer a simple question of WHY would i want to switch to git , wewhat benefits it provides over my svn and why would investing an insane amount of time of resourrces to merit these advantages, and the discussion ends here.
    Git as a tool for developers has failed misrebly in a sense that it abstructs developers from doing their real job, the same way linux in it’s infancy failed to provide users with straightforward way to di simple things

  365. Red Baron July 6, 2017 at 6:51 pm

    If you are a beginner and have no coding experience and/or experience with version control, SVN is as much of a bitch as Git or any other similar tool. This applies to documentation, command line syntax etc.

    I’m not saying I don’t like SVN but being forced to be connected all the time (IF you want to have any version control whatsoever) to service that provides it is a nightmare that I certainly find to put SVN at a big disadvantage when you compare it to Git. Sure, you can say “Well provide localhosting for your SVN” but to this I will reply: “What if you are working for a customer, you connect via VPN and don’t have direct control over what happens with the SVN?”. It has happened many times that the servers of a customer just get f@cked and your version control with SVN just takes a huge dump on your face. No connection + SVN = manual (as in copy, paste, archive files and folders) version control.

  366. Pluto August 11, 2017 at 12:11 am

    I work with CVS from 10 years and I never found any particular problems due to CVS. I don’t understand why all the world wants to use GIT. Crazy.

  367. Pingback: Git Cheat Sheet | Andreas' Blog

  368. geowar1 September 7, 2017 at 4:44 am

    I agree 100% with everything you said. Period. I’ve never had a version control system be as much of a PITA as git. That said, GitHug Desktop does make it much more usable. The only git commands I occasionally have to use the command line for are: “git stash save”, “git stash apply”, “git stash clear” and “git reset –hard HEAD^”.

  369. Bryan September 9, 2017 at 1:02 am

    Is the “f” word really appropriate for an otherwise quality blog like this? I was always taught that such language is the substitute for lack of intelligence, and surely not to be used in a public setting. Disappointing.

  370. Neutrino September 18, 2017 at 2:56 am

    Didn’t see these things mentioned in the article, but a couple of issues which imo help to make git as useless as it is ubiquitous.

    1. Can’t move anything and keep it’s history, which you can with svn and Mercurial.

    2. Can’t revert changes in a way that is at all useful. If you need to revert past a merge git will error complaining of missing option -m which means you have to explicitly select which of the merge parents to follow. You have to do this for every merge you wish to revert. The revert option will only take 1 -m option at a time, so to revert past multiple merges you have to revert past every merge manually one at a time. Of course first you have to spend half an hour trying to work out which parent it is you need to go back through for every merge you are trying to revert.

    https://stackoverflow.com/questions/5970889/why-does-git-revert-complain-about-a-missing-m-option

    That a source control tool that can’t even save file history on move/rename or revert usefully has come to take over like it has is a disaster, and the git fans that have foisted this crap on the rest of us have a lot to answer for.

    • SavageTwinky September 18, 2017 at 8:18 am

      Number 1 is incorrect

      Number 2 I’m not sure what your trying to say. Git has anonymous branching so determining which series of changes you want to remove means just figuring out which parent you want to remove, and it removes all the changes that merge introduces.

      • Neutrino September 19, 2017 at 10:59 pm

        Point 1. You are mistaken. Git does not track file history.

        echo something > file1.txt
        git add .
        git commit -m “Added file1.txt”
        echo something else > file1.txt
        git mv file1.txt file2.txt
        git add .
        git commit -m “Renamed file1.txt -> file2.txt”
        git log –follow –pretty=oneline –abbrev-commit file2.txt
        14fe438 Renamed file1.txt -> file2.txt

        As you can see, only the last commit is logged. file2’s history prior to renaming is not retrieved.

        What Git does do is if you add a file to a repository with the same content as another file that has just been deleted from the repository, Git will assume it was the same file. There’s a bit more to it than that, but that’s essentially what it boils down to. At any rate this kind of guesswork is quite different from the proper file history tracking you get with other tools.

        Point 2. You understand me fine. As you say in Git reverting means having to determine which merge parent you wish to remove for every merge you want to revert. Since typically you will merge in other developers changes each time before you push your own changes to the repo, the effect of this is that to revert your last N commits you have to revert at least N merges (likely many more since every other developer will also have had to merge before pushing their own changes too). This process of selecting which parent to remove for each merge is something that has to be done one at a time. It’s such a laborious task that for someone who wants to spend more time developing than messing around with Git it can actually be quicker to just do the work again rather than even bothering attempting to revert in this manner.

        If you aren’t used to using tools other than Git it might surprise you to learn that this job of having to remove each parent manuually for every merge in a revert is something you don’t have to do at all with other tools. I’ve never had to got through this rigmarole before and I’ve used CVS, Sourcesafe, SVN, TFS, Perforce and Mercurial. I’m not suggesting for one minute that all these other tools are better than Git in all regards, but this inability to revert without it being more effort than copying the work over manually seems to be peculiar to Git.

      • SavageTwinky September 28, 2017 at 9:16 am

        Point one is still wrong, history tracks through name changes. Your doing something wrong
        $ echo blah > file1 && git commit -A -m “added file”
        $ git mv file1 file2 && git commit -m “rename”
        $ echo blah > file3 && git commit -A “added file3″
        $ git log –oneline
        c4d5b2c (HEAD -> master) added file3
        63f46da rename
        205f98f test
        $ git log –follow –oneline file2
        63f46da rename
        205f98f added file
        $ ls
        file2 file3

        Point two your doing it wrong. Git is intended to work in a branch heavy model, you shouldn’t be merging tons of small commits bidirectionally, and expect a single way to undo a bunch of small changes. Make a branch, do the changes, then merge the collective in.

        You can also filter your last N changes if you were working on it more like SVN and just revert the non merge commit changes… and it will work the same without every having to touch a merge commit.
        git revert $(git log -5 –no-merges –pretty=%h –author=”mememe”)
        I literally just learned how to do this in 20 mins, not difficult if you take the time to understand the tool your using. Optionally you can git revert –no-commit to create a single commit instead of 5.

        Another way is just checkout a different version of the file, although this doesn’t work with renames
        git checkout rev file

        The *right* way, work in a branch, merge with master regularly if its a large complex feature, then when your ready merge back into master. You’ll have a single merge commit that represents the entire branch. Use –no-ff to make sure to create a merge commit. You can even checkout a file at a previous index if you know only you’ve worked on it. If your really insane you can use –squash when merging back to disconnect your branch and make a single commit single commit without a merge.

        Tools are different, they solve different problems. Git is a branch heavy tool. I’ve used other source controls but the difference between you an me is I took the time to understand Gits design and strengths and use it to those strengths instead of complaining because I don’t know how to use it. I’ll agree that some commands are obtuse and its a bit harder to learn, but your opinion seems to be wrong and from a place of ignorance. I agree with the blog, its hard to learn. But I I find it worse if a developer is trying to use a new tool explicitly like its another tool. Its not SVN or Clear Case so don’t walk in expecting the way you learned how to use SVN or Clear Case be the ‘correct’ way to use a new tool. That’s just poor judgement.

      • Neutrino October 2, 2017 at 11:19 pm

        No I’m not doing anything wrong, you are just not understanding, probably deliberately.

        In your exmaple you’ve only renamed the file and committed. You haven’t edited the file, renamed and committed. If you do that (as I’ve already demonstrated quite clearly) Git will fail to track the file’s history, exactly as I said it would.

        The rest of your post boils down to “Git doesn’t care what you want to do. You have to do what Git wants you to do instead, and if you aren’t happy with that then you’re just ignorant”.

        Well you’re certainly entitled to your rather self-serving opinion. The problem for me though is that I have actual work to do, and spending my time working out how to execute nested Bash commands like this “git revert $(git log -5 –no-merges –pretty=%h –author=”mememe”)” in a Windows shell, or memorizing the umpteen completely unrelated things that git checkout does, or all the different commands I have to avoid to stop Git from losing my work, or what Git’s ‘design’ is (or if it even has one), does abolutely nothing whatsoever to help me get that work done.

        I measure the usefulness of something in those terms. If it helps me get my work done it’s useful. If it gets in the way of me getting my work done, it’s useless. in those terms Git is useless to me, and all the evangelical zeal in the world will not change that.

      • SavageTwinky October 3, 2017 at 1:13 am

        Your doing something wrong, if you use git mv it marks the file, if you don’t it will attempt to detect the mv which it will only be able to detect slight changes.

        Nested git commands? Just make an alias… also I pointed out several ways to do it. Not to mention this is assuming all your going to use is the command line. SmartGit or some gui makes everything trivial.

        And my opinion is not self serving. These are complex tools designed to solve certain problems or enable specific workflows. It would be like a carpenter bashing in nails with a nail gun because he didn’t want to learn how to use it. Git was designed to work in branches until your ready to integrate with master, if you do this you should never be in a position where you have to arbitrarily revert the last n merges you did, just the one where you merged into master.

    • Mac Weber September 27, 2017 at 10:28 pm

      Thanks, had forgotten how easy reverts are in svn.
      git has bundle files…. but, you’ll need a recipe to get anywhere with it. You can work with it like an offline branch; but, importing it to a server is a pita. –all, –tags, but you still will not get branch history.
      git is basically this conglomeration of one-day hacks all put together and marketed as a system. Nobody ever planned it out and nobody has ever done any overall design work, as far as I can tell. Every time something is broken there’s a new add-on or external script or maybe eventualyl a change; rather than fixing the root design issues.

      • steveko September 28, 2017 at 7:44 am

        >git is basically this conglomeration of one-day hacks all put together and marketed as a system.

        Well put. That’s also how I feel about the Linux/Unix command line in general, for that matter.

      • Max Weber November 8, 2017 at 2:34 am

        @steveko, years ago my friend came up with a User Friendly assessment for Unix, “Instead of User Friendly, Unix is User Hostile”. :-)

  371. Neutrino September 18, 2017 at 3:00 am

    “If you are a beginner and have no coding experience and/or experience with version control, SVN is as much of a bitch as Git or any other similar tool. This applies to documentation, command line syntax etc.”

    With svn though you can never destroy your codebase and you can always revert back to any point in history. With git you don’t even have that basic guarantee. Also svn documentation and command syntax is clarity incarnate compared to git.

    • Max Weber November 8, 2017 at 2:32 am

      git checkout
      “checkout” is actually support in other scm tools. LOL. git has a command called “checkout” but it doesn’t do what checkout does elsewhere, including Sharepoint.

  372. Neutrino October 5, 2017 at 11:19 pm

    An entry for the crazy command line syntax of the millennium award.

    git branch -d [branchname]

    Deletes your branch if it’s already merged.

    git branch -D [branchname]

    Deletes your branch whether you’ve merged it or not.

    The case of the command option is literally the difference between losing your work or not.

    • SavageTwinky October 7, 2017 at 1:23 am

      You don’t lose your work, reflog says hi. Branches aren’t fully cleaned up when you delete a branch head.

      • arnebab October 7, 2017 at 2:56 am

        In this case I must agree: You are sent to a chase for the right subcommand, then you can set your branch on the commit again. In this case, automatic gc should not kick in before the user has a chance to correct the error. Except if there was a second spelling error and the user didn’t realize that he/she deleted the wrong branch but rather trusted in -d not deleting a not-yet-merged branch (so the branch couldn’t have been wrong, after all only one branch got merged just now, right?).

      • SavageTwinky October 7, 2017 at 3:18 am

        Lets not forget -D is a shortcut for –delete –force
        If people just read the documentation… they could see there are much more explicit terminology and shortcuts are a bit vague.
        Granted it is a problem… like git clean -fdx these work like flags, and its seemingly inconsistent with git branch. It should really be git branch -df but likely there aren’t many cases where -f is applicable.

  373. Carl Complaint October 16, 2017 at 1:31 pm

    From the very first time I saw this “strange thing from another planet”, my hate for “nerds” has increased 10-fold. It is an elitist, convoluted, detached-from-reality parallel universe run by the proverbial nerd in their basement. Not a single concept or piece of terminology in this thing is even remotely understandable at first glance. And they’re not even trying to. A company uses Git? I won’t even apply for a job!

  374. helvete October 18, 2017 at 3:07 am

    What a biased point of view. If you criticize git that you have to `commit` in comparison vit SVN shouws your utter ignorance. Have you ever tried to cherry-pick?

    Another flawed assumption is that SVN handles more code-submitters better. Have you ever tried to automerge branches with SVN? You would thank for ever discovering the git. Not even mentioning tthe repository size.

    One could go on almost indefinitely. But maybe I am just tired and all the rant is just a funny sarcasm:-)

    Have a nice day

    • helvete October 18, 2017 at 3:10 am

      You would thank for ever discovering the git

      should read:

      You would thank [insert-your-deity-or-sanity] for ever discovering the git

      Something ate my pointy brackets and their contents

  375. sudhir500 October 27, 2017 at 2:59 am

    nice.. you are right.. but i think all these steps give more sophisticated way to mange files and avoid mistakes.
    I only hate rebase stuff.
    too confusing. :-)

  376. nlcatternick November 29, 2017 at 7:33 pm

    this is the state of art of repository for open source in 2017? and people complained about ADA?

  377. nlcatter November 30, 2017 at 4:36 am

    its free – its free CRAP

  378. Pingback: High-Level Problems with Git and How to Fix Them | Digitators

  379. Kevin Reynolds December 18, 2017 at 4:08 am

    I agree 100%
    Git backend is probably a fair VCS, but the UI blows bigtime. We went from discussing SVN from 5 minutes per release to discussing GIT to 20 minutes a day… Company has to dedicate a team to training and questions…. Use Git, expect to pay $$$$$

  380. Rambab January 26, 2018 at 8:41 am

    I totally agree , crappy solution for problem ..

  381. cyp February 9, 2018 at 2:59 am

    Great post! Unfortunately it is not the people that actually write the code that decide what versioning tool is used. I have used CSS,VSS,SVN. All worked ok. The way git does things is retarded. Some claims it is fast but is not. And it can be seen from the beginning when you consider things logically.

  382. Bachsau February 12, 2018 at 2:47 pm

    Well, as Linus once wrote: “The information manager from hell”. ;)

  383. Pingback: A year of using Git: the good, the bad, and the ugly – Ivan Krivyakov

  384. asdf@asdf.asd April 13, 2018 at 1:50 pm

    Being debated on is not a good sign. Git SUCKS.

  385. Jacques Laroche May 11, 2018 at 10:55 am

    Totally on point. Git is a godsend in terms of a system and in regards to it’s cost and how much user engagement it has fostered in the open source world. Unfortunately it is unbelievably convoluted. It is a sprawling mess that makes the simplest tasks a daunting, arduous journey.

    It is totally obvious the system was hacked together with a frenetic fury that never really considered how a normal person could use it without wanting to throw themselves into a river full of hungry piranhas.

  386. AG May 19, 2018 at 2:23 am

    Thanks for this article. I’m new to Git and was wondering why TortoiseGit seems to be little short of a nightmare, including a recent incident where it was swearing to me that everything was sync’d and up to date with the repository, but I could clearly see the projects did not match. Trying to wrap my head around all the intricacies and gotchas.

  387. Assimilater May 26, 2018 at 7:10 am

    This is from 2012, yet I stumbled upon this when looking up “what does repo do that git doesn’t” on google, it piqued my interest as git is probably the only software package in existence I don’t have any quips with (seriously every program’s terrible).

    Though it’s entirely possible your position has changed, I will mention for years of using git I have literally never used rebase, stash, cherrypick, reflog, etc, etc as per your update. As for push/pull/fetch/merge/status/log how is that different from SVN? It’s been several years but I’ve used SVN and distinctly remember doing merges, pushes and pulls, looking at a list of modified files, looking at the history to find where something went wrong…

    As for the complexity of the command line interface, there’s a reason I use gui tools like sourcetree, gitkraken, kdiff, tortoise, or whatever I can find wherever possible. Same thing with SVN or Hg…I never bothered learning the SVN CLI but I somehow doubt it’s significantly less hairy than Git. Hg is about the same

    The article was interesting though :) Like I said I couldn’t think of a complaint about git so it was good to stretch that a little I suppose

  388. A. Arnovitz June 9, 2018 at 3:49 am

    It is years later but you are still right on. I have used multiple source control systems over the years, including subversion, ClearCase, TFS/VSTS, etc. and I really am not impressed with Git for the reasons you stated. I especially do not like it for enterprise environments but unfortunately, it is being adopted more and more.

    Part of my distain is fueled by those that think Git is the end-all, be-all of source control systems and that everything else is total garbage. If someone else besides Linus had developed it, I don’t believe anyone would have used it.

  389. Pingback: Proud to be a Moron – My Journey with Git | Martin Kolb's Blog

  390. Ankita June 12, 2018 at 9:14 pm

    I resonate with you buddy. I think you should also mention git hooks. They are so easy with svn and with git again a lot of complexity :(

  391. Baur June 22, 2018 at 6:52 pm

    Here is my git cheet sheet, where I try to give good explanations of git terms and commands, from beginners to advanced.

    https://github.com/capslocky/shell-cheat-sheets/blob/master/git.md

  392. Baur June 22, 2018 at 6:54 pm

    Here is my git cheet sheet, where I try to give good explanations of git terms and commands for beginners.

    https://github.com/capslocky/shell-cheat-sheets/blob/master/git.md

  393. Prateek June 28, 2018 at 1:26 am

    Everything works in this world. What i have observed , when we were using SVN it was simple, easy and fast. But GIT is not simple, however perhaps this is because of distributed nature. I am trying to catch up GIT , i am new in this. One main question i would like to ask , what is best GUI tool for GIT in Linux operation system . For window we have TortoiseGit but i did not find this for Linux.

    Second question , what is best GUI tool for GIT ? How you see codes changes before committing into GIT ?

  394. The Life Sugar July 6, 2018 at 5:38 am

    I totally agree , crappy solution for problem ..

  395. iosif hamlatzis July 18, 2018 at 4:45 pm

    I thought I was the only one who hated git. thnx for the article

  396. welchie99 July 24, 2018 at 1:21 am

    Great article.

    I’m new to Git in the last 2 months and I am feeling the same pain. (And lost code and time due to inconsistencies in commands).

    Is you opinion any different now?

    • steveko July 27, 2018 at 7:40 pm

      Not really. I still think the git command line is a complete disaster, and overall the conceptual model is much more complicated than it needs to be. I wish gitless had caught on.

  397. Matt August 11, 2018 at 3:40 am

    When SVN was my day-to-day VCS, I learned the command I needed to use for a particular situation when I need to and it “just worked.” It was simple, intuitive, and easy to remember. It was extraordinarily rare that I needed to go back to the SVN book for reference.

    Now that Git is my day-to-day VCS (by critical mass/popularity, not by choice), I find that not only do I need to go back to Git documentation over and over (and over and over and over) again, I also need to keep a folder name “git-tips” containing text file snippets, and a folder of bookmarks to blog posts about git scenarios. I never had to do that with CVS, or Perforce, or Visual SourceSafe, or Subversion, or Mercurial, or Darcs, or… well, with ANY other VCS I’ve ever used.

    Go back and re-read that previous paragraph again. And one more time for good measure. Let it sink in, because that experience is commonplace in Git-world.

    Does Git suck? No, I don’t think so. Is Git overhyped and overvalued? Absolutely. Nearly all VCSes are perfectly adequate for the most common day-to-day use cases. It’s when you encounter problematic edge cases where they really start to differ.

    Unfortunately, while Git has the power to address many of these cases “natively” (in other VCSes we addressed those edge cases by hand – like the so-called “ghetto merge”), the syntax and concepts are so arcane that the benefit of having that power is eroded by the maddening complexity of trying to take advantage *of* that power.

    • sfkleach August 24, 2018 at 6:16 pm

      Nice comment. In my case I found SmartGit was the way to make git friendly and accessible for most operations. There’s still a few things I go to the command line over. But I strongly recommend picking up a cross-platform GUI client such as SmartGit, GitKraken or even SourceTree. This doesn’t fix the underlying issue that git’s conceptual model is inappropriately complicated, the command line options are unintuitive and complicated, and key use cases such as previewing merges are awkward. But, for me, SmartGit has made me love git & centralised VCS is no longer of interest to me. I need the ability to manage my code evolution with full version control without a network connection & git delivers that with excellent performance.

  398. pouet August 23, 2018 at 8:46 pm

    I completely agree with this, and I’d even say Git has some issues that aren’t mentioned here. One of those is that it’s really hard to have a cvs policy that allows to keep a “clear log” using rebases and maintaining a large project that has several subprojects while still being able to roll back to a previous version in prod and maintaining parallel dev states, especially separating bug fixes branches and new features branches. In my company we have settled for a policy that is really far for clean but works quite well for us as we’re a small team. The model is a bit inspired from git-flow :
    – the production state is fully represented by merges on the Master branch. Each merge represents a single stable delivery, usually including new features. No one is allowed to commit directly on it.
    – ongoing developments are done on a “dev” branch. Once it’s reaches a state considered stable (all new features on it are finished and tested), the branch is merged back into Master and delivered in production.
    – every subfeature is made on subbranches of dev. If “dirty” commits are done on it, a member of the team interactively rebases the commits and warns his colleagues before push-forcing it on the remote subfeature branch, so they flush all their changes before and rebase their local copy after.
    – all hotfixes are made on hotfix branches created directly from the master branch, so it doesn’t include other ongoing developments. If some fixes have been done on the dev branch, they’re cherry-picked from it onto the hotfix branch.
    – after each delivery, the master branch is merged back into the dev branch and all other subfeature branches are then considered obsolete and finished ; then a new dev cycle can start.

    On the other side and despite git’s complexity, I still feel that it gives a much better control on what’s going on than svn, which I also work with. It has a fair share of good sides too. I especially like how easy it is to clone a repo, create a new one, amend commits, etc. I feel like its performances are also very appreciable… In comparison, SVN is really f*** slow…

    • sfkleach August 24, 2018 at 6:20 pm

      What you have described is pretty much the default way of working with git in small teams – it sounds identical to what we do. The only twist is that we have out continuous-integration linked to our dev-branch and delivery-branches for our (multiple) deployment environments and with continuous-delivery linked to each of those branches.

  399. joeschmo August 27, 2018 at 8:35 pm

    People are idiots. Sorry, there it is. Okay, well, that’s the grab line…
    I’ll try not to be too judgemental (:P) but… the dumb ones are dumb – less offensive. But a sadly large portion of the clever (not wise) ones too often are enchanted by how clever they are (thanks Julian Lennon – great expression). These people often think they’re wonderful and over-complicate things for their own gratification, or at least fail to even true to simplify things because they believe “one should have to make a certain effort” because they did (or believe in some form of ‘user intelligence darwinism’ in the programming community). While there are good arguments for not dumbing things down to excess, the flip side is there is an excessive lack of care in finishing things in the “blue-sky-thinkers” *already*, without making things more complex than they need to by not at least making things consistent and clean. I know the type. I will shamefully admit for a long time I was one, albeit more the “meh, who cares, let’s move on” type than the “oh, they’re just too dumb” type.

    SW Eng is complex, yes. Things can get messy by evolution, sure. But time moves on and cleans them up – so the theory goes. I don’t want to rag on git so much as ask the following rhetorical questions of its developers / proponents. Is that *the best* you/they can do? Do you think your command interface is: logical – complete – minimal? Is the documentation as good as it can get? If I wrote git, let me say right now I would not be happy with the result, nor would I leave it as-is – even merely in the command taxonomy, and the hundred million switches.

    The design mentality of the creators is written into the project. You could tell mercurial came from python developers before you even look into it’s history – there’s a striving for the (granted, impossible) dream of perfect simplicity throughout. Git is the brutalist architect’s untreated concrete monster, but without the rough beauty or the practicality. It took the savvy of github to take what was free and “worked” to make a ludicrously simple (looking!) UI to make it work, and to, via it’s amazing free and clean web-presence, popularise the monster. I’ve never come across a developer *ever* who didn’t know Git and Github. I’ve met many over the years (both when it could be justified and now, less so) who knew of Mercurial but didn’t know of a Mercurial platform. So… Mercurial lacked this web proponent. is simple, well machined minimalism of a Miesian skyscraper. Both have their faults, but of the two Git shows a certain arrogance of not being finished – for whatever reasons.

    Well, the elephant in the room here is that anyone old enough (or who has bothered enough to study up on their tech history of the last 50 years) knows that LT is *the* most overrated personage in the history of computer science.

    It has been my overwhelming experience that we ‘old nerds’ (no we mostly wouldn’t even like to call ourselves geeks… we’re that crusty!) have “opinions” when it comes to such things. Preferring RS et al over LT is oft opined. This LT upstart… who does he think he is, etc? LOL! Well, I could go on. But there is a prominent theme also of “whatever works and is easiest”. It seems prevalent. Something happened on the way to the fair, because that sentiment seems to be all but lost now – or appears to on forums I look on. There’s so little “yeah, that’s something we could improve – let me get on that” and so much more “this is the new gospel”. Sure there’s a practical in between, but once upon I time I remembered when ‘nerds’ were keen to prove themselves by improving things anywhere they could, rather than putting on propeller hats and thumbing their noses to those they (usually in embarrassing error) believed themselves superior. I don’t want to sound jaded but when I read of fewer people than ever “having strong lower-level computer skills and knowledge” I do find it tempting to believe them wholesale. The extremes of modernity: Things either come off a platform or they are shrouded in “ja kewl magic”.

    A final note from a (clearly failed) retiree: Making something easy for others when that thing addresses a complex problem is *really* hard – and this is almost the definition of *good* human technology, and has a strong correlation with financial success. Even git – through github in this case – I would argue, demonstrates this. So simplicity and easy-of-use is *almost* the core selling point of virtually everything… forever. Now… ehem. Git is free…

    Although there seem to be more than enough comments here, you know I just couldn’t help myself. Git is something of a joke to me. It’s getting close to the “dictionary of letters”, or “letters as classes in an object tree” idea that a tragically insane colleague once wrote for a POS database. Or the “StandardItemObject” class written by another in boost. I grimace to think of some of my own insanities too – and yes, Git’s “but I have a guid of my last patch” is, alone, *almost* there. Because, you know, a number, a date-time, or a elected unique human-readable prefix just *wouldn’t* have worked (or maybe, have taken more than 10 minutes to come up with over a coffee). Git is almost like an asylum inmate’s attempt at source control before they realised the entire concept was just beyond then and they abruptly stopped, only to have other madmen take up the task for themselves, randomly assigning switches as they went. Having used innumerable… I still look at git and think: I could perform that last command by writing a bash (grep) script and some sql – only, if I implemented it that way it would be slightly more readable and perhaps even more brief than the git command…

  400. joeschmo August 27, 2018 at 8:47 pm

    As if I haven’t said enough. But I simply had to share. Someone *actually* wrote this – over at bitbucket.org – assumedly, they had to *think* this too first, in order to then write it down.

    I am a big fan of open source software and always will be. But… just read the comment. I think that says it all.

    “Git isn’t perfect. However, I would argue that there are more important things than having a cuddly command line. Sure, it would be nice if Git did things a little better, gave less cryptic errors, ran fast on Windows, etc. But at the end of the day, these things are superficial. Go and write an alias if you don’t like a particular command. Stop running Windows (no seriously).”

    Clearly this comes from someone who has never been (trusted to be?) the go-to person on any project of size or worth in a commercial environment. To downplay the importance of the usability of something you… use… (LOL!) when money is riding on it and a team needs to use it. Well, it shows the sort of relaxed and complacent birthplace of the tech itself, I think. As long as it doesn’t have anything to prove. Why not just write the scripts in BF? I can only think times have changed. I think that as a technical lead… anywhere… that I’ve been, if a critical source-control error came back as something inscrutable to the client users and I said “these things are superficial”, well, I’d expect that I would be fired. But, like I said… git is free. Python is free too, as are many other great open-source design efforts. It’s just that git seems to be “free and knows it”. But keep it up guys, oh you mighty lords of gitworld: a nice high bar for users, a nice low bar for developers. It’s the way of the future. (Keep thinking that… as you fade into obscurity – just don’t ask “how did it happen?”)

  401. TheFox September 3, 2018 at 9:29 pm

    Nothing about line endings?

    It’s the single most annoying issue that just keeps coming back.

    I would like the option for git to LEAVE THE FUCK MY LINE ENDINGS ALONE. git should know what constitute a line ending (yes, CR, LF or CRLF, very complicated!), but not offer to mess with them in any way. I would like this option.

    I know there is a rationale for git minding my line endings as it might cause some “merge weirdness” but I’m not sure if it will be worse than the current recurrent enigmas that stem from git wanting to “fix” my line endings, so I’d like a chance to try, please.

  402. Anonymous Dev September 25, 2018 at 10:44 pm

    Great article, my aproach when it comes to issues has always been dump the entire repo and re-clone it. I’ve even been advised to do so by Git loving Git experts. I do that quite frequently. A system that messes things up so profoundly on such a regular basis needs some serious rethinking.

  403. Alex September 28, 2018 at 12:48 am

    Hello Steve,
    Let me please add some more points to your list. I planned to create an own one and found suddenly your post.

    === The most GIT disadvantages I hate ===
    1. Not possible to work directly with remote repositories without cloning (just a very limited information are obtainable by “git ls-remote”).
    This is not possible to do like this anymore!:
    – svn delete -m “” svn://URL/file // To remove a single file you must chech out a huge copy
    – svn log svn://URL/file // To get the list of new commits (or even to get just the SHA of first next commit following your working copy!!) you must chech out a huge copy or fetch that is again unnecessary local downloads!
    – svn info svn://URL/file // Also impossible!
    Every time you must clone tonnes of files and then perform operations from working copy that’s unbearable.
    I had a lot of Groovy scripts and Jenkins jobs which worked relying on quick requests to remote SVN repo and it worked like a charm. Now I have to replace my graceful scripts with ugly unreadable tonnes of code to get the same behaviour.

    2. There is no analogue of SVN –stop-on-copy option. You can’t simply watch the _branch_ revisions starting from branch creation. It always connects the master revisions as well. With such a behaviour the ‘-b ‘ option for ‘git clone’ is totally useless, because the only logical use case to see branch commits is to filter-out parent branch commits (see the commits ONLY on this branch). I don’t need to see those parent commits, because for my human logic it is straightforward that everything that was committed when the branch did not exist has no relation to th branch, so no need to display it !! This is clearly demonstrates how ugly is the logic of GIT creators that they don’t see such an obvious thing.

    3. It is not possible to check which branch was checked out. The working copy is “universal”, it does not belong to any branch. If you say “git checkout ” then “git branch” will tell you “detached …” and no information from which branch did you “exit”. In svn “svn info” always shows the branch!!

    Not possible to get the branch name under which the person created a commit. It is obviously that when you commit you commit to some branch. So theoretically there is a 1-1 correspondence between commit and the branch where it was committed. But GIT just does not store this information anywhere (however, COULD HAVE STORED!).

    GIT maintainers completely destroyed the “branch” as a logical entity. Now it is very relative thing that you can’t rely on anymore. And this is the most sucks with GIT. Those gurus which are in a high meditation sync with “super mega innovative” GIT ideas it is probably useless thing and they decided for us, users that of course we must think the same GIT religion (of course as THEY think).

    What I observed in general, a spirit of that “science” : GIT maintainers try to destroy all hard, reliable and invariant things (like “branch”, “head” terms), and turn everything into some dialectic diarrhea where you can’t find any borders and limits. This is like to write on the white sheet of paper without vertical and horisontal lines on it. I hate this concept really. I am sure must be very clear rules and types everywhere.

    4. “Head” term is completely perverted.
    In a normal human-nuderstandable worls “head” always meant “latest”. If I did not update my local copy, it does not on “head” and I should update to “head” to get commits of other developers.
    In GIT they call HEAD something what is actually a “current”. It is obviously that HEAD must mean “the latest commit on the current branch on the server”. ON THE SERVER, dude!
    Instead, they perverted all human-understandable terminology and call HEAD the currently checked out revision.
    Why that? So now I have one HEAD, then I “git fetch” and have another HEAD, more HEADible HEAD. Aha…yes, of course…it’s better than SVN?…Aha.. Let that to somebody else, not to me…

    5. It is not possible to clone the given commit. In SVN you could easily operate with the commits using “svn co -r ” and “svn up -r “.
    You can’t update till SHA in GIT. You clone all stuff and one then select using “checkout” what revision to set as “HEAD” in GIT terms. Completely idiotical.

    6. It is not possible to perform actions outside of workspace. In SVN you could use the absolute path to workspace, like:
    svn commit /home/user/myWorkspace/mySVNProject
    In git you must do “cd /home/user/myWorkspace/mySVNProject” first. Is it really hard to implement the same in GIT? Of course no. I just suppose it contradicts with the paradigm of GIT maintainers which have already foreseen in advance what is better for us.
    ————————————————————————————-

    • Andrew Finnell April 18, 2019 at 12:23 pm

      You only need to clone a single time and you’re done. Ideally, forever. That is part of the trade off of working on a distributed system. You never work directly in someone else’s repository. Remote just means Other in this case. It doesn’t necessarily mean Central. As there is no central repo.

      4. SVN does not have branches. It’s a fake concept. Thus, one can reasonably implement a LATEST in SVN. In Git, what does latest mean? Latest of what? master, develop, release, branch1510?

      You cannot reasonably compare a system like SVN to GIT. They’re fundamentally different and barely have anything in common.

  404. Ojosh!ro September 28, 2018 at 7:09 pm

    One of the most infuriating things is the talking back with “Did you mean…” and tips like that. Someone wasted way too much time on smart remarks that could have been used to construct some kind of UI.
    And a –dont_whine and –do_as_i_say option would be handy too. Or combined into –shut_up_and_do_as_i_say.

    • arnebab October 22, 2018 at 11:53 pm

      That would be dangerous, because then Git would do as you said, but interpreted the git way. What you’d need is “do as a sane UI would interpret this”. And then making that the default :-)

      (but that’s really hard with the implementation-driven model git chose)

  405. Pingback: svn vs git (simple picture, no deep shit) – 7Tek Club

  406. private November 8, 2018 at 6:43 am

    Late to the game. Missing from the list, user need an IQ of at least 130. I don’t so using git is a *real* struggle.

  407. Daniel Mcliver November 9, 2018 at 8:01 am

    I think its funny that git is meant to encourage small local commits, yet when a conflict occurs you often have to rely on squashing commits to help resolve them, talk about a walking contradiction.

    As for #10 thats only half the problem with feature branches especially if you are rebasing on trunk, pushing a commit that’s a merge (from conflicts) gets rejected as part of the merge request, so how on earth are you meant to sort out conflicts & maintain a nice rebase at the same time? Enter git cherry-pick which seems like the worst hack ever (especially if you many commits on your local, then its squash + cherry-pick), see first paragraph.

    Ugh.

  408. Si Hobbs November 29, 2018 at 10:00 am

    I first read this article years ago, when I could have been convinced either way about a VCS, but I was going with the crowd at the time and that crowd was going with git. But you know, in hindsight, Git really is an amazing tool and rewards me every day, even though I do want a –shut-up-and-push-upstream-branch. But this is a very cool historic piece of writing, and a sort of dream-catcher for rants. I like that comments are still open and people are extending the list haha.

  409. Dylan Young February 15, 2019 at 6:56 am

    git isn’t a DVCS (as you can see numerous times by perusing the git mailing list).

    It’s a database. You’d be better off comparing it with SQL for user-friendliness :p

    That said, it’s pretty astonishing that no one DVCS based on git has risen to prominence. Could be that exposing the powerful features of git in a user-friendly way is a more challenging task than one would guess.

    That said, git is astonishingly extensible in basically any programming language you’d like,

    So go for it!

    • steveko February 15, 2019 at 8:56 am

      I think the lack of success of any git wrapper says much more about the way mindshare for that category of tools works. Git-less is actually a really good tool, but it’s very difficult to get critical mass of acceptance.

      • arnebab February 16, 2019 at 8:18 am

        Another interpretation could be that git has some deeply ingrained deficiencies which are very hard to work around in the user interface without reproducing the limitations (for example gitless reproduces the split between host repository and work repository) — and they need to provide access to normal git repositories to allow for widespread use and a gradual switch-over.

        The limitations cannot be conceptual, since Mercurial provides an easy user interface while providing the same set of features as git. From experience with Git I think that they are deeply rooted implementation details which manifest as inconsistencies in the user interface — that in turn prevent the creation of uniform interfaces that provide the same power. Either you have to give up some operations, or you have to learn git in addition to the simpler interface to do the operations missing in the tool. Most prominently that is likely to happen for every new feature in Git.

  410. BobM February 24, 2019 at 11:05 am

    My job is architecting and developing applications for my customers. Secondary to my job is learning and using new tools. I am not stupid. My customers don’t want to hear that I will be late on a delivery because of version control problems.
    My company has been a long time svn user, and converted to git about 5 months ago. It’s been rough. But we like the advanced branching git gives us. We’ve lost work several times – likely because we don’t understand the best way to recover it. But it’s just easier to delete a local repo, reclone and redo the work rather than try to figure out how to fix the numerous inexplicable conflicts that arise. I have even gotten into the habit of backing up my local workspace before committing.
    The most frustrating conflict we get happens like this:
    pull
    do some work
    pull (no conflicts)
    commit
    push
    wait a little while (have found waiting here reduces the frequency of conflicts)
    pull
    at this point I often get conflicts with the work just committed and that NOBODY else has touched. Often, the ‘conflict’ is between an two identical copies of the same file. But, my repo is in conflict state, and I can’t do any more commits until the non-existent conflict is fixed.
    We are committed to git, despite the fact that we rarely had issues with svn.

  411. John March 7, 2019 at 4:32 am

    After 8 months of intensive git use, all I want to say is this: f**k git, and all the managers that force you to use it. I’ve never had with SVN in 15 years even 10% of the problems I had with GIT in 8 months.

  412. Chris Milburn March 22, 2019 at 1:01 am

    Excellent article, developers should not be spending their time learning archaic scm commands they should be developing the business code that pays their wages.

  413. bevin March 23, 2019 at 5:42 am

    Even after 7 years in 2019, I completely agree with you, I HATE git, nowadays, I am spending 5 days coding, remaining 2 days resolving merge conflicts, and recovering lost codes, sometimes we all wonder how the hell we got those problems since all of us were following mature guidelines of git, somehow in someway, git just either gets ‘detached’ or something happens.

  414. mrpotassium April 16, 2019 at 11:25 pm

    I love this comments section. People are butthurt because they don’t like git’s terminology or command line interface. And they recommend ‘improvements’ that would break most build systems or are inconsistent in itself.

    If you think version control was better before git, your brain was rotted by whatever you have used before. Get over it. Git’s design is simple and since ~2007 it’s pretty easy to use. If you disagree, most possibly because you are throwing a tantrum and don’t want to adapt it.

    You really should question you own capabilities instead of persuading yourself that git is actually a bad tool and seeking here for confirmation. Git’s success speaks for itself.

  415. sfkleach April 17, 2019 at 7:05 pm

    To say “Git’s success speaks for itself” is to be incoherent about what it actually says, a blank wall on which we are invited to project a warm fuzzy. Does Microsoft’s success means that everything Microsoft does is good & that it is beyond criticism? Does the success of Apple’s iPhone mean it is perfect? Obviously not. Similarly, git is far from perfect, despite its obvious success. Of course, some of the comments in this thread are very weak but there’s some substantial comments that build on the coherent and strong points made in the original post.

    • mrpotassium April 17, 2019 at 8:06 pm

      Where did I say it’s perfect? Git’s success lets me conclude that is does A LOT things right. Valid critisism will always exist, but neither the article nor the comments are.

      If you don’t like the UI of the git command line, you are in the minority. Go and use one of the dozens of GUIs or wrappers.

      • sfkleach April 17, 2019 at 8:24 pm

        Did I suggest git was just a little imperfect? Nope, I suggested it is highly imperfect. “You are in the minority” – an unsubstantiated guess and my own guess would be in the other direction. Being widely used does not imply contentment. Based on the opinion of my workplace colleagues, I would say that git is mostly disliked, if not positively hated, despite (or because?) they are forced to use it.

        By the way, I really like git, use it every day & you would need to pry it from my cold dead fingers. But I also think it has a lot of warts.

      • mrpotassium April 17, 2019 at 8:45 pm

        Then take a look at the official Git User’s Survey from 2016:
        https://survs.com/report/nz2odu1spl
        Less than 1% hate git (Question 36)

      • sfkleach April 17, 2019 at 8:48 pm

        Nice reply. Of course I would have been one of those who publicly love git. And I also think that it has problems. It’s just not a binary thing.

      • arnebab April 17, 2019 at 11:04 pm

        This relies on the assumption that the success of git is mainly driven by git the tool and not by other effects — like GitHub which benefits more from weaknesses of git than from its strength, loss of hosters of other systems — including takeovers of companies by git zealots (sadly not a joke, look at bitbucket) — and zealots who readily took to lies to bolster git and badmouth competition.

        Git was one of 5 free software systems that competed.
        – CVS was already in decline.
        – Subversion was not distributed, so it was out, too.
        – Bazaar was too slow for larger systems for a long time and when it finally got fast enough, it had already lost brainshare and got unstable due to missing maintenance of extensions.
        – Mercurial kept up, but lost repository hosters (first freehg early on, then google code which openly advertised Github as replacement).

        Git is good enough to replace SVN because its distributed model gives it a clear edge, but it is horribly annoying to use.

      • arnebab April 17, 2019 at 11:07 pm

        Regarding the git user survey: 23% say that the user-interface (UI and UX) needs *some* improvement, 20% even say that it needs *much* improvement.

        Looking at the comments here, most of them are about the user interface — so they could come from 43% of the people who replied to the git user survey.

      • mrpotassium April 18, 2019 at 6:28 pm

        I used Mercurial before Git and it was the only competition to Git that could be taken serious. It definitely had much better Windows support and a better GUI. But as soon as you start working with branches, which is essential for a DVCS, Git is actually easier, more powerful and faster.

        Yes, there were multiple factors contributing to Git’s success, but saying the ‘Git zealots’ forced the world to use Git sounds just like a Flatearther talking about ‘Globeheads’. Arguing exactly like a conspiracy theorist.

        And no, the 43% of people that say Git needs *some* or *much* improvement in UI and UX are not the people that commenting here. I would say that too. The people commenting here are mostly the 1% that hates Git.

      • sfkleach April 18, 2019 at 9:07 pm

        Go back to the original post, which makes a lot of very straightforward criticisms for which there’s really no satisfactory response. Steveko’s point is simple enough – it’s useful but flawed. It’s not a question of loving or hating git. I love my dad but he’s just a guy, right? I love git and true love ain’t blind.

      • steveko April 18, 2019 at 7:09 pm

        >The people commenting here are mostly the 1% that hates Git.

        I find this reframing kind of funny, as if there is some objective fact that 1% of people hate Git, based on a survey of highly motivated Git users. I don’t know what the real proportion is, but when this post was shared on the various social media platforms back in 2012, there was IMHO a roughly even split between supporters and detractors.

        The bigger issue is how the question is even framed, like Git is *either* great *or* terrible. The reality is it’s useful, but very flawed.

      • mrpotassium April 18, 2019 at 8:38 pm

        > based on a survey of highly motivated Git users
        The ‘Git zealots’ have struck again.

        It’s not even very flawed. I have yet to see valid criticism of Git on this page. It’s only a massive, lazy rant about either Git not fitting one’s *personal* workflow or a Git command not doing what one was *personally* expecting.

      • mrpotassium April 18, 2019 at 10:29 pm

        I will engage in a discussion of these papers if you want to. But you need to make a point I can address instead of throwing them into my face.

        sfkleach suggested the original post, where the complex information model of git is criticised multiple times. It’s a perfect example of your preoccupation when using Git, because it’s actually so simple: You have a tree of commits with refs (pointers to commits). And you have your working tree. That’s it. You can open your .git directory and understand most of it by just looking at it. You could even write your own git tool that operates on this data in a few hundred lines of code.

        Branches? Pointer to a commit. Tags? Pointer to a commit. HEAD? Pointer to your checked out commit. Stash? Temporary commit. Index? Pointer to the commit you are working on.

      • rjubber April 19, 2019 at 12:27 am

        Heh – you old troll you. Of course you’ve not seen any ‘valid’ criticism of Git on this 1000 post page, all of which I’m quite sure you’ve read and considered, because your definition of valid is *personal* and flexible. For some reason you have an emotional investment in a piece of software, so any criticism causes your position to become more entrenched. That’s fine, you’re only human, and we all suffer from this sort of argument backfire effect at times.

        The two rather woolly observations you cite don’t really represent the primary criticisms against Git, on this page or elsewhere, but they do allow you to highlight the word *personal* in an attempt to suggest you have an objective position that others lack. A survey of programmers defined primarily by being prepared to fill in a survey suffers from profound selection bias so we can put that to one side.

        How about some anecdotal evidence for your consideration? I’m a games programmer, and I’ve freelanced at a number of companies where git or other resource management software is in use. The people using Git at these establishments range from experienced programmers to artists, designers and producers, whose technical knowledge, quite reasonably, doesn’t normally encompass expertise in version control. The chances this multitude will ever fill in a git satisfaction survey is slightly lower than zero. Their response to using git, even for the simplest operations, is consistently one of distrust and fear. Their workflow is incredibly narrow. When things go wrong, they’re screwed and they know it. This sensation extends to some of the programmers as well, although to a different extent. As a freelancer, I see this at every place I visit. It’s consistent. I admire git’s ambition, it’s open code nature and the heavy lifting it is capable of achieving. However the way I see people using it tells me the interface, visually wrapped or otherwise, is wobbly and confidence sapping. In a way my field is human/computer interaction, and I strongly subscribe to the notion that if somebody doesn’t understand an interface/menu/ui/command line interface/joystick setup/you name it – then the problem exists with the *interface*, not the user. A designer can’t blame the users. A dogmatic defence of git, usually based around the perceived failings of the people using it, won’t lead to necessary improvements in that interface or maybe a reconsideration of the abstraction model underpinning it.

      • mrpotassium April 19, 2019 at 3:04 am

        Anecdotes of artists using Git are surely more representative than a survey among thousands. I can tell you anecdotes of my grandma using Microsoft Word. Is it therefore also an example of bad UI/UX?

        I *personally* hate Microsoft Word and the workflows it encourages and because I am forced to use it. But I don’t call it flawed software because I know it was designed with a specific user group in mind. For sure it has it’s right to exist.

        Software becomes crap as soon as it tries to please everyone, because you can’t please everyone. Git solves it’s use case very well. As I said, use one of the many wrappers if it fits you better. Perfectly fine.

      • arnebab April 23, 2019 at 1:13 am

        @mrpotassium: You do realize that your reply can be shortened to

        – “git is not for artists, and if it were, it would be crap” (translation: It cannot be improved to help them better),
        – “I’ll ignore that you wrote that the wrappers don’t help”, and
        – “I’ll continue to ignore selection bias. Instead I’d rather attack the experience you reported from a group of users which is very unhappy with git”

        , right?

  416. mrpotassium April 23, 2019 at 6:01 pm

    That was not reasonably shorter than my reply, but that’s okay.

    It wouldn’t be crap, it would be a whole nother tool. This question is all about creating a general purpose tool vs creating a specialized tool. Most programmers probably wouldn’t like to use it. Seriously, if the wrappers don’t help, what would you suggest? This is exactly the feedback that should be ignored. Of all the wrappers and GUIs available, NONE fits your needs? It’s just stubborn. And instead of writing a better wrapper, you thinks it’s appropriate to change Git’s core? Why?

    Let’s assume the survey is biased. It doesn’t change my point.

    • arnebab April 23, 2019 at 7:23 pm

      So to get version control which is more suitable for artists, we need another tool? Or more concrete: If you’d be asked by a company that has more artists than developers (who still need to cooperate, though), would you suggest to use another tool, if you knew of one which is ok for programmers and better for artists?

      • mrpotassium April 23, 2019 at 7:34 pm

        No, I suggest the artists use whatever Git wrapper/GUI they want. If they don’t like any of them, that’s not a problem if Git itself. What problem do you wan’t to solve exactly by changing Git what a wrapper can’t do?

      • arnebab April 23, 2019 at 8:06 pm

        @mrpotassium: rjubber said that none of the wrappers help.

      • mrpotassium April 23, 2019 at 8:14 pm

        What problem do you wan’t to solve exactly by changing Git what a wrapper can’t do?

      • rjubber April 23, 2019 at 8:25 pm

        “I *personally* hate Microsoft Word and the workflows it encourages and because I am forced to use it. But I don’t call it flawed software because I know it was designed with a specific user group in mind. For sure it has it’s right to exist.”

        Nobody has questioned the right of any software to exist. Informal fallacy of relevance. Moving on.

        Word was designed with a specific user group in the sense it was designed for all users. It’s a word processing app, not a specialised tool for designing the next space shuttle. If some people find it hard to use, it has flaws. You can pretend otherwise until you’re blue in the face, but the interface is also part of the software. Quick example. I make some software that does a useful function. But I put it behind a randomly generated password that needs a five hour gpu dictionary hack to break into, and change the buttons and ui language randomly every time the software is run. If the underlying function still worked, would you argue the software was without flaw, despite the horrible interface?

        So it goes with Git. I’m not protesting it’s underlying power, but rather the way it has been set up to be used. Software that promotes fear in its unwilling user base might well be worthy of improvement.

        “Software becomes crap as soon as it tries to please everyone” – no. Maybe you’re thinking of pop music. Software becomes *better* if it manages to please everyone, or at least gets partway there. Software designers are not the gatekeepers of functionality. We don’t parcel it out to the deserving. Similarly, a coder who makes bad docs, explains things as if the audience has the same knowledge base, doesn’t use comments, uses random naming conventions etc., is a nightmare, not a boon, no matter the level of skill on display. Interface is at least as important a part of software design as utility, if not more so.

      • mrpotassium April 23, 2019 at 9:04 pm

        > Nobody has questioned the right of any software to exist.

        Let’s call it ‘reason to exist’.

        > If the underlying function still worked, would you argue the software was without flaw, despite the horrible interface?

        Never argued that. My point is that Git’s interface is good. Git has a lot of power users and those like the interface as it is. For other user groups wrappers do exist. Yet you want to mangle all functionality and every user complaint into one big UI?
        There are things that make an UI objectively, for everyone bad. That’s what you are talking about. But at one point you always have to make compromises if you want to create an UI for everybody.

        And the Git user groups are *very* different. You won’t have an UI that is both liked by artists and by embedded systems developer and by my grandma.

      • arnebab April 24, 2019 at 4:16 am

        @mrpotassium let’s take your grandma out of the group (except if your dad is nicknamed Bobby Tables https://www.xkcd.com/341/).

        Why shouldn’t you be able to write a UI which is both liked by artists and embedded systems programmers? I’m not talking about perfect, I’m talking about good enough to be liked (and as side-constraint: scales to facebook scale, just because it should be suited to all kinds of projects, and artwork-heavy game projects can be massive). Good enough that rjubber would regularly meet both developers and artists who like the system — even though there would be some in either group who don’t.

        Would it suffice for you as proof of being possible if I gave you one single example?

      • mrpotassium April 24, 2019 at 4:41 am

        > Why shouldn’t you be able to write a UI which is both liked by artists and embedded systems programmers?

        They have different requirements to a UI. One will want to automate things. One will want his software small enough to run on embedded devices. One will want the UI as intuitive as possible. One needs the UI to run over SSH. One wants better performance, another one a better memory footprint.

        > Would it suffice for you as proof of being possible if I gave you one single example?

        Yes.

      • arnebab April 24, 2019 at 6:03 am

        > > Would it suffice for you as proof of being possible if I gave you one single example?

        > Yes.

        Firstoff: Sorry, this was a trick question. I don’t consider my question good style, but decided that it’s the best path forward in this case. I hope you agree after reading the answer.

        Second: Give Mercurial a try. I’ve seen its plain command-line interface used effectively and without problems by programmers, word-users, and scientists, and I read reports of artists who worked easily with it, too. My personal experience after introducing it in our work-group at university (spread between the Netherlands, the USA, and Germany) was that after a 15 minute presentation with the core commands and some initial support in setup I got roughly one question every six months (which then was about a rare corner case or special setup), and otherwise Mercurial just worked for all involved.

        Its plugin architecture makes it easy for programmers to add power they want without turning the core tool into a scare-inducing foot-gun.

        With git at my current workplace, we spent one full day with long-prepared presentations and hands-on training, and I’m still supporting someone once a month, even though I’m not the designated git-person (I just happen to have some experience with git from free software projects). And the support usually takes roughly one hour while with mercurial it was about 10 minutes (writing an email with a short explanation).

        So give Mercurial a try. It shows that it is possible to write a UI which is good for both embedded systems programmers and artists.

      • mrpotassium April 24, 2019 at 8:02 am

        I have mentioned earlier that I used Mercurial before switching to Git.

      • arnebab April 24, 2019 at 9:49 am

        You should try it again, with a focus on whether it works well enough for you that you could use it to collaborate with artists.

  417. mrpotassium April 23, 2019 at 8:11 pm

    What problem do you wan’t to solve exactly by changing Git what a wrapper can’t do?

    • arnebab April 24, 2019 at 4:19 am

      The problem I want solved here right now? I want to have a system which is liked (or at least not feared) both by the majority of artists and by the majority of programmers rjubber meets.

      • mrpotassium April 24, 2019 at 4:34 am

        Again, why can’t a wrapper solve this?

      • arnebab April 24, 2019 at 5:51 am

        The problem is not that it can’t, but that many, many tried and rjubber reports that they don’t. Either they are all badly done, or the problem of wrapping git is harder than you think.

  418. TLL April 25, 2019 at 3:37 am

    I totally understand the value of utilizing Git on large projects with multiple teams, multiple dev environments, etc …. . What I do not understand is why any individual developer or small dev team (2 – 4 programmers) would ever use Git. You add complexity without gaining any of the advantages provided by Git. SVN tracks changes, manages conflicts, and allows for revisions as well. SVN is not sufficient for multiple dev teams wherein you may end up with drastically different code bases. But for a small team, it is much better and the simplicity correlates into a drastic increase in productivity.

  419. Pingback: Git vorgestellt: Wie man die ersten Schritte mit Git geht

  420. Paul Klapperich June 1, 2019 at 10:05 am

    “9. Git history is a bunch of lies”, re: git rebase

    IDK. This seems like a strange complaint when many of your other concerns boil down to “svn and other centralized VCS wouldn’t make me do this!!” In a central VCS, developers don’t get the option. They have to update, rebase their working directory, and then commit. This can cause situations where my working directory was fine and I broke it during update, and now that it’s broken I can’t commit and share with my co-workers.

    With git, hg, and other decentralized VCS, I can commit code that works, and then pull in new changes. Now I have the choice to either merge or rebase. I always check and see if it merges cleaning, if so then I usually rebase (cause that will also work automatically), quick test, and then push my changes. If I have to intervene during the merge, then I commit it as a merge and push. This way if the merge broke my code, my co-workers and I can always go back to previously working code from both branches of the history.

    Rebasing/squashing commits that have already been shared with others is obviously a bad idea. But I really appreciate that DVCS give me the choice to rebase or merge. I dislike how CVCS force rebasing on every commit.

  421. David Saintloth (@sent2null) June 25, 2019 at 9:04 am

    I love how comprehensive this list is and love even more how bang on each of the items is in describing why git is not the end all to be all of version control architectures.

    As a person who has invented his own, (see: http://apriority.dyndns.biz ) I realized long ago that the most important aspect of version control fluidity is to enable the developers to push new code to the repo as quickly and painlessly as possible. The task of “maintaining” should be done exclusively by one person when there is a person involved and ideally by an automated agent set with a behavior policy when various types of conflicts emerge.

    Speaking of conflicts all fall into the category of code falling out of sync what is the optimal way to prevent this??

    Notification on event. I call the grander concept of building systems this way, “social oversight”.

    If git enabled a live reporting of remote changes to local repositories it could end the need of the vast number of commands and eliminate a dramatic amount of complexity. Imagine …if ..while developing your repo could report to you that the resource you are working on was modified by a remote dev. and by who in their local copy and that a possible conflict has emerged…this would then allow you and that agent to immediately socially convene to collaborate on merging in the code…rather than having situations where a developer grinds out code locally for a week between pushes (it happens and will continue to happen and the vcs should fix around the user behavior not try to change the user behavior) and then when they are ready to push / merge get a bunch of merge conflicts that if they don’t marshal correctly could break their local build, the system would real time interrupt all developers working on a given resource and force them to deal with emerging conflict points …instead of letting them build up like a bomb to be dropped the next time the developers push.

    Tangent for the interested:

    AgilEntity implements a real time notification on the life cycles of all managed code, this allows any and every change to broadcast to agents subscribed to that particular resource….it could be a js file or it could be an image if it is managed changes to it can broadcast to subscribers of its life cycle (this happens naturally by permitting users access to entire classes of resources be they code or content using the action oriented workflow and permissions system)

    What this does is forces conflicts to be handled as they emerge in real time…thus eliminating really the job of a formal maintainer to handle merge complexity…it forces collaboration as a solution to code drift which ultimately is the fundamental issue with a distributed version control system that lacks real time monitoring of all managed resources.

    • arnebab July 31, 2019 at 11:20 pm

      The notification sounds interesting, and I could see how this could be implemented with a server-side hook and editor interaction — but on push.

      I would not want to interrupt other developers in real time, but I would like to see it if someone pushes changes which create conflicts with changes I did not push yet. I wouldn’t want those changes to enter my repository right-away, but getting the warning on commit would be useful.

      • mrpotassium August 1, 2019 at 12:13 am

        You can easily achive this in git with a client-side hook. Take a look at your .git/hooks directory for samples.

        The notifications would be indeed pretty annoying for large projects, especially because 90% of merge conflicts are trivial. Also, solving conflicts was never the job of a maintainer, but of the author of the code.

      • arnebab August 1, 2019 at 8:09 am

        I can get a notification on push which tells me which files would have conflicts that can’t be resolved automatically? I don’t see that — I checked pre-commit.sample, pre-push.sample and pre-rebase.sample. Which one did I miss?

  422. Pasquale July 21, 2019 at 6:40 pm

    New to this forum. I am probably destined to be one of those dopes too dumb to understand Git but I’m glad I have so much company! I have been a developer and configuration manager for 30 years so I’ve seen stuff. I’ve used SCCS, then CVS/RCS and PVCS, VSS, Perforce, Subversion, and most recently a database-driven entity-relationship system known as Truechange.
    I am now tasked with migrating our code base to Git & Bitbucket and after a year of research and trial-and-error I am confused, scared and frankly repulsed. I was driving a Corvette and now asked to use a (really fast) go-cart with a bunch of confusing & misnamed controls. And the enthusiasts keep telling me how great it is, how powerful, how easy, how uh, well, cool. The emperor is naked. True had change-sets which could be migrated. Migration. Git never mentions it, and no, cherry-picking is not the same.
    Git seems to be built by & for developers. There is nothing for CM or QA or the PMs. It’s as if they don’t exist. There seems to be no release process, and no literature about that. Speaking of documentation, here is an illustrative example. In git-summary, there is an entry for “changesets” but only to say that “git does not store changes, but states”. However, 2 entries later admits that cherry-picking “extracts change(s) . . . of a commit” and so on.
    Trivial, you might say, but it point to the recurrent faddishness of paradigms: a new way of thinking often captivates developers. That is why we have OOP and patterns and Agile and so many other failed fads. I predict Git too will fade away, tho not soon enough.

    • sfkleach August 1, 2019 at 12:05 am

      Hiya! I was kind of following your argument until you dropped off the deep end about OOP, patterns and Agile being failed fads. Gee, how many fronts do you want to conduct war on at the same time? Those are _humongous_ claims that need exceptionally good evidence, not being lobbed like hand grenades in an act of desperate self-defence. As a result It just feels like yet another rant against git and, despite your prediction, I predict git will enjoy enormous ongoing success despite its many flaws – at least in part because rival solutions are rarely argued well or as thought through.

      • Pasqale October 20, 2019 at 9:48 am

        If you look at these items as rebranding of some earlier process & mode of software development, then yes they are “failed fads”, but maybe in the case of OOP, if you include OOP languages, then perhaps I’ve gone too far. Maybe more accurate to call them buzzwords.
        My point about Git remains and I’d like to drive it even further home by pointing out that the vast majority of posters here are developers (and a large swath of even them hate Git). What good is checking great code into a branch if it cannot easily be tracked, migrated and merged into various flavors of the end product? Yet nothing in the general literature discusses this important part of version control. It’s all about development for developers.

  423. Pingback: Un impostor entre dos aguas | jordisan.net

  424. Usuck Reallybad August 1, 2019 at 6:22 am

    This is one of the most interestinig thread on internet when you look at it as some kind of cultural phenomena.
    At one side you have a person who made really good software, on other sides are either clueless n00bs or grumpy grayballs trapped in CVS mindset.
    And Cancer dude msking money out of someone-s else effort.
    Pathetic.

  425. genius September 4, 2019 at 1:44 pm

    Well, after reading some really old comments and pretty new comments, I arrived to this conclusion:

    People don’t understand what Git is, people try to use Git the WRONG way, people want to press 1 button (or write one command with no arguments) and have everything resolved, people don’t like Git and instead of creating their own they start spitting sh** everywhere.

    And now Git Flow is used pretty much like normal Git workflow… and it is awesome…

    I totally understand that sometimes it is more cryptic than useful but you must also see the other side, it is the MOST efficient VCS nowdays to handle ANY difference in files…

    Learn it more and then spit fire and start blaming everyone for using Git… then, go back to SVN or worst tools…

    • rjubber September 29, 2019 at 2:31 am

      Dear genius

      Every defence of Git is pretty much the same, and suffers from the same misapprehension. There are people out there who have so much time on their hands, or the right mental framework, that they actively enjoy learning how to use a version control system with a complex, arguably profoundly non-intuitive, interface. The rest of us are primarily interested in coding, and just want an easy to use VCS as a tool on the side. Especially if we have to use multiple different systems when contracting. People who don’t like the Git interface are, in the defenders’ view, simply not good enough at using Git to be able to properly criticise it.

      Can you genuinely not envisage some kind of VCS that has the power of Git but a much nicer interface? I don’t mean the clicky buttons here, I’m talking about terminology and syntax. Putting it another way – your defence seems a little circular. I’ll rephrase your argument like so – “People who don’t understand Git would realise how easy it is to understand if they just understood it!” To which I would add the obvious rejoinder that one of its big problems, as has been said many times, is that the interface is hard to understand. I salute your capacity to use Git with facility and flair – you’re doubtless one of the many people out there far cleverer than me to whom this comes naturally. But an interface (from a games programmer perspective especially) that only works for outliers, is almost certainly a bad interface. In my industry, if somebody uses my software incorrectly, the fault is mine, not theirs.

      There is always a better interface possible, even for complex software. Git goes in the opposite direction and seems to be as opaque as possible. I’ve been using VCS systems for decades now – some were broken and have been discarded, some are simple and require little maintenance and one aptly named piece of software in particular strikes fear into every person in whichever office I’m contracting with.

      • sfkleach September 29, 2019 at 7:20 pm

        What an excellent post – very well said. I am a git enthusiast and have been promoting the use of git for many years; however, I am not blind to its many design flaws. Better version control systems are possible and arguably already exist. Yes, git has achieved tremendous traction and massively uplifted the quality of software development, but there is a valid sense that many people have (including myself) that this popularity is boxing us in too. If anyone is interested in co-designing an alternative approach then I have some ideas I would be interested in sharing.

  426. PG September 20, 2019 at 6:34 am

    it’s 2019… Git is not any better :(

  427. Ferda Mravenec September 27, 2019 at 11:29 pm

    I’m 6 years working with this Shit (Git) and still fighting…

    • sfkleach September 29, 2019 at 7:28 pm

      As I have recommended many times on this list, if you are struggling with git on the command line then there is another really good option. For me, SmartGit was a game-changer and I cannot recommend it enough. I have tried quite a few good git front-ends and SmartGit is the one I continue to recommend (although I haven’t gone back to GitKraken since it went Pro & apologies to the GitKraken folk for not knowing the state of play – maybe you can throw your hat in the ring too.) I have no affiliation with SmartGit or the company Syntevo, directly or indirectly. I am just a fan of their software.

      One feature of SmartGit I particularly like is that it shows you the git commands it is issuing on your behalf, which means you pick up some nifty tricks along the way. And the fact that it works on Linux, Windows and MacOS is brilliant – I use all three on a near daily basis – and means I don’t have to worry that I am recommending a platform specific product. Similarly, it works with Subversion and Mercurial too, which means you have one tool, that you can take anywhere (the license is for you, as a developer, not your computer). Genius!

  428. Russ October 3, 2019 at 6:34 am

    Thanks. I’ve been trying to get my head around Git. Finally gaining some understanding I am on the verge of giving up. When I asked a question about how to do version control, one responder said “Version numbering is not the responsibility of source control and Git has no release numbers”.

    Huh? What is a version control system for if it can’t do versions? The company I am working with did not want to pay for a good version control system and told me to use Git. I am going to try to get them to spend the money!

    Russ

  429. me November 7, 2019 at 9:11 am

    The reason Git is so popular is it is free
    If Microsoft did not set the price per seat so high for TFS it would be the leader in VC

  430. Rio November 8, 2019 at 1:54 am

    I am new to git. I spent about 10 hours to learn git commands. Is that easy and normal for you? I failed after a whole day.
    >git add
    It is ok.
    >git commit
    it is ok.
    >git push
    You can’t push. There are some changes on server. You need to pull first.
    >git pull
    You can’t pull. There are something pending to commit.
    >git pull -f (Please just pull it no matter what risk. Already backup)
    You can’t pull. There are something pending to commit.
    >git commit
    Nothing new to commit. You need to add.
    >git checkout (I don’t want to add those thing. I want to igore them. Now I just want svn revert)
    You can’t checkout. You need to merge…

    I was insane! I don’t know what to do. I don’t want to merge. I already deleted all changes and revert local repos but why you git still ask me to merge? Is that clone is the only way to fix it?

    • Igor January 24, 2020 at 10:33 am

      Hi,
      This is simple – you didn’t verify the commit.
      There are some changes that probably failed when you committed them to your local repository. If you issue:

      > git status

      you will see that there some files that still needs to be committed.

      • arnebab May 10, 2021 at 8:00 pm

        Which means you want git stash, that isn’t well integrated with other settings in git but is essential to get anything done. More so: You want –autostash which works with almost (!) all commands in git.

  431. Pingback: La UX de los programadores: ni esnobismo ni masoquismo | jordisan.net

  432. Pasqale Argenio December 27, 2019 at 9:39 am

    Features Git lacks:
    1. Ability to edit commit messages. (Maybe there is some workaround involving a new commit but our old version control system contains this feature.)
    2. Migrate: There is cherry-pick but it’s quite different. Our old system supported migration of changes among branches.
    3. SCCS Keywords: These embedded strings are auto-updated with version information, eg tag names, for display by field support & others needing to verify what is installed.

    On the topic of non-orthogonal command set: how does “git checkout ” serve to rollback changes to a file?
    But then, Git was conceived by a self-professed sociopath…

      • Pasquale J Argenio June 10, 2020 at 6:23 am

        Thanks, but why am I looking at Mercurial documentation for Git features?
        OK, the other product we used was proprietary & somewhat expensive, but it contained all of the features mentioned, plus an understandable abstraction hierarchy, understandable by mortals.
        It had adequate, terse documentation with great indexing, was easily customizable, fast enough, simple interface & great support for building & versioning. I can find NO documentation or posts about Configuration Management using Git. I’m talking about putting together a version from a disparate set of features, and managing a list of versions going forward — versions that operate the same on different platforms and with different user bases (think human languages).
        There is nothing in the Git literature or online. Every discussion seems to be by & for developers and ends with the commit or maybe the Pull Request.
        What happens after that pray tell?

  433. chealer January 18, 2020 at 3:24 am

    Please let me know if this article is offered under a licence allowing redistribution.

    By the way, it’s “maintenance”, not “maintainance”.

  434. Doug Kimzey May 16, 2020 at 7:22 am

    When you need to do something as simple as a revert to a previous version, Git can be a show-stopper for novice users. The ambiguity and vague syntax is the number one reason for the steep learning curve. The documentation is a gold-mine of “don’t do this” examples for technical writers. Every ambiguous command is described in terms of three or four vague commands. There is no clear source or destination. In using the Team Manager in Visual Studio,the ambiguity is still a huge factor. For example commands such as Reset with options to Delete Changes or Keep Changes. There is no indication of what you are keeping or deleting. I have taken courses on-line on Git. This includes a course on how Git operates under-the-hood. Under the hood, it is a good system.But it is working under a syntax that is ambiguous, vague and guaranteed to cost the world billions in lost work and productivity. I find tough partial differential equations by far easier and more pleasurable than using Git. The syntax is simply horrible.

  435. CDSRV TechSupport July 1, 2020 at 3:03 pm

    This framework was put together to provide easy to remember commands and functions for the complex set of options needed to accomplish common software development workflow steps. The project is structured to be applicable to any version control system.

    https://github.com/CDSRV/runtime/tree/default/bin

    branch : switches branches or creates a new branch if it doesn’t exist
    branch.delete
    branch.empty

    status
    add
    commit
    pull
    push

    .. and others,

    a work in progress – more on the way
    – contributions welcome

  436. Paul December 2, 2020 at 2:13 am

    8 year old article, still applies for the most part. At least now we have better interfaces for viewing and manipulating the git repo, but having used subversion for years, and used git for years, git still feels like a step backwards. Projects I’ve worked on, we’ve had way more serious issues with git than we ever had with subversion.

  437. Gamm February 26, 2021 at 12:10 pm

    Git your shit together.
    Why does it have to be complicated? Having to research half an hour to do the most basic things? Its like the vi-lovers. Get a f*** life!

  438. Mika April 27, 2021 at 8:00 pm

    @Steve Bennett, thank you for this blog! While reading it was like, ‘oh yes agree’, ‘yepp it’s all true’ and so on. Can we call GIT to be a ‘tool’, or not? Does it really help you? Or, are you just forced to use it? For me the latter…

Leave a reply to Stephen Leach Cancel reply