Home > Usability > 10 things I hate about Git

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:

About these ads
  1. February 27, 2012 at 11:28 am | #1

    #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 | #2

      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.)

      • February 27, 2012 at 2:23 pm | #3

        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).

      • August 5, 2012 at 3:45 pm | #4

        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 | #5

        “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 | #6

        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.

      • August 6, 2012 at 5:48 am | #7

        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 | #8

        “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.

    • mark
      March 22, 2012 at 10:45 am | #9

      how does bzr complicate things even more?

      • September 4, 2012 at 10:32 pm | #10

        through mandatory branch-by-cloning and changing revision numbers as only identifier. At least that was ~1 year ago.

    • January 8, 2013 at 3:55 am | #11

      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 | #12

    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.

  3. February 27, 2012 at 6:15 pm | #13

    > 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/

    • March 7, 2012 at 6:57 am | #14

      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.

      • September 3, 2012 at 4:33 pm | #15

        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 :) )

    • September 3, 2012 at 4:53 pm | #16

      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

      • September 4, 2012 at 10:31 pm | #17

        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 | #18

    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 | #19

      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.

      • August 6, 2012 at 12:12 am | #20

        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.

      • August 6, 2012 at 12:14 am | #21

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

  5. March 9, 2012 at 4:23 am | #22

    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 | #23

      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.)

      • August 5, 2012 at 2:06 pm | #24

        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 | #25

        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 | #26

    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.

    • May 2, 2012 at 11:54 pm | #27

      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 | #28

        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.

      • September 3, 2012 at 5:20 pm | #29

        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. March 9, 2012 at 7:47 am | #30

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

  8. March 9, 2012 at 9:53 am | #31

    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 | #32

      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.

    • March 9, 2012 at 10:01 am | #33

      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.

      • March 9, 2012 at 10:26 am | #34

        I’m not sure what we should have done, even after all these years. I suppose a better answer might have been a stripped down free version (no guis, no subrepos, no binary server) and a for-pay enterprise-y answer. In retrospect, that might have been a better answer.

        As an engineer, I didn’t much care for that answer, I was trying to help Linus and his team and I wanted them to get the good stuff, not half of the answer.

        As for not reverse engineering the protocol, I know everyone hates that but we were trying to protect what little business model we had. Freely admit I went about it wrong, though given the goal of trying to help Linus and have a business, even now I don’t have a better answer.

      • steveko
        March 9, 2012 at 3:35 pm | #35

        I wonder why the open source community (ok, RMS) reacted so vociferously to the use of a non-free VCS like BitKeeper, yet they seemingly have no problem with the non-free VCS hosting site GitHub. GitHub is making squillions off hosting Git, yet as I understand it, the Github code itself is closed source.

      • March 9, 2012 at 3:50 pm | #36

        Well, I’m personally not ok with it. I had to do this:

        https://bitbucket.org/site/master/issue/3054/make-bitbucket-free

      • March 11, 2012 at 10:00 pm | #38

        @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.

      • December 30, 2012 at 11:43 am | #39

        Jordi Gutiérrez Hermoso :
        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.

        /jordi;

        You summed it up perfectly, Jordi. ;)

  9. JJ
    March 9, 2012 at 9:49 pm | #40

    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 | #41

    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 | #42

    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 | #43

      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
      • September 3, 2012 at 5:26 pm | #44

        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 | #45

        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 | #46

        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 | #47

        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.

      • September 4, 2012 at 10:27 pm | #48

        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.

  12. March 9, 2012 at 11:52 pm | #49

    “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 | #50

    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.

    • September 3, 2012 at 5:28 pm | #51

      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.

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

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

    • steveko
      March 10, 2012 at 10:53 am | #53

      Don’t. There are thousands of great open source developer tools out there. The Linux and Gnu communities have a particularly unfortunate, and highly influential attitude towards how people should use and develop software – but not everyone subscribes to it.

    • August 5, 2012 at 6:54 pm | #54

      Hey, you’re using open source right now. And Git may not always be convenient or intuitive, but it’s a tool and it’s available for free use.

    • September 3, 2012 at 5:29 pm | #55

      Just have a look at Mercurial. It shows how to do DVCS right.

  15. March 10, 2012 at 1:34 am | #56

    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 | #57

    #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 | #58

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

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

  17. March 10, 2012 at 1:56 am | #59

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

    • Q
      August 5, 2012 at 5:39 pm | #60

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

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

      • December 22, 2012 at 7:48 pm | #61

        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 | #62

    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 | #63

    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”

    • imMute
      June 8, 2012 at 12:53 pm | #64

      I think you’re looking for “git merge master origin/master” in between the commit and the push.

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

    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…

  21. March 10, 2012 at 5:25 am | #66

    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 | #67

      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. March 10, 2012 at 7:58 am | #68

    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 | #69

      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…”)

    • September 3, 2012 at 5:33 pm | #70

      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.

      • December 22, 2012 at 8:05 pm | #71

        “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 | #72

    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. March 10, 2012 at 8:48 pm | #73

    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?

    • March 11, 2012 at 10:13 pm | #74

      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 | #75

        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 | #76

        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.

      • August 6, 2012 at 3:40 am | #77

        “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.

      • September 3, 2012 at 5:35 pm | #78

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

  25. March 10, 2012 at 10:55 pm | #79

    Use SmartGit, Luk.

  26. Tgr
    March 11, 2012 at 2:31 am | #80

    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.)

    • August 7, 2012 at 6:50 am | #81

      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).

  27. vzemlys
    April 3, 2012 at 9:23 pm | #82

    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 | #83

      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 | #84

        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 | #85

      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..

  28. Greg
    May 28, 2012 at 12:06 am | #86

    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 | #87

      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.

      • August 5, 2012 at 11:21 pm | #88

        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.

  29. June 17, 2012 at 3:13 am | #89

    #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.

    • June 17, 2012 at 10:40 pm | #90

      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.

      • June 21, 2012 at 1:03 am | #91

        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.

      • September 4, 2012 at 10:11 pm | #92

        denommus :
        Git is not a mere toy

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

  30. C
    June 28, 2012 at 11:33 am | #93

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

  31. jason ko
    June 30, 2012 at 4:08 pm | #94

    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.

  32. July 4, 2012 at 12:59 pm | #95

    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 | #96

      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.

  33. July 8, 2012 at 5:56 pm | #97

    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 | #98

      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 | #99

        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 | #100

        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 | #101

        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 | #102

        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.

      • August 6, 2012 at 6:39 am | #103

        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”

      • August 6, 2012 at 7:10 am | #104

        “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.

    • August 7, 2012 at 9:17 am | #105

      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.

  34. Craig
    July 18, 2012 at 9:09 am | #106

    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.

    • August 6, 2012 at 1:51 pm | #107

      Yeah i found the same, they have a similar enough syntax that the change wasn’t too harsh and with time I came to prefer the Git way of doing things.

    • September 3, 2012 at 5:41 pm | #108

      and then there’s the 5%, which crop up every other day, providing limitless amounts of annoyances…

  35. ilupper
    August 3, 2012 at 6:41 am | #109

    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?

    • August 4, 2012 at 12:06 am | #110

      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.

    • August 7, 2012 at 9:24 am | #111

      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.

  36. August 5, 2012 at 11:49 am | #112

    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.

  37. August 5, 2012 at 11:55 am | #113

    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.

    • September 3, 2012 at 5:42 pm | #114

      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…

  38. matthewfedak
    August 5, 2012 at 1:13 pm | #115

    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.

    • August 6, 2012 at 6:45 am | #116

      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.

  39. August 5, 2012 at 3:18 pm | #117

    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.

  40. August 5, 2012 at 3:49 pm | #118

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

  41. August 5, 2012 at 4:29 pm | #119

    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 | #120

      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.

  42. Josh
    August 5, 2012 at 4:47 pm | #121

    > 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 | #122

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

      • May 5, 2013 at 8:40 pm | #123

        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.

  43. x
    August 5, 2012 at 4:54 pm | #124

    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.

  44. passcod
    August 5, 2012 at 5:30 pm | #125

    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 :)

    • steveko
      August 5, 2012 at 9:49 pm | #126

      I’ll take your word for it :) Definitely a pity that those messy concepts keep leaking up into the UI though – you see references to treeishes and refs and such all over the man pages.

    • August 6, 2012 at 6:51 am | #127

      I personally heartily recommend a perusal of the documentation in many fine books about how git internals work. Once you realise its just a big graph, glued together with SHA1 and gzip, and all the functions are just different methods of mutating the graph, it seems much much simpler.

      http://progit.redhome.cc/book/th/ch9-0.html

      and

      http://git-scm.com/book/en/Git-Internals

      Should give you ample information to understanding git better =)

  45. August 5, 2012 at 5:33 pm | #128

    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.)

  46. Sakuraba
    August 5, 2012 at 5:45 pm | #130

    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 | #131

      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.

  47. BAReFOOt
    August 5, 2012 at 7:31 pm | #132

    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 | #133

      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 | #134

      > 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.

    • September 3, 2012 at 5:48 pm | #135

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

  48. August 5, 2012 at 7:46 pm | #136

    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.)

  49. August 5, 2012 at 7:50 pm | #137

    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 | #138

      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 | #139

        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.

  50. Olivier Refalo
    August 5, 2012 at 8:53 pm | #140

    Agreed! Git is way too complex.

    That’s why I built G2 !

    https://github.com/orefalo/g2

    • August 6, 2012 at 3:14 am | #141

      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 | #142

      > 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.

  51. Simon Tewbi
    August 5, 2012 at 9:08 pm | #143

    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.

  52. Erik
    August 5, 2012 at 9:26 pm | #144

    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 | #145

      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.

  53. August 5, 2012 at 10:04 pm | #146

    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 | #147

      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.

  54. riotingpacifist
    August 5, 2012 at 10:57 pm | #148

    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

    • September 3, 2012 at 5:52 pm | #149

      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 | #150

        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.

      • September 4, 2012 at 10:05 pm | #151

        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)

  55. August 6, 2012 at 12:31 am | #152

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

  56. Harald Wellmann
    August 6, 2012 at 2:20 am | #153

    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?

    • September 3, 2012 at 5:56 pm | #154

      “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).

  57. August 6, 2012 at 2:48 am | #155

    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.

    • steveko
      August 7, 2012 at 12:42 pm | #156

      Nice suggestion – added.

  58. August 6, 2012 at 2:50 am | #157

    > 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.

  59. August 6, 2012 at 2:51 am | #158

    Do you like, not know about reflog or something?

  60. August 6, 2012 at 2:55 am | #159

    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.

    • August 6, 2012 at 2:59 am | #160

      Oh yeah, and stash is freaking awesome, can’t live without stash.

      • Mathieu Duponchelle
        August 6, 2012 at 3:08 pm | #161

        So true, saying it’s useless almost sounds like trolling to me …

  61. August 6, 2012 at 5:57 am | #162

    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/

  62. August 6, 2012 at 6:22 am | #163

    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!

  63. August 6, 2012 at 6:33 am | #164

    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.

  64. Peter
    August 6, 2012 at 6:39 am | #165

    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.

    • September 3, 2012 at 6:03 pm | #166

      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.

  65. August 6, 2012 at 7:09 am | #167

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

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

  66. August 6, 2012 at 7:40 am | #168

    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.”

  67. carleeto
    August 6, 2012 at 7:54 am | #169

    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).

    • August 6, 2012 at 12:45 pm | #170

      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 | #171

      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 | #172

        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.

    • September 3, 2012 at 6:05 pm | #173

      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.

  68. August 6, 2012 at 10:19 am | #174

    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.

  69. August 6, 2012 at 2:43 pm | #175

    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 | #176

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

      • August 6, 2012 at 4:17 pm | #177

        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.

    • September 3, 2012 at 6:09 pm | #178

      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/

  70. NNM
    August 6, 2012 at 7:53 pm | #179

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

  71. August 6, 2012 at 8:47 pm | #180

    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

  72. August 6, 2012 at 9:14 pm | #181

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

  73. Riku
    August 6, 2012 at 9:52 pm | #182

    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.

    • September 3, 2012 at 6:12 pm | #183

      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 | #184

        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.

      • September 4, 2012 at 9:34 pm | #185

        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.

  74. Fred Yang
    August 6, 2012 at 10:37 pm | #186

    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

  75. rdm
    August 7, 2012 at 12:37 am | #187

    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

  76. August 7, 2012 at 2:37 am | #188

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

  77. Br.Bill
    August 7, 2012 at 4:05 am | #189

    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.

  78. ilupper
    August 7, 2012 at 4:38 am | #190

    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 | #191

      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?

    • August 7, 2012 at 4:55 am | #192

      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?

  79. Vincent
    August 7, 2012 at 6:53 am | #193

    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.

    • September 3, 2012 at 6:17 pm | #194

      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.

  80. Tacker
    August 7, 2012 at 7:59 am | #195

    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 :)

  81. Tyler
    August 7, 2012 at 9:04 am | #196

    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.

  82. August 7, 2012 at 10:26 am | #197

    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.” :)

  83. August 7, 2012 at 1:34 pm | #198

    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 | #199

      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.

  84. August 7, 2012 at 3:43 pm | #200

    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.

  85. August 7, 2012 at 5:38 pm | #201

    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.

    • steveko
      August 7, 2012 at 6:08 pm | #202

      Best comment so far!

  86. August 7, 2012 at 6:38 pm | #203

    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? ;)

  87. August 8, 2012 at 3:13 am | #204

    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.

  88. August 8, 2012 at 3:55 am | #205

    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.

  89. August 9, 2012 at 1:13 am | #206

    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.

  90. vectorgorgoth
    August 9, 2012 at 10:50 am | #207

    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 | #208

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

    • Brilliand
      October 23, 2012 at 9:02 am | #209

      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.

  91. LFM
    August 10, 2012 at 11:17 pm | #210

    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.

  92. August 11, 2012 at 2:14 am | #211

    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 | #212

      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 | #213

        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 | #214

      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.

      • September 5, 2012 at 7:59 am | #215

        Jepp. I use Mercurial for that…

      • wtpayne
        September 19, 2012 at 1:12 am | #216

        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 | #217

        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 | #218

        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 | #219

        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 | #220

        @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.

  93. August 11, 2012 at 2:19 am | #221

    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.)

    • steveko
      August 11, 2012 at 9:52 am | #222

      Great – I’ll have to try that.

  94. August 12, 2012 at 10:44 am | #223

    Love the diagrams… How did you make them?

  95. August 12, 2012 at 1:51 pm | #227

    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.

  96. steveko
    August 15, 2012 at 11:26 am | #228

    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.

    • September 3, 2012 at 6:25 pm | #229

      that’s what you get by using Mercurial: Power-users activate the extensions they want. All the others have safe defaults.

  97. asdf
    August 17, 2012 at 2:47 am | #230

    That’s why I love SVN+Tortoise :)

    • rdm
      August 20, 2012 at 11:38 am | #231

      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.

      • September 4, 2012 at 9:23 pm | #232

        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…).

  98. Sam Duke
    August 20, 2012 at 9:16 pm | #233

    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 | #234

      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 | #235

        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.

  99. August 29, 2012 at 3:02 pm | #236

    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 | #237

      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.

  100. Footman
    September 2, 2012 at 10:03 am | #238

    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.

    • September 3, 2012 at 6:32 pm | #239

      “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…

  101. September 3, 2012 at 9:49 pm | #240

    Finally, someone said it.

  102. jason
    September 4, 2012 at 12:57 pm | #241

    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.

    • September 4, 2012 at 9:29 pm | #242

      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 | #243

        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 | #244

        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 | #245

        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.

  103. rdm
    September 5, 2012 at 12:22 am | #246

    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.

    • September 5, 2012 at 5:50 am | #247

      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 | #248

        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).

      • September 5, 2012 at 10:47 pm | #249

        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 | #250

        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.

  104. rdm
    September 5, 2012 at 12:28 am | #251

    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.

    • September 5, 2012 at 5:02 am | #252

      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.

    • September 5, 2012 at 5:58 am | #253

      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.

  105. rdm
    September 5, 2012 at 12:29 am | #254

    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?

    • September 5, 2012 at 5:55 am | #255

      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 | #256

        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…

      • September 5, 2012 at 7:57 am | #257

        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: http://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 | #258

        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: http://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: http://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…

      • September 5, 2012 at 11:16 pm | #259

        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 :)

      • September 6, 2012 at 11:11 pm | #260

        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 | #261

        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.

  106. rdm
    September 6, 2012 at 12:44 am | #262

    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 | #263

      actually.. to some degree you are right about reset and checkout, I should think about that more.

    • September 6, 2012 at 7:38 pm | #264

      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.

    • September 6, 2012 at 7:48 pm | #265

      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.

  107. rdm
    September 7, 2012 at 12:02 am | #266

    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).

  108. tbxi
    September 12, 2012 at 8:16 pm | #267

    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 | #268

      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.

  109. nobar
    September 21, 2012 at 9:20 am | #269

    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.

  110. September 24, 2012 at 10:32 pm | #270

    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?

  111. September 25, 2012 at 9:12 pm | #271

    “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.

    • September 26, 2012 at 7:18 am | #272

      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…

  112. Kaysey
    October 1, 2012 at 10:02 pm | #273

    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.

    • October 19, 2012 at 7:25 am | #274

      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.

  113. October 3, 2012 at 6:23 pm | #275

    Nothing is better than CVS and SVN, I tried perforce, clear case and GIT but only like CVS and SVN .

  114. October 11, 2012 at 9:15 am | #276

    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.

  115. Johan
    October 11, 2012 at 9:28 pm | #277

    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.

  116. Git is awesome
    October 17, 2012 at 4:53 am | #278

    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.

    • October 19, 2012 at 7:38 am | #279

      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 | #280

      > 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.

  117. Don
    November 1, 2012 at 10:40 pm | #281

    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.

  118. demizeyde
    November 4, 2012 at 5:47 am | #284

    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.

  119. Gary
    November 6, 2012 at 5:38 am | #285

    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.

  120. Sean Roehnelt
    November 6, 2012 at 7:29 am | #286

    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.

  121. November 6, 2012 at 9:36 am | #287

    Reblogged this on Sergey Tihon's Blog and commented:
    Exactly the same emotions

  122. Doctor Who
    November 8, 2012 at 7:32 am | #288

    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.

  123. November 27, 2012 at 10:38 am | #289

    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.

    • December 28, 2012 at 2:03 pm | #290

      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 | #291

        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.

  124. Mike
    December 31, 2012 at 11:37 am | #292

    Git? I just don’t get it! there are no reliable tutorials. They all say something different and give no valid examples.

    • January 14, 2013 at 4:17 pm | #293

      Hey Mike, here’s one:

      Ry’s Git Tutorial at http://rypress.com/tutorials/git/index.html

      • rademi
        January 15, 2013 at 12:34 am | #294

        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).

  125. January 15, 2013 at 7:41 pm | #295

    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)

  126. systemBuilder
    January 16, 2013 at 1:04 pm | #296

    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!”…

  127. January 16, 2013 at 7:07 pm | #297

    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.

    • January 18, 2013 at 8:28 am | #298

      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 | #299

        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…)

  128. January 16, 2013 at 7:12 pm | #300

    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?

  129. January 20, 2013 at 10:57 am | #301

    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: http://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-500

  130. Chris
    January 26, 2013 at 12:37 am | #302

    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

  131. January 28, 2013 at 5:15 am | #303

    Here’s my recent rant on git: “…a Nightmare of Mixed Metaphors” –
    http://ventrellathing.wordpress.com/2013/01/25/git-a-nightmare-of-mixed-metaphors/
    -Jeffrey

  132. Paul
    February 1, 2013 at 7:24 pm | #304

    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.

  133. Mr. Lee
    February 5, 2013 at 7:17 am | #305

    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.

  134. February 7, 2013 at 2:42 am | #306

    “git checkout — ” performing a similar operation as “svn revert ” still gets me.

  135. February 13, 2013 at 1:40 pm | #307

    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.

    • February 14, 2013 at 12:54 am | #308

      > 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.

  136. February 13, 2013 at 1:56 pm | #309

    addendum: svn is not comparable to git. hg is the only free product which compares favourably to git.

  137. karl hoover
    February 14, 2013 at 4:50 am | #310

    There are thousands of medium size, commercial project for which svn is perfect. And I really like the ‘comparative anatomy’ diagrams. Thanks!

  138. mvswdev
    February 15, 2013 at 11:57 am | #311

    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 | #312

      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.

  139. Tony Cavanna
    February 24, 2013 at 7:00 pm | #313

    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 | #314

      Really? What was the sequence of events exactly? I get the message “Reinitialized existing Git repository in …”, and nothing is lost.

  140. Tony G
    February 26, 2013 at 8:01 am | #315

    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!

  141. Diego
    February 27, 2013 at 1:09 am | #316

    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 | #317

      >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.

  142. March 7, 2013 at 2:39 pm | #318

    The man pages are one almighty “fuck you”.

    This is officially my favorite thing on the Internet!

  143. April 24, 2013 at 9:23 am | #319

    As a long time Mercurial and BitBucket user I agree. I find Git to be terribly confusing, unintuitive and cumbersome to use. –JamesMills / prologic

  1. March 10, 2012 at 2:41 pm | #1
  2. March 10, 2012 at 2:52 pm | #2
  3. May 5, 2012 at 3:11 am | #3
  4. June 3, 2012 at 6:33 pm | #4
  5. August 6, 2012 at 10:00 pm | #5
  6. September 11, 2012 at 7:22 am | #6
  7. October 18, 2012 at 3:17 pm | #7
  8. November 13, 2012 at 1:05 am | #8
  9. January 22, 2013 at 11:48 am | #9
  10. January 25, 2013 at 7:55 pm | #10
  11. March 5, 2013 at 9:17 am | #11
  12. March 7, 2013 at 7:04 pm | #12

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: