Steve Bennett blogs
…about maps, open data, Git, and other tech.
10 things I hate about Git
Git is the source code version control system that is rapidly becoming the standard for open source projects. It has a powerful distributed model which allows advanced users to do tricky things with branches, and rewriting history. What a pity that it’s so hard to learn, has such an unpleasant command line interface, and treats its users with such utter contempt.
1. Complex information model
The information model is complicated – and you need to know all of it. As a point of reference, consider Subversion: you have files, a working directory, a repository, versions, branches, and tags. That’s pretty much everything you need to know. In fact, branches are tags, and files you already know about, so you really need to learn three new things. Versions are linear, with the odd merge. Now Git: you have files, a working tree, an index, a local repository, a remote repository, remotes (pointers to remote repositories), commits, treeishes (pointers to commits), branches, a stash… and you need to know all of it.
2. Crazy command line syntax
The command line syntax is completely arbitrary and inconsistent. Some “shortcuts” are graced with top level commands: “git pull” is exactly equivalent to “git fetch” followed by “git merge”. But the shortcut for “git branch” combined with “git checkout”? “git checkout -b”. Specifying filenames completely changes the semantics of some commands (“git commit” ignores local, unstaged changes in foo.txt; “git commit foo.txt” doesn’t). The various options of “git reset” do completely different things.
The most spectacular example of this is the command “git am”, which as far as I can tell, is something Linus hacked up and forced into the main codebase to solve a problem he was having one night. It combines email reading with patch applying, and thus uses a different patch syntax (specifically, one with email headers at the top).
3. Crappy documentation
The man pages are one almighty “fuck you”. They describe the commands from the perspective of a computer scientist, not a user. Case in point:
git-push – Update remote refs along with associated objects
Here’s a description for humans: git-push – Upload changes from your local repository into a remote repository
Update, another example: (thanks cgd)
git-rebase – Forward-port local commits to the updated upstream head
Translation: git-rebase – Sequentially regenerate a series of commits so they can be applied directly to the head node
4. Information model sprawl
Remember the complicated information model in step 1? It keeps growing, like a cancer. Keep using Git, and more concepts will occasionally drop out of the sky: refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces
5. Leaky abstraction
- Find the merge base between your branch and master: ‘git merge-base master yourbranch’
- Assuming you’ve already committed your changes, rebased your commit onto the merge base, then create a new branch:
- git rebase –onto <basecommit> HEAD~1 HEAD
- git checkout -b my-new-branch
- Checkout your ruggedisation branch, and remove the commit you just rebased: ‘git reset –hard HEAD~1’
- Merge your new branch back into ruggedisation: ‘git merge my-new-branch’
- 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’).
- Push your new branch (‘git push origin my-new-branch’) and log a pull request.
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:
- git add . / … / git push -f origin master
- git push origin +master
- 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
- Make some changes
- svn commit
If your changes involve creating new files, there’s a tricky extra step:
- Make some changes
- svn add
- svn commit
For a Github-hosted project, the following is basically the bare minimum:
- Make some changes
- git add [not to be confused with svn add]
- git commit
- git push
- Your changes are still only halfway there. Now login to Github, find your commit, and issue a “pull request” so that someone downstream can merge it.
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:
- git checkout master [to make sure each new feature starts from the baseline]
- git checkout -b newfeature
- Make some changes
- git add [not to be confused with svn add]
- git commit
- git push
- Now login to Github, switch to your newfeature branch, and issue a “pull request” so that the maintainer can merge it.
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.
And now here’s what you need to deal with for a typical 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.
- 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.
- 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”).
- 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.
- 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…
- Use Mercurial instead! Sure, if you’re the lucky person who gets to choose the VCS used by your project.
- Subversion has even worse problems! Probably. This post is about Git’s deficiencies. Subversion’s own crappiness is no excuse.
- 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.
- If you can’t understand it, you must be dumb. True to an extent, but see the previous point.
- 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:
- http://think-like-a-git.net/
- https://github.com/nvie/gitflow – a tool to support Vincent Driessent’s branching model.
- http://www.itworld.com/software/288711/things-people-hate-about-git – apparently a magazine article inspired by this post.
#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.)
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.)
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).
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.
“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.
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.
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/
“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.
basically you want git to bend to your will while thousand use it and don’t agree with you.
to bad :)
You put your comments in an excellent and well-balanced way as usual – a pleasure to read. I use and enjoy using git every day but it’s by no means my idea of an ideal tool & your comments rightly target both the inarguable shortcomings and the closed-minded defensiveness of the UNIX community.
I particularly have sympathy with your humorous summary “Git’s hard, deal with it.” It reminds me of a colleague who once remarked “Unix – you want friendly? Get a dog.”
For me, I have found SmartGit/Hg to be a wonderful utility that has opened up the power of git to me without screwing up my projects & it means I can basically forget about the command line for almost everything. I’ve tried many of other tools in anger and, for what is it worth, I think SmartGit/Hg is the simplest and best – and gets significantly better every version.
I have no affiliation with Syntevo or their product. This is simply my personal recommendation. I don’t have much money to spend on software these days, being a dad of three kids means I am perpetually poor, but I shelled out for this product because it meant I could use it at work, at home on my hobbies and on my open source projects in Windows, OS X and Linux. Syntevo have genuinely impressed me.
Life is too short to spend all on learning the power of GIT. Do you learn all engine mechanism when you buy a car? Car does solve your problem. To make it easy and powerful , you make different interfaces and abstractions (can achieve in same commandline). To do it, empty your cup and keep your reasoning reasonable to real world scenarios.
I have used mercurial, far easy and does job well than GIT. I don’t know why there is hype over GIT. What I will do with its almighty power, when it takes long to learn.
If GIT does not simplify its workflow and commands, other variant will come out of frustration because the community failed to recognize pain.
Thanks for voicing these concerns, and I believe git is (slowly) moving toward being more user friendly. Some developers tried to force the git kool-aid on me in 2009, and I steadfastly resisted, I was happier living in svn-hell than trying to make the jump to something “worse.” By 2013, I was forcing the git kool-aid on others, and liking it better than svn, it had matured considerably in the meantime and gotten much better integration with other tools.
Keep pointing out the flaws, once people adopt git they tend to forgit how seriously messed up it is, just because it is so much better than what they left. I’m introducing a new group to git as I type this, and they’re feeling the pain. It still could be easier than it is.
For a clean repository after git stash, one can, prior the stash, git add .
This will send all untracked files into the stash afterwards.
It was not a new concept. Git took a lot from BitKeeper which was not only not new but was deeply familiar to Kernel developers after years of use.
I’ve been using git for at least five years now, if not more. The only commands I’ve ever had to use are:
git pull : Get the remote commits
git push : Put my commits
git commit : Create a commit
git checkout : revert a file
git checkout -b : create a branch
git rebase : rewrite my local history to make it look as through the previous commits were always there to begin with. (rarely use this)
People make this more complicated then it needs to be. They either try porting over their concept of how SVN works and try to apply it to git. Or they start making needlessly complicated choices with how they want to manage their VCS.
how does bzr complicate things even more?
through mandatory branch-by-cloning and changing revision numbers as only identifier. At least that was ~1 year ago.
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/
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.
Steveko (and a few more people here) are very reasonable in their expectations that in the year 2016 we deserve to have tools with smart, rather than cryptic, user interface. And smart error and warning messages, that respect the user. But the Linux community was always opposite from that. Why?
Well, they’ve spent half of their life learning to use cryptic commands, and now they don’t want them simplified. But why? Here’s why:
1. Now that they have learned everything by heart, it seems easy. They’ve forget their own pain and now don’t understand how others can find it hard to learn. Why wouldn’t you spend a few months on this tool, a few years on that tool, another few years on another tool. After all we know that an average human being lives for 800 years, out of which the youth lasts for the first 750. Right?
2. Now that they’ve learned the tool, they don’t want user interface to change. Because that would mean they would have to learn it again. And feel that pain again… hmmmm, maybe that’s exactly what they deserve.
3. Now that they know how to use the tool, why would newbies have it any easier than they had? Let them go through the same hell. Let everyone forever use crappy UI just because they had to use it. Let in the 24th century Capt. Picard of the Enterprise be blown away by Klingons because the ‘git am’ patch didn’t apply the new photon torpedo launch procedure.
At the risk of over-repetition, tools that provide a friendly and much easier-to-understand front-end to git already exist. My favourite is SmartGit, which I have used for several years, but I am now using Sourcetree at work and I have to say that I am very comfortable with it too. It would be lovely to have the command-line interface tidied up but there’s no great urgency to do so when you have excellent GUIs like these. To everyone who is wrestling with the command-line – destress your life by downloading SmartGit, Sourcetree and GitKraken then picking the one you fancy.
Attributing this to the “Linux community” is false. The Linux community is also the origin of Mercurial (which is feature-equal to git and with a much easier command line interface – it is not only also from the Linux community, but just like git from Linux kernel developers) as well as wonderful graphical interfaces like TortoiseHG and KDE’s Dolphin.
There is a group of people who do not value good interfaces. But they are a subset of computer users, not a subset of the Linux community. And within the Linux community we at the same time have people who don’t value good interfaces and those who value them very much.
> 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/
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.
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 :) )
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
hm, lost a tag to the filter… rebase way again:
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]
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.
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.
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.
Most projects would accept patches by email from new/unproven devs in the SVN/CVS days.
Keep in mind that just because many Open-Source projects does that, doesn’t mean all have to, if you feel more like just allowing people to commit to your repository, then by all means… After all Forks and Pull-Requests isn’t even a Git thing, it’s a Github thing… (and other Git tools tend to begin to follow suit, like Stash)
I see it as a great feature…
Just allowing commit access to your repository is fine as long as there are few contributors, but how will you ever make sure that your projects stays on it’s track towards it’s vision if you allow thousands of contributors commit access?, even open source projects need someone at the rudder… I know from a “patchers” perspective, it may be a bit cumbersome, but as the tools get along it gets easier and easier to work this way, and today it’s mostly done with a single click of a button… All the commands are neatly hidden beneath…
Turn it around, many/most open source projects are handled in spare time, giving the repository owners more tools to manage what is accepted into the project at the expense of the developers time may seem ridiculous at first. But for each 15 minutes you may spend extra, you may save 5 minutes of the owners time… Try to multiply that by a thousands… If it becomes to big of a task to accept incoming patches, they bulk up and some of them will never be accepted because there simply isn’t enough time…
The Github model speeds that up for the owners by an incredible huge factor… Yes at the expense of your time… But in the end it means that more contributions are accepted in the end, doesn’t that serve everybody’s interest?
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.
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.)
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.
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.
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.
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!
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.
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?
And then there is http://fossil-scm.org/ with is a pleasure to use.
Here’s another vote for Fossil! The genius behind SQLite wrote it too, so it’s got good genes.
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).
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.
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.
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.
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.
Well, I’m personally not ok with it. I had to do this:
https://bitbucket.org/site/master/issue/3054/make-bitbucket-free
Oh, and I’m not the only one who is not ok with github’s non-free nature:
http://programmers.stackexchange.com/questions/129152/are-there-open-source-alternatives-to-bitbucket-github-kiln-and-similar-dvcs
http://mako.cc/writing/hill-free_tools.html
@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.
/jordi;
You summed it up perfectly, Jordi. ;)
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
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
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.
I’ve got nothing against the approach that led to Git being created. I just wish that:
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…
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”.
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”…
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.
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.
Arne is confusing the API, where your semantics are fixed once you name them, with user interface. The fact that the API and the commands can both be accessed by the shell *is* confusing.
“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!
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.
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.
Actually to maintain a large project in SVN is quite easy – you can easily checkout partial bits, merging and branching can apply to sub-sections of the repo (which is why svn merging isn’t quite as good as gits, it has to deal with more complexity). I worked on a 3Gb repo at a previous company, without any problems.
Part of the problem is that no-one considers the cases of a system they always prefer to spread FUD in favour of their preferred system. Don’t criticise someone else for spreading FUD and then do it yourself!
And *this* is why I avoid open source like the plague!
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.
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.
Just have a look at Mercurial. It shows how to do DVCS right.
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.
#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.
“Everyone is a committer, everyone is a maintainer.”
Well put – humble contributors never had to be maintainers before.
SVN is still around, there’s a reason for that.
«Visual SourceSafe Is still around, there’s a reason for that.»
And for both that reason it’s called “loss aversion”.
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.
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.
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”
I think you’re looking for “git merge master origin/master” in between the commit and the push.
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…
For my code to be safe I have to use a tool that safeguards my code from the ground up, and I must use that tool properly. Feeling has little to do with it, but nevertheless, with git I feel powerful and completely in control. How safe is my code? I have never lost any code with git. Glad to see I’m not alone with this feeling…
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
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?!
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.
I actually think git fails on both those counts.
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…”)
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.
“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….
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.
Pingback: 我痛恨Git的10个理由 | 曹志士
Pingback: 我痛恨 Git 的 10 个理由 - 博客 - 伯乐在线
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?
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.
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.
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.
“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.
I would agree, if I did not have Mercurial, which does everything git does while being easy to use.
That is a serious reason not to use it. The whole point of a SCM is to protect your commits. Anything else is just gravy.
I’ve worked at a place where every so often someone would pop up to the git guru and ask for assistance as they thought they’d just trashed their work. That might be ok in an open source situation, but totally unacceptable if you got paid to write it. I’ve used git for a project and all I did was commit and push to master (it was just me using it) but even then one day I found it had pushed to a branch and required a pull… I still have no idea how I managed that given my workflow.
Maybe when the SVN guys add shelving, the reasons people use git will go away, but I doubt that. The reasons to choose it seem more political than anything else. Maybe someone will create a ‘centralised SCM for decentralised teams’ that had the ease of SVN with the convenience of git.
“It appears a developer had returned from holiday and having found it hard to merge their work simply forced a push.”
This is not a git issue; it’s a management/training issue.
First time that happens, send the dev to be retrained, and restore from backups.
Second time, fire the dev for incompetence.
Yep. With enough training, all software is perfectly usable. :p
I think this may be the most hopeless defence of a system since Ribbentrop’s Nuremberg testimony. I hope your attitude isn’t prevalent in nuclear power stations!
As many here have tried before, you’re blaming the user not the interface. If your safety system is reliant on everybody knowing everything the self-appointed best coder knows, and having a backup system that is somehow bullet proof (and budget proof), and moreover that fear of dismissal is your primary data protection method, your company is quite clearly a terrible place to work. (although eventually self-correcting). It’s important to try and grasp the notion that humans are not meant to program computers. We’re bad at it. Your personal vision of yourself maybe a pointy eared vulcan, watching reams of matrix like code on six monitors, CSI-style speed typing away without a bug in sight but that’s not a terribly robust approach to software design for the majority. Also, we’re not actually discussing code here, the primary reason you employ a coder, but a support system, designed to make life easier.
Obviously I’m biased, as a games developer, but software developers or computer scientists who don’t understand or dismiss the importance of a good user interface are a menace to everybody working alongside them, simply from an employment perspective. In the shorter term, it should be obvious that a source control system, designed to transparently protect historical versions of code and resources, that encounters so much UI criticism, and that requires *such* a large body of non-coding knowledge in order to use without concern in day to day tasks, requires at the very least an overhaul. I would argue everything from terminology to failsafe conditions could do with some renewed thought. Like the SA-80 rifle, raw power is somewhat undermined if the tool sometimes kills the user.
Use SmartGit, Luk.
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.)
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).
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.
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).
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.
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..
Pingback: fl0blog » Blog Archive » Learning git
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.
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.
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.
Pingback: Free GIT repository hosting | rizwaniqbal.com
#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.
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.
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.
It is also not a safe tool. And that’s an unnecessary problem.
Speaking from my heart. Very good summary. Thank you for that
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.
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.
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.
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.
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.
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.
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.
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.
But repositories do have local names. A repository name is the file system path to the repository.
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”
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.
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.
Can you explain how something that saves everything is smaller than something that just saves differences? It makes no logical sense at least to me. Please explain!
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.
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.
and then there’s the 5%, which crop up every other day, providing limitless amounts of annoyances…
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?
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.
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.
I could not disagree more.. there is nothing more annoying then having to redo your workbench of whatever popular IDE you’re using every time you want to change branches. Let’s take IntelliJ for example. You can literally click in the bottom right, create a new branch, make changes, commit, switch back to another branch, merge, and never have to shutdown, restart, reconfigure, reset ENV paths, reset run paths, etc.
While idealism says the location of a project should never matter, when attempting to run large Enterprise apps, whether they be monolithic or micro-services based in nature, at some point your setup is going to rely on the specific location of your source code.
The separate directories is one of the more annoying things about SVN. The biggest being that it doesn’t actually support branching and it’s all smoke and mirrors.
Git allows you to switch between branches so quickly it’s hardly an issue. Not to mention that this is an invalid argument. Nothing stops someone from cloning a Git repository as many times as they want into as many directories as they want and changing the branches in each of the folders to be whichever branch they want. That’s sort of the point of Git. It’s distributed. You can run a whole distributed system locally without the need of a server.
There’s no argument for SVN to be had. Git supports what’s being talked about. It also supports having to NOT have a different folder for each branch. SVN supports this with switch if you want to risk losing all your code.
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.
Would you mind elaborating? It’s the same number of commands:
git add myfile
git commit -a -m “added my awesome file”
done.
People like to talk about the push/pull/fetch/rebase issues. But this turns the conversation into an Apples vs. Oranges comparison. Git is a distributed version control system. Trying to compare the entire _possibe_ workflow of a Git system to the single minded workflow of an SVN system is illogical.
You don’t have to push anything ever. In fact.. You can require OTHERS to pull from you and you’ll just be providing changes. As this is what Linus does.
If we want to get extremely picky and attempt to compare SVN vs. Git when adding a new file, these are the only commands you need:
git add myfile
git commit -a -m “added my awesome file”
git push origin master
done. The thing to remember here is that Git is NOT Client/Server based. This is why when you commit it doesn’t “go to some other server.” There are no servers, there’s only other participants in the commit graph you’re working on. And you can push your new commits to them or they can pull your commits into their’s.
The number of commands isn’t everything (though it’s not even the same numbe of commands: you have 3 git commands but only 2 svn commands).
In addition it’s having to remember to add `-a` (or customize the local git) because git defaults are a bad fit to this usecase.
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.
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…
It is unfortunate you lost code. That is probably one of developers worst nightmare. The person that put Git into place should have explained that it is ALMOST impossible to actually destroy data in Git. Even if you go through and force deletes (which can easily be locked out) the data still exists in the Git Garbage Collection. The Git GC doesn’t run constantly and can easily be used to recover data you’ve accidentally removed.
Even if you undo a commit in Git the proper way, you don’t actually remove that commit. What you’re doing is reapplying the reverse changes into a NEW commit. So the commit graph shows everything that has happened.
With all that said, here is how you setup a Git system for failure: Allow Force Push
Here’s a more elaborate explanation:
The people that are champions of using rebase do so WITHOUT telling people what is actually happening. If you are someone who likes to commit/push your changes often before you’re actually done and ready to merge them you can NEVER use rebase. You could destroy everyone else’s git repository.
Git rebase is used to replay the commits you have locally on top of commits that have been fetched from a remote graph. This sounds great as it can lead to a clean commit graph, but becomes a problem when someone (or some machine) already has your commits, even if it’s in a different branch. If those commits exist ANYWHERE else besides your machine, then rewriting the history will blow up the entire Git system. It can’t reconcile two different histories. Think of it as time travel. you’ve basically gone back in time and changed the order things happened. If you were the only one that have experienced those events in time no biggie. If anyone else has experienced those events in time, you’ve just potentially killed them.
So.. never ever ever rewrite history. If you check in a password and need to get rid of it.. It has to result in a complete and utter redo of everyone’s repository, meaning a reclone for everyone including the CI machine.
If you don’t try to rewrite history in git you can never lose data. And even if you do manage to remove something it is almost guaranteed to exist in the Git GC. Plus, who doesn’t copy their repo before they attempt a potentially devastating change? Whether I use SVN, Git whatever, I always zip copy my repo before merging, rebasing, renaming, etc. I don’t want to lose my code.
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.
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.
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.
Something I had to do every week while using SVN… That awesome mergeinfo property.. it’s so magical.
How does Github for Windows affect the equation? It is supposed to be a superior UI (at least for Git).
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.
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.
> 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.
I should add that I can’t really disagree with anything else you’ve said, so I guess it’s time to evaluate Fossil.
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.
Until you forgot you pushed that one time because someone really really needed something and now you’ve just wrecked the entire git history because IT didn’t disallowed force pushes.. What’s with the ‘clean history’ thing? Changing source code isn’t clean. It’s messy. You can pick a file, use blame to see what’s been changed and it all works regardless of a messy graph or not. Who really finds value from a ‘clean’ graph vs a ‘messy’ one apart from some need to make the pretty lines go the right direction. rebase is incredibly evil unless every single person that is using the system knows every single way to use git. Not stopping history rewrites and telling developers to use rebase is the quickest way to lose days of work weeks at a time.
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.
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 :)
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.
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 =)
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.)
To avoid the bug tracker loss, you can use the b-extension.
Well, in Mercurial… http://www.digitalgemstones.com/projects/b/
That way you have all your bugs in your repo.
And ideally you do the same for your documentation.
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.
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.
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.
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.
> 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.
Here here!
That mindset is one of the main reasons why git is hard to use…
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.)
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.
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).
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.
Agreed! Git is way too complex.
That’s why I built G2 !
https://github.com/orefalo/g2
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.
> 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.
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.
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.
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.
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).
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.
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
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.
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)
I like the way you explained certain things but the use of illustrative diagrams is more exciting…thanks
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?
“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).
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.
Nice suggestion – added.
> 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.
Do you like, not know about reflog or something?
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.
Oh yeah, and stash is freaking awesome, can’t live without stash.
So true, saying it’s useless almost sounds like trolling to me …
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/
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!
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.
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.
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.
> git branch -rv Lists local and remote tracking branches; shows latest commit message
You sure? Don’t you mean:
git branch -av
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.”
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).
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.
What kind of engineer defends a tool by saying “there’s nothing better, so get used to it”?
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.
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.
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.
+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.
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.
Wait, what’s wrong with “commit –amend -m …”?
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.
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/
Can I use this as my homepage? lol
Git is overrated bs.
Don’t bother replying, I won’t bother elaborating. I hate Git.
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
Your post is actually a great tutorial on how to use git. Thanks!
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.
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.
rdm :
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.
Pingback: 10 Things I hate about git | Part-time Life
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
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
Thank you for this well-timed post. It feels good to know that I’m not the only person who finds github impossibly confusing.
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.
Is it possible to merge in git 2 branches that’s not the current branch (aka checked out to the working dir)
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?
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?
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.
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.
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 :)
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.
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.” :)
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.
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.
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.
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.
Best comment so far!
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? ;)
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.
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.
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.
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.
Heh, still trying to work out if this comment is satire.
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.
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.
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!
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.
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…
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.
Jepp. I use Mercurial for that…
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.
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.
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.
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.
@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.
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.)
Great – I’ll have to try that.
Love the diagrams… How did you make them?
Omnigraffle (free version).
ah, damn. I had hoped you had used some free licensed tool I could adopt :)
(I wanted to write that question, too)
Now the lack of a free tool got me to seriously learn ditaa to make my own diagrams :)
→ diagram: http://draketo.de/files/hgbranchingoverview_2.png
→ source: http://draketo.de/files/2012-09-03-Mo-hg-branching-diagrams_6.org
→ created for: http://draketo.de/light/english/mercurial/complete-branching-strategy
Indirect thanks for that :)
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.
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.
that’s what you get by using Mercurial: Power-users activate the extensions they want. All the others have safe defaults.
That’s why I love SVN+Tortoise :)
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.
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…).
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.
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.
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.
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.
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.
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.
“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…
Finally, someone said it.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
So, if you are seriously talking about modifying git, why not introduce new commands that work the way you want them to work?
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…
I think you’re missing my point. In my opinion git is pretty much unfixable for several reasons:
* The default commands are unintuitive,
* The commands are really hard to change constructively because they are intended to be used in scripts,
* Regardless of that, the commands change in small ways, which don’t hurt small scripts but make full-featured commandline ui replacements hard to maintain and
* The community around git has quite a nonsignificant proportion of quite vocal people who say and mean stuff like this: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-357
I am forced to use git in some projects (or rather: was forced till I switched to using hg-git), and I got bitten by it quite badly a few times. Due to that I think that promoting git over equally powerful but easier to use solutions is a problem for making free DVCS systems become the de-facto standard – with the goal of replacing all unfree versioning tools (from VSS over Clearcase to TimeMachine).
For everyone who writes stuff like “finally someone said it” in here, there are likely hundreds of people who silently harbor a hate for git – and project that hate over to all other free software tools (because its shortcomings are so typical of early free software utilities). And those are the people who could really help free software.
…ok, now I framed git as harming free software. Please read this with a grain of salt: Git is a great tool. I just think that it is not the best, despite its popularity, and that other tools would draw more people towards free software and DVCS – and even more importantly: alienate less people.
Being a newcomer to git, and working with it, and helping others with less experience than I use it, I do not think that “the commands are unintuitive” is a real issue. In my mind the biggest problem is that I need to tell everyone I work with to use:
git config --global push.default current
This command means that
git push (without any file name)
only pushes the current branch. That’s not the default behavior, and that is tremendously confusing.
Once that’s out of the way, the recipes for git init and git clone combined with these commands, are pretty much all that I ever use:
push and pull:
git push -u
git pull
branch switching (and creating a new local copy of a known remote branch):
git checkout BRANCHNAME
git checkout -b REMOTEBRANCHNAME remotes/origin/REMOTEBRANCHNAME
branch creation and deletion:
git checkout -b NEWBRANCHNAME
git branch -D DEADBRANCHNAME (or maybe use a small -d if I'm paranoid that I had work on that branch)
janitorial cleanup:
git gc
git fetch --prune origin
git reset --hard (to throw away changes)
git reset --soft (to undo a commit that was on the wrong branch)
and queries
git status
git diff (sometimes with arguments)
git branch
and, of course
git add (with file names)
git commit -m 'message'
git merge (branchname)
Now, you can say that this is unintuitive, and I’ll grant that I’ve not spelled out ever detail of why I’d use these commands. But as near as I can tell the big “intuitive” issue is that we have multiple repositories with git — when I commit, I am committing to my local repository, not to some other repository. I own my local repository, and it can only include changes that I bring into it. If I’m being paranoid I might set up another local repository to pull into — this way I can pull changes and discard the entire repository if I don’t like them.
And no one that I work with uses rebase. Ever.
And if someone creates a problem for someone else, that person is responsible for fixing it. It sounds like some people posting in this forum don’t work with people that are responsible for fixing the problems they create. But I feel that that’s a social problem and not a git problem.
That last concept is worth repeating: If you are working with people that will not take responsibility for fixing the problems that they create, your life is going to be unpleasant. You are going to have a lot of frustrating experiences, cleaning up other people’s messes.
And if you feel that you need better tools, to cope with other people’s messes, so be it. Personally, I think that that problem should not be considered a technical problem, but a social problem.
I do wish that git could be configured to never allow a local name for a branch to differ from the remote name for a branch. But by restricting myself to the above commands (and note that I never name a branch during push nor pull), I get close enough to that ideal for me to get my job done.
As for the comment about “computer scientists” — my guess is the person making that comment does not understand the scientific process. (From my point of view, the closest thing to a “computer scientist” is someone that actively practices test first design, and that doesn’t even make sense as a constraint on git use.) I think we should ignore ignorant comments like that.
As for people that hate git and/or feel the need to blow off steam… *shrug* yes… haters are going to hate, or something like that. But if they want to have a coherent discussion about the problems that they are encountering, and I have the time and interest, I might try seeing if I can talk with them on some sort of reasonable basis.
This comment was rather long and I wish I could preview it before it goes live — here’s hoping that it doesn’t look too dumb…
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.
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 :)
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.
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.
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.
actually.. to some degree you are right about reset and checkout, I should think about that more.
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.
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.
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).
Pingback: git hates
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
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.
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.
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.
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?
“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.
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…
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.
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.
Nothing is better than CVS and SVN, I tried perforce, clear case and GIT but only like CVS and SVN .
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.
While they are smart, they are not brilliant. If they were, they wouldn’t have created such a mess in the first place.
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.
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.
> 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.
Pingback: Git is awful | Smash Company
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.
> Yes, the fundamentals are awesome
…Except for the mandatory garbage collection (even anonymous branching could be crafted by a good UI choosing temporary branch names automatically, but the garbage collection is unfixable)
for an example of the effects of the garbage collection, see http://draketo.de/proj/hg-vs-git-server/test-results.html#results
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.
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.
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.
Reblogged this on Sergey Tihon's Blog and commented:
Exactly the same emotions
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.
Pingback: git vs svn | objetweb
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.
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.
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.
Git? I just don’t get it! there are no reliable tutorials. They all say something different and give no valid examples.
Hey Mike, here’s one:
Ry’s Git Tutorial at http://rypress.com/tutorials/git/index.html
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).
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)
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!”…
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.
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”).
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…)
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?
That possibility always exists, especially for complex topics.
But the google hosting is no real counter-example: It shows a handful of projects which chose to not use googlecode…
The example I showed is not what google does today (it now also offers git for code hosting, see the group effects), but why they chose to use Mercurial:
Mercurial offers an excellent “sweet spot” in terms of flexibility, simplicity, and speed. – Alex Martelli, Google Tech Lead
And for me: I have more usability problems with git itself than with github. I wrote some of my reasons and wishes herein our previous discussion here: https://steveko.wordpress.com/2012/02/24/10-things-i-hate-about-git/#comment-500
Pingback: gitの図 at softelメモ
Pingback: GIT: a Nightmare of Mixed Metaphors – Ventrella Thing
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
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
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.
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.
“git checkout — ” performing a similar operation as “svn revert ” still gets me.
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.
> 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.
addendum: svn is not comparable to git. hg is the only free product which compares favourably to git.
There are thousands of medium size, commercial project for which svn is perfect. And I really like the ‘comparative anatomy’ diagrams. Thanks!
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
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.
I’ve just discovered git init will overwrite a repository without question. Just lost a day’s work, restoring my source from backups.
Really? What was the sequence of events exactly? I get the message “Reinitialized existing Git repository in …”, and nothing is lost.
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!
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.
>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.
Pingback: kirjoittaessani » Blog Archive » Revisionismus
The man pages are one almighty “fuck you”.
This is officially my favorite thing on the Internet!
Pingback: Git מהשוחות, אמנות אסקי יהודית בגטו ועוד. קריאה קוד פתוח ושיטוט ברשת « טכנולוגיה בשביל אנשים
As a long time Mercurial and BitBucket user I agree. I find Git to be terribly confusing, unintuitive and cumbersome to use. –JamesMills / prologic
While I agree to a greater or lesser extent to all the points made in this article, the advantages of git are so compelling I would never select Subversion in preference – and I never expect to have a use for Subversion again. For me, SmartGit/Hg tamed git and made it very simple to drive effectively.
The key defect of git from my perspective is that is cannot handle files > 2GB in size. I work in GIS and that’s not a particularly large file; files up to 10GB are commonplace. Although I don’t especially want to version control such large data files, I do want to manage them and base my development platform on a single repository with a single API. It seems surprising weakness to me.
Mercurial and Bazaar also seem like fine tools, with slightly different strengths and weaknesses. I have not spent much time on them, other than to verify that they also suffer from the same irritating defect and hence I have no compelling reason to switch.
Interesting perspective. I do understand what you mean: you don’t want to *version* the GIS files exactly, but you do want them stored in the same repository as the rest of your project.
That’s exactly it. I am aware of projects such as git-media, of course, but they are band-aids. (Apologies for the typos in my original post).
You need http://git-annex.branchable.com/
I was aware of git-annex but thank you. Git-annex is still an band-aid however, in the sense that it isn’t integrated into git tools (such as smart-git or sourcetree etc). The inability to correctly handle large binary objects seems to be a inarguably shortcoming in git.
Pingback: Free GIT repository hosting | Think Digital, Talk #Interactive
Pingback: River Recycled » From Twitter: Continuing my anti #git ranting. this suits my moo… » The Same River. Twice.
git gets easier once you get the basic idea that branches are homeomorphic endofunctors mapping submanifolds of a Hilbert space.
Thanks for your excellent, well thought out comments, Steve.
Pingback: Blackmoor Vituperative » I dislike Git
Thanks for the “bread and butter” figure. It really helps me understand git.
I guess GIT screams for someone for someone for someone to make a decent interface for it (probably paid for). Most of the issues would then either be bypassed or simplified and probably something like a cutback form for users.
I’ve been thinking recently about this very issue. It seems noncontroversial to say that git has the best adoption and the strongest architecture. It’s true that there are some great git clients out there which help get you access to that strong architecture. I’ve tried Tower and Gitbox and others. They help, but the complexity of the system, even for not-very-advanced tasks, comes out if you need to do anything besides clone, commit, pull, push, and merge without conflicts.
I think there’s definitely room out there for a git command line abstraction that thinks about every common case that a contributing developer would come up against, and basically maps those use cases into git commands. GUIs could be built on top of that command line abstraction, but without the abstraction first, the temptation with a GUI is just to give buttons for each command. With git, I don’t think that’s good enough.
Would someone else want to work on this? Does this sound like a promising idea? I’ve seen some other tools try this but I don’t think they go far enough. Simplification for this would be really, really difficult and require a deep as sea trenches understanding of everything that can happen when you want to, say, undo a commit.
In a way this could be like “Javascript the good parts” for git. List out all the common end-user workflows, build aliases/scripts/walkthroughs for them that cover all the bare metal decisions your average contributor doesn’t want to have to make (undo commit that has/hasn’t been pushed to remote, push before pulling intentionally(?), rebasing vs merging).
I’d view such a project a success if it could work for a team of 1-20 developers managing a repository that does basic staging, production, and version tagging contribution behavior and they could learn the whole thing in less time that it takes them to figure out why their git 3-way merge thinks the wrong side is more up to date.
Very insightful comments. Working on a project like this, although very valuable, could be unrewarding. As you point out, you’d need a very deep knowledge – but once you get to that level, you may not be so motivated (because, after all, Git is so simple now!) I doubt you’d get much support (if not downright hostility) from the main Git developers, so you could be working in isolation for years, constantly frustrated by small changes in Git’s internals.
Why not just map the command line with intelligent logic- do not delve into the internals of git- sure they might change the commands but that can be patched over. If need be merely hide the command line and simulate keystrokes.
Pingback: Don’t be a git, use subversion | ebeab
Another issue for me is the impossibility of checking out just one folder of my repository, not the repository as whole.
I understand the concept of Git managing “projects” in the meaning of “you have to check out everything or nothing” but this is often not the way I need a version control to work.
Example: I provide several useful files for my company: a LaTeX tree, OpenOffice templates, Office templates etc. A user interested in the LaTeX tree only does “svn checkout …/trunk/latex” and is done. In git she has to clone the whole repository including all branches tags etc. and then has to use the one folder she is interested in.
Thus I still use svn for this project only to avoid this special issue.
svn is great if you want to prevent shared ownership – if what you want to prevent is group effort. (cvs is another possibility for that.) There’s nothing wrong with hating git – if what you need is a bottleneck – if git is the wrong tool for you.
It is possible to dislike git without preferring svn. I wonder whether you tried the DVCS alternatives. Compared to git, the Mercurial UI is wonderful…
It’s possible to hate part of something without hating the whole thing. (Hating your government without hating your country.)
It’s possible to hate one thing without preferring a certain other thing. (You think Git is a 3/10 but SVN is a 2/10.)
Lol, so many git haters and all i see is complaining about things that they don’t understand.
Or, to put it another way, the mismatch between git’s functionality and version control functionality that leads to confusion and disdain.
Also please do not mistake criticism for hate: I prefer git over svn any day. But it loses to Mercurial by a huge margin.
>Lol, so many git haters and all i see is complaining about things that they don’t understand.
That’s kind of the point, actually.
I doubt that the people posting here are stupid. Still it requires more time and work to understand git good enough than they may be willing (or paid for) to spend on understanding their version control system.
The version control system should not be harder to understand than the code itself.
That so many people do not understand git is not a good sign…
I don’t get it?
What’s there to get? :) It is indeed bad sign that people have a problem understanding something that intuitive :)
http://4.bp.blogspot.com/-9C8qiz5gmS8/TmzA5DW-EMI/AAAAAAAABjI/RhyCGbgSIls/s640/bad+sign.JPG :)
I’ve used a variety of VCSs over the years and finally stumbled (got lumbered) on Git. A long-long time ago I used CVS (I cant remember much except it was a bit crap). Then we got VSS (absolute crap and dangerous), then SVN (yeaa! happiness at last). Then in one company I worked in an abomination called “AccuRev” was intoduced, an interesting attempt to create a visual UI, some good ideas but so horrible that we needed a support team to look after it. Then I discovered DVCS and Mercurial (enlightenment and bliss). Used it for two years in my last job (still using it for my own stuff on BitBucket). For the last year I’m working in a company that is migrating from a mix of VSS (aargh) and SVN (I know, mad in 2013). My boss has decided that Git is the way to go even though I am the only one in the company with DVCS experience and would much rather use HG. I set up a server in-house with a demo repo, wrote a three page guide for everyone (and pointed them to Joel Spolsky’s excellent hginit tutorial) but no, my boss is insisting on Git. I’ve spent the past few days cursing and gnashing as I’ve tried to set up the Git server on Windows and port a few projects into it (the pain!, thanks to Tim Davis ‘http://www.timdavis.com.au/git/setting-up-a-msysgit-server-with-copssh-on-windows/’ for really trying to explain it all). It’s got to the stage where I’m about to tell my boss it’s HG or I’m outa here…
Try to look at some of the 3rd party suppliers, I have never ever installed a pure git server my self, but Stash (from Atlassian) was virtually pain free…
Overall it seems there are more momentum on git these days, e.g. Atlassian adopting it in Stash, Microsoft delivers git integration in Visual Studio and many others… So it might not be such a un-informed choice to adopt it over e.g HG…
I can second you on that It’s a damn risky decision if you don’t have any in-house that has the knowledge though… But top bosses often tend to think in terms of “That is what they all talk about, so we should go there to…”, and while it’s a decent philosophy on some cases, you need to be ready to pay the price.
Anyways, 3rd party integration’s can help you… And one thing is initial installation, another is ongoing maintenance and administration, tools like Github Enterprise and Stash can IMO really help here… Even for my personal SVN i found it far easier to just install CollabNet’s subversion edge over a standard subversion server…
Pingback: Some notes and links on DVCS (dynamic version control systems) « The Wiert Corner – irregular stream of stuff
I actually had to turn down a client because they use git. I got fed up doing 1 hour billable work and 4 (unpaid) hours trying to figure out what git did. Too bad it wasn’t designed better. Oh well, lots of other choices.
GIT is state of art software and if you have problem with it, then it is more likely that you should debug relation between chair and keyboard, rather than trying to figure out “what git did”
The only thing about GIT that’s ‘state of the art’ is the concept. There is no doubt that DVCS is the way to go. Making DVCS hard is not ‘state of the art’. Mercurial (which is what I use at the moment) is at least consistent and pretty quick to learn and easy to use every day. It’s not because I learned it first that I prefer HG (SVN was the third ‘traditional’ VCS system I learned and easily the best). When I learned HG I had a number of tasks to accomplish, learn the DVCS concepts, learn HG itself and learn to set up and use remote HG servers. I came to Git with an open mind (I was genuinely interested in adding another VCS to my repertoire) but the pain was too much especially in setting up a server for the team. From nothing to a server supporting a few HG repos was an hour or two. With Git I gave up after two days. I’m not smart enough, obviously.
Well, in my personal experience, I had a problem “to get the mindset”, but then I started to work with it and beside few occasional issues mostly produced by me or someone from my team, it is a lifesaver… I really can’t imagine to work without it… I do have some little experience with Mercurial, but that long time ago. I would like to try it again, but there is really no need (for my team, I’m not saying someone doesn’t like anything else better)
Once we started to practice http://nvie.com/posts/a-successful-git-branching-model/ our git troubles are mostly based on “someone didn’t follow the rules”, but even in that case we always managed.
I am kind of sad when I see many people in this thread are spiting all over git, but for very wrong reasons, especially if they like SVN…that is just wrong :(
http://www.sourcetreeapp.com/
Atlassian makes a this great free git client that handles most of your common git tasks without any command line work.
Yeah, SourceTree is pretty good. It does a great job of helping you understand exactly what mess you’ve gotten into this time.
Steve agreed 100%. Unfortunaltey what sells in IT is complexity not common sense
I don’t think that logic holds. There are hundreds of technologies that have done very well due to making a complex problem very simple. Git has succeeded in spite of its complexity, not because of it. If there was a simpler version, I think that’d do pretty well.
I honestly disagree. git succeeds despite its complexity because what it offers is so good.
I’ve been using git for over a year and it has only provided frustration and suffering, though I can appreciate it’s power. I’ve nevertheless managed to trash my repository several times trying to fix what should be trivial issues. You are right on that git is made for power users not the end user.
One extreme annoyance for me is that I need to distribute my code over several machines from which I do not intend to do any development. In fact for most use cases, when I want to pull code out of the git repository I want to replace whatever rotten old code I have in the current directory, ie I just need an update to the latest. To do this I must use the extremely hard to remember commands,
git fetch origin master
git reset –hard FETCH_HEAD
The git developers apparently never thought that some people might just want to use git to fetch code. I have found that it is much safer to only develop code for my repository from one golden directory. Otherwise you can get unwanted merges that are a pain in the arse to unwind. In fact it is not that unusual to alter compile flags that are specific to the architecture of a given machine, or to set data directories in source configuration scripts that are also specific to a given machine. I don’t want to pollute the repository with that sort of thing. Yes there are commands that enable this such as the -s ours flags etc., but it is very hard to remember the exact syntax, since, as described it is not consistent.
Someone really needs to develop a consistent easy user interface overlay for git for common simplified workflows. I also find it annoying that the gui’s that are provided don’t have some of the most important commands. git gui is very poor with regards to fetching and merging but pretty good with regards to adding committing and pushing.
Did you try switching to Mercurial? Your usecase would be resolved with `hg pull -u`.
hg-git allows you to easily access git repositories with Mercurial.
First of all thanks for your post. At work we use subversion; while I start to get used to git, I do not think it would be a good idea to introduce it at work exactly because of its complexity; so yes I fully understand why you “hate” git.
Still I think some of your points are not very valid:
1. Complex information model
Hmmm. The way most tutorials are written you are correct. The main reason why I still disagree is, because once you look at the “advanced” stuff it actually gets simpler. Once you understand that git stores three main types of objects (blob, tree, commit) + each object is referenced by a SHA-1 checksum over its content, the information model starts to look a lot simpler.
After that reading https://www.kernel.org/pub/software/scm/git/docs/gitglossary.html clears up lots of questions.
2. Crazy command line syntax
I agree. It really could be better; but then again it would be really easy to make it less crazy if people cared enough.
What about the project “Easy Git” ?
3. Crappy documentation
I agree that the man pages do not make sense to a new user. But that is because you first should understand about git objects, then understand of local / remote repositories, then read “gitglossary” and then at last read the man pages of the commands (at least this was the order which made most sense to me).
I once gave an introduction to subversion. If you talk to people, which are completely new to version control in general, then even this is hard, even if the concepts in subversion are much simpler and easier to understand. I think that learning something completely new usually means that the terminology will sound like gibberish.
4. Information model sprawl
Once you understood about “blob”, “tree”, “commit” it does not seem so complicated anymore…
The biggest problem seems to decide how to organize branches for a given project. With subversion this seems to be even harder; at least from my experience.
5. Leaky abstraction
The example you give here seems to be something which you could not even do in subversion ?
So the complaint seems to be, that you do something quite complicated and it turns out that doing it requires a set of complicated commands. This seems not very surprising. Maybe what you were trying to do was not complicated ? But then it might help to explain first what you were trying to do, before complaining.
The “no abstraction” means that you are able to do these complicated things, because these complicated things do not allow for an easy abstraction…
6. Power for the maintainer, at the expense of the contributor
In all your examples you seem to assume a model in which everybody has write access to a central repository. At least that would be the “easy” case in subversion.
How would you setup a maintainer kind of workflow with subversion ?
I am really interested, because I really have no clue how that would work:
– Checkout
– Modify
Now:
– Commit ? Hardly; I do not think everybody gets write access to the central repository
– Commit to some other repository, which was cloned somehow ? Who then integrates my changes into the “master” repository ? A maintainer ??? this poor guy! How do I get updates from the “master” repository ?
So what would be the easy workflow without expense for the contributer ?
7. Unsafe version control
That was an interesting topic, because I am still quite new to git and understood the concern. After googling: What about
git config receive.denyNonFastForwards true
on the “master” repository. This seems to avoid most of what you are worried about or am I wrong here ?
In general all of this assumes that you have write access to the master repository.
As I said I do not understand how you would have a maintainer like workflow, if everybody has write access.
8. Burden of VCS maintainance pushed to contributors
How do you “update/commit/update/commit” without write access ?
How do you have a maintainer if everybody has write access ?
I do not seem to understand how you would implement your supposedly simple workflow.
What happens in the case of “update/commit” … oh crap I broke the build ?
“undo commit” (not really possible in subversion) ?
revert change then commit ? What happens with the user users who already “updated” the broken commit ?
Maybe they fixed it on their local working copy and now get conflicts when they update my “undo commit”…
The model you describe seems to put a lot of responsibilty on the contributors; they really should not make any mistakes, because it hurts everybody else.
9. Git history is a bunch of lies
“Surely the correct solution is a better log output that can filter out these unwanted merges.”
That sounds like you want a sophisticated AI as a filter. When I look at the logs of our subversion repository at work it is quite hard to tell which log entries might be merged; so no clue how a computer might do that.
Git history on the central repository (or master repository) is only a lie if you allow it, by allowing non-fast-forward updates.
10. Simple tasks need so many commands
This is mostly unfair. If you want to do the same as subversion you would do
1. modify
2. git commit -a
3. git push
So exactly one more step than in subversion. The git way allows you to do “git status” (ok I did not forget anything), compile … broke the build; oh good I can still fix it, before anyone notices it and gets angry.
The thing about github only applies if you use github. You compare oranges with apples; a central subversion repository with github…
Note that after using git for a while, I never use “git commit -a”. It simply happens far too often that I modify several files, but only want to commit few of them. It is much easier to first use “git add”, then “git diff –cached” to see if you really got everything and then use “git commit” to commit exactly that (yes I agree: The syntax could be more obvious). With the subversion command line there simply is no way to do that; you need “svn commit ” and sometimes you might commit too much or not enough.
Another example: “git stash”. The way I do that with subversion is, to first use “svn diff” to create a patch file, then undo all my changes with “svn revert” and then to reapply the changes later when I am done with whatever I wanted to do. Note that re-applying the patches requires “patch” a non-subersion command as far as I know. So the “simple tasks need so many commands” applies to subversion in this case.
…
“As an added bonus, here’s a diagram illustrating the commands a typical developer on a traditional Subversion project needed to know about to get their work done.”
And where is the maintainer in this picture ?
That is where the complexity from the github example comes from. So again you compare apples and oranges.
Summary: I still completely agree that git is a lot more complex than subversion. Yes it really lets you shoot into your food. Still I am not convinced that subversion is so much easier (I just have to remember the svn-property and “how to merge” discussions we had at work).
>The main reason why I still disagree is, because once you look at the “advanced” stuff it actually gets simpler. Once you understand that git stores three main types of objects (blob, tree, commit) +…
This is kind of true, which is very weird. You really, really shouldn’t need to know this stuff.
>2. Crazy command line syntax I agree. It really could be better; but then again it would be really easy to make it less crazy if people cared enough. What about the project “Easy Git” ?
I don’t think it’s about “caring”, it’s that the syntax is too hard to change now. The attempt to separate “porcelain” and “plumbing” has failed. EasyGit doesn’t go far enough.
>That was an interesting topic, because I am still quite new to git and understood the concern. After googling: What about git config receive.denyNonFastForwards true on the “master” repository. This seems to avoid most of what you are worried about or am I wrong here ?
I think if new users need to set some hidden flag on their repositories in order to protect against data loss, my point is confirmed, no?
>The model you describe seems to put a lot of responsibilty on the contributors; they really should not make any mistakes, because it hurts everybody else.
I’m not really advocating for “everyone has write access” workflows. I’m just pointing out how complicated the default workflow is for Github. GitFlow probably improves things a lot.
>Git history on the central repository (or master repository) is only a lie if you allow it, by allowing non-fast-forward updates.
Interesting idea, thanks.
>Still I am not convinced that subversion is so much easier (I just have to remember the svn-property and “how to merge” discussions we had at work).
Yep, Subversion is too limited for modern development.
Pingback: Learning to Code | Quartet
I agree, and I could probably add 10 reasons more to hate git :)
I hate git right now. It is the source of great frustration. :/ Suck it, git!
These things should be much much easier to do, instead it’s harder than actual programming and such.
I’ll repeat my recommendation for SmartGit (http://www.syntevo.com/smartgithg/), a tool that makes git a pleasure to use. I have no affiliation with Syntevo but simply pleased to be able to pass on my positive experience. I have used pretty much every tool out there and this is the only one I can wholeheartedly recommend.
Good luck!
Pingback: Learning to Code | Decluttr
Someone probably said that already, but the Information Model is not that complex, given the decentralized nature of Git. Repositories are repositories, whether they are remote or local. Tags are actually tags, much closer to the real life thing than in SVN, and there is no trunk, which was some kind of a fuzzy notion in SVN. Commits are still commits, on SVN same as on Git. I don’t know what treeishes would be. Stash is just like a commit, and you don’t have to use it if you don’t like/understand/feel comfortable with it.
But I guess all this is just a matter of perspective.
Apparently, you have been spending a lot of time on Github, and it is the real target of several of your criticisms. The thing is, a/ I don’t know any code hosting system that allow anyone to do something similar with SVN (I’m only talking about the pull request part, of course), making the comparison quite pointless, b/ github is not git. It is one way of using it. Most usage of git I have seen are very similar to what SVN was like before the switch, only more powerful (not going to be to long on that, but the merge tracking alone justifies the switch)
Last point, regarding rebase, it is not a “lie”. The commits you push to the remote are not modified once they are pushed. No pull is ever made of a different tree, history is not rewritten, you simply apply your work on top of the latest remote version. (If you use rebase after a pull has been made on your repo, that’s a different story, but the SVN admin could do just the same).
>Repositories are repositories, whether they are remote or local.
Remote repositories, local repositories, and local copies of remote repositories (ie, origin/master) all behave differently on the command line.
> there is no trunk, which was some kind of a fuzzy notion in SVN
“master” is a pretty fuzzy notion in Git.
> I don’t know what treeishes would be
That’s what Google is for.
> Stash is just like a commit, and you don’t have to use it if you don’t like/understand/feel comfortable with it.
Except the syntax is all different and a few other peculiarities.
> Last point, regarding rebase, it is not a “lie”.
If the sequence of development goes A-B-C-D-E, yet the version history after a rebase goes A-C-E-B-D, I think “lie” is an apt description.
> > > Last point, regarding rebase, it is not a “lie”. > > If the sequence of development goes A-B-C-D-E, yet the version history after a rebase goes A-C-E-B-D, I think “lie” is an apt description. >
Agree.
I think an important default behavior would be for rebase to be the default merge behavior when history lines up correctly; automatically use merge instead if/when history isn’t congruent. In other words, new commits should normally go on top of pulled changes regardless of the timestamps without requiring a different set of commands or prior knowledge if what has changed in the remote repo.
Another related behavior that would help me understand our current repos would be for git to show history in merge order instead of commit timestamp order by default, or at least provide an easy tool to display history in merge order.
>
> new commits should normally go on top of pulled changes regardless of the timestamps without requiring a different set of commands or prior knowledge if what has changed in the remote repo.
New commits go to the top by definition. Of course, by the time you pull, they are old commits. You might be thinking of unpublished vs. published commits – but the software cannot reliably determine which is which. You can set the pull behavior per-branch via the branch..rebase config option.
> Another related behavior that would help me understand our current repos would be for git to show history in merge order instead of commit timestamp order by default, or at least provide an easy tool to display history in merge order.
What do you mean by “merge order”? Commits which happened on different branches do not have any obvious ordering. If you want to keep together consecutive commits as much as possible, you might be looking for the –topo-order flag.
At first I was going to hate, but then after getting through your post I think it’s pretty well written. I’m not expert so I can’t debate. My only confusion is when you compare SVN process to GIT why you also talk about github. I don’t use github professionally so it clouds the point a bit. I do use github for my public/personal code.
I wrote the article about my own personal experiences with Git which all involved (and still do) Github. I almost never come across projects that use Git but don’t use Github in either my work or sideprojects.
fair enough. I mean I use github for my public projects but I also don’t do much collab on there. I use just git on the commandline for my private projects and for work we use gitlab which is just an alternative to github. But without me knowing better I wouldn’t think you’d need any gui (gitui, github, gitlab etc) to manage repositories. So I’m just saying if you take that out of the equation I wonder how its diagram compares to svn in complexity. I figured github was just for managing repo’s and users in a GUI friendly way, and to merge forks and stuff like that, but not necessary.
Perfect article which reminded me of my 9-month experience with Git after 5 years of experience with SVN. I definitely agree that user interface of Git totally sucks comparing to one of SVN. Git beats SVN in lots of things just because it is DISTRIBUTED version control system (VCS), while SVN is centralized one (ironically 90% of Git supporters doesn’t know the difference :)).
So, I’ll add to superb comparison of “Granny on the freeway”:
Git is like Formula-1 sports car – it accellerates very fast, it brakes very good. In hands of a professional it’s really awesome tool. But for beginner to intermediate user it’s total overkill and out there there are 95% of such users.
SVN is like normal city car – it has normal engine, normal brakes and normal suspension and hence fits 95% of use cases. Any professional on this car will easily beat beginner on Formula-1 simply because he/she knows that in most cases power is not what matters.
So, 90% of arguments for Git over SVN looked like advocating Formula-1 car in small city over normal city car just because it’s so damn fast :)
Pingback: My Journey Towards Learning Git | Robert Cina Online
Great article. I must say it has been quite “challenging” being forced to switch to Git from SVN. It is a completely different mindset which I have had trouble switching to after 12 years of Clearcase, then SVN. I got very use to using SVN through Eclipse and using Git through Eclipse seems to be much more difficult, at least at the very beginning.
The bottom line for me is simply that Git is in my way. It consumes more time $@#&ing with it than it’s worth. Source control should be a tool to enable my coworkers and I to collaborate effectively while focusing on the core work of programming. As such, I need them to have a tool that’s simple and bulletproof. Git is anything but.
Glenn, I totally approve of your approach. However, I must also admit it is not for me.
See… from my point of view what you are telling me is that you (a) do not understand Git, and (b) are happy with the alternative you are using. So you are not motivated to change. That might change in the future, but that future has not arrived, yet.
That said, if we were working together? I would bet that I could have you up and productive with Git within an hour (probably half an hour, but let’s allow some time for unanticipated problems…).
Something similar could probably be said of other tools (like Hg). Proficient technical people learn to take advantage of their tools, whatever they are, and to focus on delivering what some people ask them to deliver. [Management, of course, has a slightly different job.]
That is then an hour you spend, getting someone else up to speed. And if stuff I read on the internet is of any value, he will keep stumbling regularly and ask you again.
With hg you could say that I have that position in the team I work in. We have 3 people not really familiar with version tracking. And in 2 years, I got about 6 questions after the initial setup. Not per month and not per year, but overall. How’s your mileage with git?
Maybe, yes. But often enough that hour spent saves me a good 10-30 hours over the course of a year. Also, most of the younger programmers I have worked with already know how to use git. So it’s really not that big of an issue for me.
Also, a lot of problems with git are really github issues, and most of those can be resolved by cloning a fresh repository and working with it. Most of the remainder can be resolved by making sure that they are using a relatively recent version of git.
Hi again,
I still would really like to know how to setup Subversion in such a way, that you get a maintainer workflow. You write:
——- snip ————
8. Burden of VCS maintainance pushed to contributors
In the traditional open source project, only one person had to deal with the complexities of branches and merges: the maintainer
…
—— snip ———-
I work with Subversion each day, but I still have no clue how you would setup a maintainer if you have a central Subversion repository.
How would you do that ?
I am really interested, because I certainly do not know.
Hmm. lundril, if you seriously need to know how to do maintainer branching patterns with Subversion, ping me at my consulting address http://opentechstrategies.com/. (This is not meant as a statement one way or the other in the git-vs-subversion debate, by the way. Git has great branching and merging, and I use it all the time. But I couldn’t tell if your question was just part of the conversation, or was an actual attempt to find help for your workplace. If the latter, I’m happy to take a look, though it sounds like you understand Subversion pretty well and basically are just missing what you’d get from Git.)
Pingback: Version control Part 1: Local repository | Tom Wallis
Pingback: The Git Reference | Tamasdan.com
> “git pull” is exactly equivalent to “git fetch” followed by “git merge”.
Actually, “git pull” does more than that; it also spots upstream squashes. See http://gitolite.com/git-pull–rebase.html
Pingback: Git: what they didn’t tell you | Steve Bennett blogs
Yikes. Interesting post. From my experience it’s like someone trying to re-invent the wheel. First time I used Git, I had conflicts on my second commit. It’s not as much about the tool you use, but more about how you use the tool at hand. In repository’s case, for the projects that I’ve worked on, SVN is just fine. No need to complicate things.
What flowchart software let you make the beautiful charts in the article? Thx!
Omnigraffle.
You’ve summed up my feelings with more educated examples. I gave up on subversion in favor of git, and I think it has the features that I want. But, man, it is so difficult figuring out the way to use that functionality.
It was extremely easy getting the repository and first import setup, but after that, the developers decided to let the users suck it after that.
Amen brother! I am boggled by how the industry is turning to favor Git and not Subversion.
> To reset one file in your working directory to its committed state:
> git checkout file.txt
It seems that the correct command is
git checkout HEAD file.txt
or
git checkout HEAD — file.txt
I was bitten by this. When you pass paths or –patch, git checkout defaults to the index (staging area), so if you want to revert to its committed state you must pass HEAD explicitely as a parameter.
Of course this only proves that git does things very differently when file names are present on the command line…
However, after learning git for about one or two months, it does not look as horrendous as people say. It’s certainly possible to use it despite the little annoyances, and it usually prints useful messages on the screen while it operates.
Currently I’m a little annoyed with git add -A, git commit -a, git stash -u…
If only we had git add -A, git commit -A, and git stash -A plus an easier to use git reset… I think it should be separated in two commands: one to undo git add and other to move HEAD.
Just wanted to vent:
Git again fucked up my local changes when I did a pull.
Git is so stupid compared to TFS wheneven I try to pull changes from teh server it can’t just download the unchanged files and leave the changed ones alone. I had to stash my local changes, then pull server changes, then un-stash my local changes and retarded git couldn’t unstash my local changes (dunno why, it didn’t say, but I guess it’s because git is the most retarded source control out there).
.
To the morons who wrote it – you should learn from Microsoft and TFS – TFS is the best!
In my experience whenever you have problem with git, it is at chairkeyboard relation. I am absolutely sure that you don’t know what are you talking about, so unless you have any argument to confirm that you did everything right and git “fucked it”, please go use something more close to your intelectual capacity. Thank you very much!
If a product is hard to use, is that a “chairkeyboard relation”, or a problem with the product?
You have missed the point of this article, which is about the poor “UI” design of git that leads to these muddles. You may well wear your underpants over your spangly tights but if that’s really what it takes to use git reliably then most of us would say it’s not fit for purpose – because most of us don’t believe version control is that difficult. Simply insulting people doesn’t make git a better tool and, given that James seems to be happy with TFS, should give pause for thought.
While technically correct, it seems like there ought to be a better way of addressing people with this kind of problem. Everyone starts out ignorant of the technical details.
In my experience, usually the best way to approach this involves asking for:
(a) What specifically did you do (exact steps)
(b) What did you expect to happen
(c) What did you see instead (exact error messages).
People will usually range from too impatient to deal to those that are interested and capable. Many times when a person follows these steps they will figure out how to make it work. Sometimes they will have trouble finding relevant documentation – that can be a good opportunity to point them at the documentation you find relevant (and hopefully they see it the same way). Sometimes they will have found an actual bug (like if the code crashes or whatever), and if that’s the case they need to be treated with respect.
Unfortunately, it’s all too easy to think you’ve found a flaw when you have not. But by asking for a small amount of effort from people you can weed out most of those who aren’t worth your time.
There might be a set of 9+ commands to make git reliable; but, there’s a single click in SVN. It might be an egit problem and it might be a stash app problem; but its not a chairkeyboard problem. For sure, what works every time with one click in SVN (and CVS before it etc) had a high probability of failing with git. – off to manually resolve even more files git failed to commit.
I use both git and TFS every working day and I have managed to get myself in bad muddles with both. However, in normal working practice I find git enormously more comfortable and secure feeling. The ability to stay under version control when I am working offline is essential, similarly private branches, and the freedom to manage my branches without managing a horrendous pile of nested folders. If you have to use git, may I suggest getting holding of SmartGitHg (or Atlassian Sourcetree), which are excellent tools and make git safer and more manageable.
James, I suggest you always `git commit`, not `git stash`, before pulling, merging, rebasing, or whatever. That (a) forces git to merge the changes in as part of `git pull`, which makes `git rebase –abort` available; (b) gives you an exact commit to return to if you find things get horribly borked, so you know your changes are safe.
Your specific feature suggestion, downloading unchanged files and leaving the changed ones alone, is not workable, as it would silently drop upstream code on the floor. That could well lead to the project being uncompilable! It would also be a nightmare when you came to git push again, as you’d be reverting parts of other people’s work.
I do hate also this stuff, since it doesnt provide download resuming like cvs does !
Pingback: The Guy Who Made Your Android Phone Possible Responds To Nasty Tweets About Him | Construction
Pingback: The Guy Who Made Your Android Phone Possible Responds To Nasty Tweets About Him | Digital Wealth
Great post. Most use git in a source control pattern where changes are branches and must be approved. This is great for two scenarios: 1. mature code base with high risk aversion. 2. Junior programming teams where most do not comprehend the whole product. The main problem with this approach is the merge conflicts. Way, way, way, way, way worse than source control usage patterns common with CVS/SVN. In those, you merge at least daily so must keep the entire product in sync. Another problem with the way git is used is many (all of both medium-sized projects I’ve worked) projects allow specific persons an advantaged seat where they can merge as is convenient to them, but everyone else has to manually resolve the junk they did. Maybe its human nature; but in the typical SVN pattern, the first merge wins; so, good developers constantly keep their code in sync with the product. In git, it quickly goes to …
BTW, ever notice how git takes like 5 commands to do something which is two right-clicks in svn. No matter what you think of how people use git/svn, the fact of usability is there. What is even more strange is its perfectly possible to make lots of branches and do code reviews on those with svn – looks more like the primary goal for git users was to be able to stash/local commit. That is the only differentiating feature as far as capabilities which I have observed. Outside of that, everything you can do with svn you can do with git, and vice versa. Svn is just 10x easier and less error prone.
Do have to give credit to egit, Eclipse plugin for git. I used it before enduring lots of gaps; but, on this project its quite decent. I almost never have to shell out. (had to for merge to do a “git commit -a” to make git take the changes.) Its a great plugin and makes using git/stash tolerable.
The local commits are one of the major reasons why I prefer Mercurial over SVN. Also branching has lower overhead. And you can commit before you merge, so you first secure the work you did, then you integrate it.
OK, read through some of the posts. FYI, svn merge intra-file is very good. Git sucked. Perforce sucks. MKS probably sucks worse. ClearCase – been years since I used it but it sucked in several places. Used several others. So far, SVN is the cleanest. Of course, have someone with a brain deciding the branch and release strategy is far more important. I actually think git merge might have improved some since 6 months ago when I used it alot. Not sure but latest project I’m seeing less mess to manually clean up after git.
If you want a maintainer then just have all commits reviewed before being accepted into the head/trunk. No matter what source control, you can branch to your heart’s content. Just like people do with git.
Some things you should NOT do with GIT which are common with SVN.
#1. commit+pull on a whole tree. While this works sometimes, when we are on this project with different timezones then silently many files do not get picked up. Sure, you might should notice it in the list; but with SVN this just always works. In contrast, with GIT you had better commit -m “” exact-path-to-file for every file. Don’t just “commit” at top of node with egit nor even try git -am.
#2. Don’t do lots of pulls. If you come from a distributed team development background, then you are used to very, very often pulling the latest. This is BAD with GIT. Apparently the git tools are like MKS and determine diff based on timestamp. laughable if not so true. I never had this problem with SVN and think they might do binary compare. You’ll end up needing BeyondCompare or another binary folder tree comparison tool if you use GIT.
Long story short, in GIT you checkout/pull ONCE, make all your changes. Then try to commit+push everything at which time you do lots of merge conflicts resolution. With GIT you cannot sync frequently or things stop working. (assuming you are branched and have a fairly complex branching relationship and have lots of people changing lots of files).
If anyone is reading this, please don’t follow this advice. Heuristic: follow the practices of people who have good experiences, not those who have bad experiences. Frequently pulling the latest is only correct in one particular workflow, where there is a single, central master copy. Also note that in git you should be fetching not pulling.
In Mercurial you normally *merge* frequently and explicitly. It works pretty well. A canonical upstream is not needed for that, just sane people who do not rewrite history.
I agree on fetching: git pull is essentially a fetch+merge and as such quite dangerous if you do not commit beforehand.
In summary, with GIT you do LOTS of manual merges for any normal-sized project where you have lots of people working on the same files. So, to use GIT like is done in Linux, you need a MAINTAINER. Only he or she really changes the files he or she owns. Changes are suggestions to him or her. That’s GIT in a nutshell. Worth noting that the two projects where I used it quickly devolved into one or more “Leads” who would delay reviewing the changes from the rest of the team while he/she refactored the underlying code base, and then expect the rest of the team to sort it all out manually. That is common and repeatedly occurs on GIT projects. It never occurs on SVN projects because, with SVN, if you want to refactor the hell out of the source base then you do it all one late night after clearing that with everyone else or you do it piecemeal after clearing it all with everyone else. Not saying GIT couldn’t be used equanimously; but, definitely tends towards creating constant merge messes which must be manually cleaned up. Bottom line: GIT is a REAL TIME WASTER. You can add at least 20% additional time to the development effort if you choose GIT instead of SVN. At least. Honestly, I think its more like 40% because with GIT you need tons of meetings to figure out what in the heck is going on whereas with SVN the small changes are palatable and, therefore, somewhat self documenting. With SVN, if you make a change affecting others then they see it soon and can understand it better. With GIT, you wait around until a Code Review event, and, by the time that occurs, then the entire code has moved on and manual merge is almost guaranteed. (well, 20% of the time at least).
Ok, let’s blame the tools for our own failures. Because if we were responsible for getting something useful done we’d be doing that instead.
Seriously, if you like SVN that’s great. if you like Mercurial, that’s great. If you like Git, that’s great. But maybe also take a look at what you are accomplishing and how you deal with other people, also.
Put differently: in a few cases changing the tool will actually help. But if you are frustrated with wasted time then you need to seriously think about doing more arguing about what tool other people should use.
@Raul Miller: Keep in mind that having to do more than changing the tool does not mean that the tool is not partially responsible for bad habits which evolved.
A good tool makes it easier to do the right thing than to do the wrong thing. And while the the obligatory branch-naming of git is pretty good at making people use branches, it is pretty bad at keeping a code-base in a consistent shape (I‘ve seen quite a few year-old branches slowly rotting away because no one merges them)..
Sturgeon’s law is probably relevant here.
correction: “about doing more than arguing about what tool other people should use” …
*that* I agree with ☺
Pingback: Git | Rauhe Sitten
Git is cool! If you don’t like it, just use your outdated svn or whatever, maybe cvs))
That was what I found too. “Git is cool”. Just use it. “Its cool”. Pretty much sums it up. Two features make it a choice for special cases; but, those are really edge conditions these days where everyone has Internet every time and where setting up a branch in your favorite SCS is easy everywhere now.
In contrast, as chronicled in this page, GIT will add 10% to 40% project cost versus using SVN. But, I’m sure most GIT fans don’t want to talk about reality.
Just did a git merge on two branches. Stash (git) said each was in conflict. In one, in a class a _different_ constant had been defined by each. Git could not auto-merge that! In another, the imports changed. Git could not automerge that! Would be nice if git know something about Java; but at least it should be able to automerge non-conflicting changes. IDK what tool git uses for merge. I know I worked at one huge co that used Perforce and its merge was bad. SVN has been good IME. Why use a tool if you git to do it all manually!!! “Git it”
Why even write code if you do it all manually? All that finger motion – it’s just so… exhausting? All that thinking! How horrible. Maybe someone else should do it?
Exactly! Last thing you need is a manual SCS! One more flaw of GIT while we are talking about GIT warts…. its “local repos” are just copies of stuff in your working folder. I know, many SCS have this problem. Heck, the project.pj files from MKS break Android compiles; but, since GIT is THE LATEST AND GREATEST, couldn’t they do this right?
BTW, GIT’s salient feature is support for code reviews. Each change is a branch. This allows one to hire unskilled high school, offshore, and other unskilled people and give them one single task. Experience will teach you that the time to code review and teach them to program is greater than the time to just hire good people. But GIT would be great for a college, and that’s effectively what most large corps are when it comes to trying to use unskilled labor to do skilled work.
A few more things which don’t work in git merge and cause manual work:
1. comments. (really, not kidding, you’ll have to manually merge if someone adds a comment (// stuff) to a file in another branch
2. net adds. Yep, when you follow the steps below as listed by stash (git site) then you’ll find the net added file is not pulled. Ridiculous bug in git (or else stash’s directions. And if a git dedicated site can’t even figure out how to make git work…).
3. multiple other problems. Its tedious to list because clearly the author of git did NOT bother to learn from the others who have written SCS in the past. Git is absolutely a way to waste another 10 to 30 minutes for each bug/feature point. Sometimes can be even more time.
(The reason I’m chronicling here is this pattern of people with 0-5 years experience jumping on fad frameworks is a waste of human productivity. For us to take the next great leap forward as a species, we must learn to “Build on the Work of Others”. Not continually doom ourselves to make the same mistakes. At the very least, decisions need to be made with a list of Pros and Cons; not based on what someone hears at Google IO or whatever latest conference.)
Stash steps (works sometimes :-) (mostly from memory)
git fetch origin ORIGIN_BRANCH_LABEL
git checkout FP_BRANCH
git merge FETCH_HEAD
(stash omits but here you make changes and must do “git add fpath” for each file. woohoo, so user freindly, NOT!)
git commit
git push origin HEAD
(now, sometimes you’ll have various problems since this won’t work. MOST git users end up deleting everything, doing a new clone, and redoing there changes. Watch them. This is the type of sgit people are doing with git. But, you can get things working with some git fetch and/or git pull – at least in the case found.)
Huh. This thread has always been a rich source of bullshit, but recently it has crossed straight into tinfoil-hat-land. I look forward to the first report of how someone got rashes from using git.
Indeed, it’s all a bit over-excited.
@tisza: You can’t expect the positive sides of git adoption to show up in a thread which is the first google hit for “I hate git”.
On the other hand, git adoption is strong enough that the dark sides of having a mostly implementation motivated user interface with quite a few awkward workflows show up more and more. And these are very likely to show up here.
So you should not be so fast to insult those who made negative experiences with git. I also contribute to a project where git costs quite some time again and again because the necessary actions for what we need are needlessly complicated and require googling everytime. This wastes quite a few resources (several hours per year for a team of ~6 people).
Was git an overall win over SVN? I think yes. We are no longer dependent on a single server. Due to having a transparent bridge to Mercurial we can also reintegrate anonymous development into our main repositories with ease. That’s a big conceptual win. That we do most things over github is a big conceptual drawback, though: We always have to ensure that we regularly pull all history from all clones, so we don’t lose development when a user decides to delete the github account.
I don’t think @tisza was ‘so quick to insult’. He was responding to an incoherent post that lowered the tone of discussion of what has been, by and large, a well-considered discussion. I am genuinely interested in the problems people have with git, as I am introducing it in my workplace. So I am very grateful when people take the time to explain the issues that they have had with git.
However in your post you allude to “the necessary actions for what we need are needlessly complicated and require googling everytime”. That doesn’t help me understand the issues that you’ve encountered or how they might apply to my own workplace.
You continue tantalisingly: “We always have to ensure that we regularly pull all history from all clones, so we don’t lose development when a user decides to delete the github account.” This is about github rather than git, I suppose, but how is it possible for users to delete github accounts?! That sounds like your project is set up wrongly but I would be interested to know more.
@sfkleach, GitHub’s authorization control is extremely poor. While users are not able to delete repositories if the configuration is sane, there is no way to limit force push access; if someone has it for some branches (which is usually needed when people work together, e.g. to rebase a feature branch shared between two coworkers), they have it for everything, and if they accidentally rebase master, it is not even logged, nor is there any way to restore the lost commits, unless someone has them locally. It is quite easy to lose work that way.
Not really a problem with git, of course, and supposedly GitHub Enterprise has more granular access control, so leaving this out of GitHub was probably some sort of business decision.
It’s a fair comment that git doesn’t build in authorisation and arguably a weakness. But I would be inclined to say this an issue with GitHub rather than git (and the reasonably well-know workaround for GitHub is to use forks). I haven’t personally configured gitolite but it seems to include branch permissions as a key feature.
Your point about rebase being a good way to screw up is valid regardless of whether it’s one person or several people. And there are some very good ways to get lost in git. I recently got in a muddle doing a demo by doing a ‘revert’ rather than ‘reset’ – which was a classic terminology blunder. I used the word ‘revert’ while speaking and the rest was … unimpressive. It took me a while to untangle myself.
@arnebab, this thread started with some reasonable (if overplayed) usability concerns, then turned into “I did this stupid thing and git didn’t stop me!” (it is of course a valid philosophical stance to prefer tools which have a dumbed-down instruction set and do not allow anything nonstandard because there is no way to tell whether it is stupid, but if you nevertheless choose a tool with a completely opposite philosophy, no sense in blaming anything but yourself), and finally descended into conspiracy theory realm. Git not being able to commit files which have been edited from a different time zone, or merge back a branch if a comment was added to the same file on master, SVN being better at merging renames, etc… Had Max not been the only one commenting here lately, I would have probably assumed that he is mocking the blog author by making ridiculously over the top claims.
@sfkleach: whether to include the kitchen sink or concentrate on version control and let you deal with other tasks using tools specialized for those is again a philosophical issue (personally I would prefer the latter). gitosis, gitolite, gitorious etc are easy to set up if you need access control.
Rebase in git is quite safe: you can use the reflog to restore the old state if you mess up. The problem with GitHub is that it doesn’t expose the reflog but makes it easy to mess up (and hard to even just verify whether you messed up). But that’s a business/legal decision, as I said, not a technical one.
(git reset, on the other hand, is a major usability blunder.)
One more. If you move a file to another package then it will show in git history but egit compare shows them as two totally separate files. Not sure if you blame the poor, out-dated compare support on egit or on git itself.
I’m pretty sure this is a git bug. Same sort of crap happens with Android Studio. Rename stuff loses history. That’s crap which used to be in other SCS’s like 15-20 years ago. Hope AS/git get fixed.
Yet another! egit says “failed to push due to funny remote ref”.
Well, that’s odd since the remote ref listed as an OLD branch and NOT the one just checkout’ed.
Well, its not even an egit bug, its git itself (using the stuff downloaded from github.com for Windows)
Here’s the command line example. Git, “Not only user-hostile, but also buggy”.
136 git checkout EPIC_BLAHBLAH
137 git pull
138 clear
139 git status
140 git push
141 git status
142 git push origin EPIC_BLAHBLAH
Ok, so, someone will say “you should have have done a “git pull”. Why not? Details:
$ git status
On branch EPIC_BLAHBLAH
Your branch is ahead of ‘origin/EPIC_BLAHBLAH’ by 1 commit.
(use “git push” to publish your local commits)
$ git push
! [rejected] HEAD -> TAG-bugnumber (non-fast-forward)
error: failed to push some refs to ‘https://accutname@stash.r.company.com/scm/stuffer-android.git’
$ git status
On branch EPIC_BLAHBLAH
Your branch is ahead of ‘origin/EPIC_BLAHBLAH’ by 1 commit.
(use “git push” to publish your local commits)
EPIC_BLAHBLAH
So, YES, you can MAKE Git work. But, WHY? Why not just use svn and save yourself headache after headache after headache?
Sorry, comment was filtered due to gt/lt.
$ git push
! [rejected] HEAD -> TAG-bugnumber (non-fast-forward)
error: failed to push some refs to ‘https://accutname@stash.r.company.com/scm/stuffer-android.git’
— comment: why is Git pushing to another branch? I checked out from the one I want. It even told me “(use “git push” to publish your local commits)”? Someone will say “You should not ‘git pull’.” Why not?
TAG-bugnumber is an old branch. The same steps used worked for a month or so until last week. The only thing I know changed is a bunch of remote branches are being deleted as part of cleanup (more make-work you get to do if you use Git).
You haven’t really given enough information here to isolate the problem. But, at a guess, you are thinking that “push” pushes a single branch (the current one) but have not configured push.default=simple and are using a version of git earlier than 2.0.
By default, git push tries to push everything in all branches up to the remote repository. But rather than trying to explain how many developers use git, I’d recommend just setting push.default (globally). This is especially important for “corporate use” where a number of people are pushing to some repository which is being maintained by an ops person or some external company, instead of a developer.
Note that this also means being willing to have someone spend 10 minutes with each developer if they are using a version of git older than 2.0, to make sure they have a reasonable push.default (and/or have read the relevant git.config documentation).
Thanks rademi. That may indeed have been it.
I am a user of both GIT and SVN. I have also implemented a few content and data versioning systems myself (although quite basic systems). This is a wonderful critique and parallels my experience with GIT/SVN perfectly. You have missed the most important negative aspect of git however which is its “promoters” or fundamentalists. Those who believe that git is the only viable choice for a VCS. These are people who push git unconditionally over SVN with total disregard towards that facts of a given situation and without consideration of the fact that GIT and SVN follow different paradigms.
GIT is great for what it was designed for, a massive project with thousands upon thousands of random contributors. Of course it makes sense to be distributed here, provide more control (communication and coordination is impossible one such scales) and so on. The masses of incomplete work alone would pose a severe problem. For me this is counter productive because I need to see what people are actually doing and steer them down the right path where necessary and that will lead into a point later.
GIT is very powerful indeed and therein lies the problem. It is too powerful. I receive little benefit from this in commercial work and it only becomes a burden. Developers losing hours tangled in GIT is a common phenomena and it has even happened to be a few times when attempting something that should be simple. These are not always stupid people but people who just want to program and not spend an hour battling with GIT. In SVN I have never seen this happen even after thousands of commits.
GIT is a risk as it lets developers do things that frankly, they really never need to be doing. Where the tables are turned, it is simpler for me to establish constraints when using SVN by establishing procedures for developers and SVN wins here because there are simple, easy to understand things such as “don’t touch the release branch” that anyone can understand. Restricting with permissions is not even necessary. As a mentioned before on committing partial work, yes, you can commit partial work with GIT but I have no need for developers to not commit partially complete work at then end of the day or when they want to include others in their efforts. Some of weaknesses SVN has over GIT can be compensated for by power users with a few basic helper scripts. If I need a backup, this is not a problem, I can’t stress how easy it is to backup SVN especially in a corporate environment where we already have backup solutions in place for everything else anyway. I find it quite bizarre how often people make this argument for git. You can’t seriously propose this in place of a proper backup solution rather than a bi-product. SVN is not perfect but it has not given me any significant problems.
Many of the problems that it “solves” are better simply avoided or not relevant in my situation. This isn’t the situation for everyone. There are situations where git makes sense but the point is, it does not make sense in every situation.
This is really an issue of scale that drives me up the wall with some people (young and old). I am very tired of hearing hotwords such as “workflows”, “continuous integration”, etc from people with little real experience or rather theoretical understanding rather than practical understanding. I have real problems and none of these solutions help. The worst of it is receiving these proposals or insistent imperatives that I must use GIT when I have no problems at all. These people are becoming the problem themselves. They have ruined GIT for me. I now block it out, i simply do not want to hear about it from others. The truth is that GIT can’t always pay for its self. It’s not a guaranteed investment.
> Git is cool! If you don’t like it, just use your outdated svn or whatever, maybe cvs))
I’m sorry, it’s not that I don’t like it, it’s that I don’t need it.
Check out https://github.com/landobyte/glo Its a git addon we built and it works well.
i’m totally agree with this writing.
still looking simple SVN/GIT.
just need clean easy interface for managing my PHP code.
any suggestions app?
cheers
Yes, try SmartGit/Hg from Svento. It’s a superb tool that makes using git a pleasure. Please don’t stick with SVN because of the negative comments you have heard. Yes, git’s has an intimidating command-line interface – but there are plenty of GUI tools that give full access to gits power but presented more elegantly. And SmartGit/Hg is my favourite. (I have nothing to do with Svento – I am just a pleased customer.)
ooooops! Syntevo not Svento – a bit of brain freeze there!!! http://www.syntevo.com/smartgit/
Or you can try SourceTree from Atlassian is you are on Windows or Mac – also a fantastic tool.
For a simpler cmd line interface try: https://github.com/landobyte/glo, it implements a simple version of the git-flow paradigm.
I agree. Sourcetree is pretty nice too – and unlike SmartGit/Hg it’s free for commercial use as well.
Just use Mercurial (hg). It’s easy to use and powerful enough that Facebook is now ditching git for it: https://code.facebook.com/posts/218678814984400/scaling-mercurial-at-facebook/
It look easy than SVN. I think we need adaptation it.
I feel your pain! Didn’t know someone felt the same about some of those issues. I’m working with git and svn together and it took a while until I found a comfortable workflow.
—
Make some changes
git add [not to be confused with svn add]
git commit
git push
Your changes are still only halfway there. Now login to Github, find your commit, and issue a “pull request” so that someone downstream can merge it.
—
Granted, I have never used Github, I use Beanstalk, but this is my process:
1. Make some changes
2. stage all changes (i use git tower but you can easily do git add .)
3. git commit
4. git push origin master
My changes are ALL the way there. no need to do anything else. This is pretty much constant. Maybe Github is different.
By “halfway there” I mean, I they’re still only in your personal repo. You generally have to then make a pull request.
I should point out that since writing this blog post, Github’s workflow for making pull requests is smoother – you don’t need to “find your commit” anymore.
Github does not allow you to push changes into random people’s repositories without their consent. Shocking!
>Github does not allow you to push changes into random people’s repositories without their consent. Shocking!
Yep, sarcasm’s easy. Think harder though, and you’ll realise there are lots of alternative workflows that the designers of Git and Github could have used instead. The concept of proposing changes to something managed by someone else is not unique to source code – but the pull request model is a particularly clunky solution.
Handwaving about how everything could be done much better in some unspecified way (without even trying to understand the trade-offs involved) is even easier. Creating pull requests directly would be theoretically possible, certainly (gerrit works like that, for example), but – apart from being complicated to implement in pure git – leaves you with authorization problems. (If project A makes a pull request to project B, and project B requests improvements, then everyone who has the right to push changes to project A can do them. If you would create a pull request directly, it would be associated with your user, and there would be no way for others to collaborate.)
Ok, so first “implementation in pure git” is not a requirement, because I’m criticising Git itself, and its pull request model.
Second, you speak of pull requests between *projects*, but one of my gripes is that Git and Github treat individual contributors to a single project as if they were each running their own project. Sometimes that’s appropriate, but it also creates a lot of bureaucratic overhead.
I share your dismay with bureaucratic flaws.
Still, the woes of bureaucracy are not constrained to git.
In fact, I prefer to think of the issue you are describing – this “clunkiness” – as being an inherent property of bureaucracy. And, yes, git “reveals” this issue, and github – with its billing model and authentication issues – makes this issue even more obvious.
Or: the model you are implicitly advocating – where one person gets full control on checkout but no one has needs to review changes – has its own headaches. And when they arise, they are not pretty.
People aren’t perfect.
Unfortunately.
>the model you are implicitly advocating – where one person gets full control on checkout but no one has needs to review changes
There were other options available, say, commits automatically become some kind of personal branch in the main project repo, and the maintainer can pull from them when ready.
I’m not really implicitly advocating any particular solution.
> Ok, so first “implementation in pure git” is not a requirement, because I’m criticising Git itself, and
> its pull request model.
Git actually does not have a pull request model; pull requests are an abstraction layer built on top of git by GitHub to manage authorization for pushes. (Git itself does not concern itself with authorization at all, just provides hooks so another tool can deal with it.) GitHub chose an implementation which is completely simple: you use the normal git commands for remote repos, plus an external step for creating the pull request. (Again compare with gerrit, where you have to push to a weird pseudo-branch to create the local equivalent of a PR.)
But certainly criticism is a lot easier when there are no requirements.
> Second, you speak of pull requests between *projects*, but one of my gripes is that Git and
> Github treat individual contributors to a single project as if they were each running their own
> project. Sometimes that’s appropriate, but it also creates a lot of bureaucratic overhead.
That is completely untrue. A GitHub project can have multiple contributors who push to that project directly. You can use pull requests within different branches of the same project for code review (or just have everyone push directly to master, and not do code review at all, although sane projects tend to avoid that option). This is not exactly top secret information either; it’s right there at the beginning of the GitHub help page on pull requests (they call it the shared repository model).
Right, Github offers a choice between:
1) multiple trusted people can commit directly to the same repository, and potentially seriously break things (a single `git push –force` can wreak serious havoc)
2) everyone has to create a separate branch for every small chunk of development, rebase it to master, push to github, create a pull request, then rewind.
Github does the best it can to create usable workflows over the top of Git, but the underlying interface it works with is so ugly.
None of what you describe has anything to do with git’s interface whatsoever. GitHub in fact supports access levels so only certain people can force push to certain branches, they just made a business decision to restrict it to their enterprise product (as I noted a few comments earlier). And it is trivial to get the same restrictions in plain git via hook scripts (gitorious does that, for example).
Anyway, GitHub’s shared repo mode works fine in practice if you don’t have to deal with patches coming from outside a team. We used it for a smallish project with half a dozen people where everyone was new to git, and there was IIRC one force push accident in half a year which could mostly be repaired from local reflog.
as info-point: to date I witnessed two force-pushes which broke stuff for me. And stopped at least as many from people who thought that this would be a simple option to just cleanup stuff.
to make matters worse, github pull requests and git branches aren’t really a good fit.
Git requires creating a branch when you do local changes and want to push and pull locally (that just means using the basic features of git locally).
Github gives you the second layer of mutliple repos with pull-requests which replicates most of the functionality of simple branching – except if you want to have multiple pull-requests. But additionally per-commit code-review advertises rewriting history in the branches. Which is easy to do locally it git, but horror to do in published code.
This article is awesome. Firstly, because it is informative, and secondly, because it is magnificently misleading. Comparing svn and git is like comparing a swiss army knife to a *carpenter*. “But my knife has these five features, why is carpentry so hard?”
If your git team doesn’t do anything complex and YOU don’t want to do anything complex, you can just stick to pull, push, checkout (-b, god forbid), and merge. You want to move a commit from one branch to another then rebase your changes against master so your history looks really nice? You can cherry pick and rebase. Or you can do what svn teams do–copy and paste things to $%^&* notepad or use 4 extra commands in a 10 step process, as they proceed to build a chair with a swiss army knife. Which is completely possible.
If what you’re doing is “svn-simple”, you’ll find the surface area of git you have to know is ‘tiny’. But if you want to have X participants each with Y versions of the project and the ability to compose anything from any of them, you can do that too, it’s your call how to use the tool. My $.03.
>If your git team doesn’t do anything complex and YOU don’t want to do anything complex, you can just stick to pull, push, checkout (-b, god forbid), and merge.
In my experience, this is simply not true. Git doesn’t work like that. You can end up in complicated, messy situations very easily, and a simple set of commands won’t get you out of it.
Simple example from the other day.
1. I fork a friend’s project, add some commits, push to my Github repo, and send a pull request.
2. Friend looks at my changes, decides to implement them a better way, and does so. My pull request is ignored.
3. I now want to submit new changes, so my github master branch needs to be in the same state as his.
Very simple situation, and yet hard to resolve with only the basic commands.
That’s git checkout. In my opinion, you should just checkout his latest in your master. If you’re trying to turn all your changes into his head, instead just using his head, that’s not a simple example, it’s not even a good idea. Nevertheless, it wouldn’t be trivial in another VCS.
If you had work you wanted to keep, you could just merge and resolve conflicts with ‘theirs’.
Actually this IS a really simple situation, and I also found myself in that one.
The answer is obviously, if you use git, you must not work in master.
And by the way, the answer in incomplete: It misses the required force-push to github to recover the online repo.
But then, here’s an even easier example.
I have a local repository.
I clone it locally to do some hacking.
I push back and the repo errors out on me. Because I cannot push into a checked out branch (useless implementation details invading the user interface). And the advise is to use an intermediate bare repo. At that point I was left thinking “are you serious?” To just transfer changes locally you actually have to understand how the internals work?
Well, I’m obviously biased by Mercurial, where this just works.
Actually, when you try to to push in a checked-out branch in git, it patiently explains you why you why that might not be the best of ideas, and what to change if you want to do t nevertheless. That’s pretty good usability in my book.
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require ‘git reset –hard’ to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set ‘receive.denyCurrentBranch’ configuration variable to
remote: error: ‘ignore’ or ‘warn’ in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: ‘receive.denyCurrentBranch’ configuration variable to ‘refuse’.
To ../foo/
! [remote rejected] master -> master (branch is currently checked out)
Agreed – sometimes Git gives good output. I really wish it did this consistently. Sometimes it gives no output, sometimes it gives very cryptic output – and just occasionally, it gives enough information to point you in the right direction.
I disagree: This Wall-of-Text which nicely illustrates that in git implementation details dominate over the user interface. And the error message actually requires implementation knowledge to understand.
All this to work around the limitation that the git branching model is a bit too simplistic in that it does not allow multihead branches. For git the state of a branch is always unambigous and it is the user who has to work around the fact that in reality that’s not the case between clones. it nicely explains, though, why git users almost exclusively branch by branching and don’t use quick testing clones.
An example:
To create a quick, clean, local test environment, git requires you to:
– clone the local main repo to another directory, [mental task: think of a name]
– checkout a new branch there, [mental task: take a name you did not use before]
– do and test the changes. If they are good:
– push or pull the branch into the main repo,
– merge the branch into master in the main repo, and
– delete the branch in the main repo.
With Mercurial you cut out 2 of these 6 steps, of which 5 are pure versiontracking overhead:
– clone the local main repo to another directory.
– do and test the changes. If they are good:
– push or pull the changes into the main repo, and
– merge the changes.
And the error message clearly shows how implementation details dominate. It lists you all these complex options, but does not care at all about what the user needs at that moment: Pushing the changes back. “name your branch – and push it to merge it later” would have completely sufficed. Git could even do that automatically when you try to push into a remote checked out branch. You would still have to delete it afterwards, but at least it would be much less horrible: It would be a brief fix to the problem and would get the user into how everyone else works around the problem instead of wall-of-texting the user.
As icing of the cake, here’s the list of names for implementation details in that text – with potential answers from new users:
– /refs/heads/master ← huh? isn’t that just the master-branch? Not if you look at implementation details.
– non-bare ← what are non-bare repositories? Are there bare repositories? Why?
– index ← what’s that? (many people always use commit -a, because they find the staging behavior confusing)
– work tree ← do you mean my files? (though it actually is hard to find a good name for that)
– git reset -hard ← why hard? Is that special?
– HEAD ← what’s that? Why is it in uppercase? Is it the most important part of the message?
And then two paragraphs on changing configuration variables to make the behavior even more surprising.
This is a very long error message which essentially says that git makes many simple workflows needlessly complicated by putting implementation details before the user interface.
The biggest problem git has, over hg, is that more people use git, so more people are exposed to its quirks.
In contrast, hg has a smaller user base, and is designed for smaller projects (which is not necessarily a bad thing, but that does not make it automatically superior, either).
Consider, for example, what happens in hg when you have a few experimental coders introducing branches to conduct local experiments. This works great, except after a year or so of this you can wind up with thousands of useless experiment branches in your hg repository. And what then? This is simply a non-issue in git. It “just works”. But the “it just works” quip does not really give an uninformed user enough information to make an informed decision.
When you have useless leftover named branches in hg, then you just close them. The history why the changes were added is preserved, but they no longer obstruct work. And no, 10k branches is not a problem for hg (I tested that). Normally you will not have leftover branches, though, because most hg developers do not need to start hundreds of new branches for trivial tests. In hg that is unnecessary, because it can cope with multihead branches (which are normally merged quickly).
I don’t understand, though, why you claim that hg is designed for smaller projects. Both hg and git were started to replace bitkeeper for Linux kernel development. Also hg is the version tracking tool for Firefox, which can’t really be called small. hg and git take a different view of what a version tracking tool has to provide for such a project, but their scope is the same.
My guess is that you get this impression from the different main target user: git caters more to the maintainer (or more exactly: to Linus Torvalds), hg caters more to the regular developer. Interestingly, large projects have a much higher regular developer vs. maintainer ratio than the typical 1-3 persion free software projects.
You are comfortable reading through 10k of branch names? That is your idea of an easy to use interface which just works?
I must admit that I do not actually understand. But I guess whatever works well for you is really your call.
when did I say that you have to read through them. The git equivalent of a closed branch in Mercurial is an archive tag (as explained here: http://stackoverflow.com/questions/10242924/how-to-close-a-branch-without-removing-it-from-history-in-git ). That clobbers up the tag namespace in git (try browsing through the tags for freenet one day: https://github.com/freenet/fred-staging/ – now imagine adding more by archiving branches), which it does not do in Mercurial, because closed branches are by default hidden from view and only shown in the commits done on that branch (yes, there’s a commandline switch to show closed branches).
Also you can just as well use bookmarks in Mercurial, which are more similar to git branches than named branches, but without the single-head limitation of git branches. The bookmark itself adds a namespace when there’s a conflict, and when you push back into a repository, all bookmarks can be moved freely, because they are not part of the definition of the work tree.
Ok, being able to hide the branch by tagging and closing it does sound address my hypothesis about the UI. But that creates a new problem, which is branch name collision. When there are natural names for a project, you’ll get naming pressure. I’m not sure if that’s a big deal, though, on a large project since you can just use per-developer prefixes to work around that.
Still, looking further, I am still uncomfortable with the assertion that mecurial “just works” as an adequate summary. I’m seeing stuff about pushes failing because of multiple heads, diverged archives and so on.
Solvable? yes. But … “just works”?
Looking further, mercurial winds up being just as powerful as git in many respects. When you add extensions. Which are not designed to work together.
You are going to have issues. That’s just a fact of life.
And people are going to make choices which lead to further issues.
And eventually the crud builds up to the point where people need to just start ignoring such things and find other approaches. Or live with it. Whatever.
Mercurial *is* just as powerful as git – and in some aspects more powerful – but that isn’t the point. The core design choices in git make some simple to describe workflows cumbersome to use, and the degree of elitism I get to see from the git community (which is surely biased, because those are the people who go into online discussions) as well as the choice to make low-level commands part of the API for tools make it really hard to fix these problems.
Just works for example means, that when your push fails due to multiple heads, the user interface gives you concise and easy to understand how to resolve that. And most extensions work together very well – especially the shipped ones (which you really just activate).
But naturally “just works” is not a complete summary. It is only valid relatively when comparing Mercurial to the troubles git gives. And also when comparing it to every other version tracking tool I worked with or for which people told me about their experiences.
People might just find better ways to do version tracking in the future – or they might change the existing tools. For example changeset evolution is really awesome, but I expect that it will need a few more years to really become a viable choice for beginners: http://evolution.experimentalworks.net/doc/
Also, “7. unsafe”? I love when people demonize rebase. Going through all that trouble for someone with all that access would be like doing an svn dump, filter and restore to remove commits from people you don’t like.
i 1000% agree… I was source control admin at my last company for many years. moving from a corporate SC product to git has been a really headache and nightmare for me. the company I am at currently is *not* distributed but ‘git is cool’ so we use it. granted, I have not taken as much time as apparently is necessary to ‘learn’ git but something as simple as ‘get latest’ on a single file is so unnecessarily difficult it requires an hour of googling and ‘messing’ with it for me to even figure it out. ridiculous.
You probably want to be using http://marklodato.github.io/visual-git-guide/index-en.html and maybe read the basic usage part.
Also, google used to be great, but that was before people, politics, spam and money pretty much trashed it. Oh well… It’s still pretty nice some of the time, but you need to expect it to fail some of the time.
Git is so weird… I have my own criticism of it from a different perspective, mostly after trying to use submodules and subtrees (almost impossible). Check it out here: http://rehalcon.blogspot.com/2014/09/i-dont-git-it.html
I have been using GIT at a new company for a month or so now and I absolutely loathe it. In computer games, if your menu system or interface isn’t understood by all your players, the fault is always yours, not theirs. Make a better interface, don’t blame the users. People who defend GIT don’t seem to understand this. GIT (even when using SourceTree) has an absolutely woeful interface, and I can’t think of a single way to justify it. The package is undeniably powerful, but I don’t care, because the usage model, especially if you’re new to it, is revolting. There are five or six developers here, all of whom have been using it for various periods of time – and none of them trust it. They all stick with the few commands they’re reasonably confident with and pray to god they never need to use any other aspect. I can always tell when somebody is merging a branch or doing anything with GIT or SourceTree by the fearful expression on their face and the way they tentatively tap at the keyboard or mouse buttons as if convinced they’re about to set off a nuke somewhere in the building. I was in prison once (for a crime I didn’t commit) and I was repeatedly raped by a man with a banjo and no teeth. GIT is much worse than that. People suggest if you learn to use it, it becomes better – but seriously – why should I bother? It’s meant to be a tool – I’m busy enough with coding thanks very much, I shouldn’t have to spend a year learning how to use the tools that are meant to assist with coding. I drive a motorbike. Sometimes I need to use a screwdriver in order to fix my motorbike. I don’t want to have to learn Kung Fu to black belt level in order to learn how to use the screwdriver. It takes time away from my biking! I imagine people who have spent ages learning how to use git will end up with a kind of Stockholm syndrome in defending the interface. For anybody else who just wants a version control system it’s maddening. The only good thing about it is that ‘git’ in British slang means ‘absolute bastard’. Was this intentional? Great article by the way.
What prison issues banjos?
I’m glad you asked that question Raul. UK prisons allow stringed instruments – as long as they have nylon strings. US prisons, for instance Parchman in Mississippi, have allowed guitars and banjos for decades, usually for better behaved murderers. Prisons don’t ‘issue’ banjos of course, although in the deep south they are a pre-requisite for being in prison in the first place. It also helps if your mother is also your sister and your aunt.
It is one thing to point out something where GIT fails or something, however most of comments in this thread are just people whining about how GIT is hard to use, has ugly interface etc…
Well, I believe that if you are programmer, console should be more natural place for you to be than GUI. If it is not, than programming is just not for you. I can’t understand how using console can be hard for programmer, unless one is complete n00b.
>I can’t understand how using console can be hard for programmer, unless one is complete n00b.
Heh. If you read the blog post, and read all the comments, and you *still* can’t understand how Git command line interface is hard to use…well, congratulations.
Well, I’m watching this thread probably about a year, and I still don’t see any decent argument other than “This is hard for me”. I mean if GIT is one’s biggest problem in being programmer, then congratulations as well…
This article has always been just one biased pile of whining comments.
> other than “this is hard for me”
So, what should people say when the UI is horrid?
> I believe that if you are programmer, console should be more natural place for you
Your argumentation about the command line is completely beside the point: Git is HARDEST when you use the command line. If you access it via graphical tools, those tools try to take away most of the pain and restrict you as much as needed to avoid most of the pitfalls of git.
> if GIT is one’s biggest problem in being programmer
No one said that git is the biggest problem. First of all, git is an UNNECESSARY problem which makes already challenging tasks harder.
I shudder when I only think of the mess in which it left the history of one of the projects I contribute to – roughly 20-30 branches in the main repo, some of them merged into production, some not, some of them still experimental, some ready to be merged (but not marked as such – this information is only contained in sometimes existing pull-requests) and quite a few further branches only available on some developers repository where they slowly bitrot away and might disappear at whim. Yes, you can say “you just need to have more discipline”, but that’s just one of the UNNECESSARY complications git adds to a task.
I’m sorry Tomas, but what you believe isn’t really relevant. A ‘real’ coder only uses the console? Doubtful. Git is even less pleasant with the console, as has been covered in the article. I’ll wager I was coding before you were born, on 8 bit machines that were purely ‘console’. Doesn’t mean I have to remain in the past. You wrote “I can’t understand how using console can be hard for programmers, unless one is complete n00b” – this is an argument from personal failure. Your failure to imagine something doesn’t make it untrue, or otherwise. As it happens I still use the console all the time, from powerful command line utilities like ImageMagick to the simpler stuff from Sony and Nintendo, which are part of their SDKs. The console still has its place – but I prefer to code in Visual Studio, Xcode, Xamarin etc, ta very much, just like I buy my lunch from Tescos instead of wandering into the forest with a rock and a pointy stick. You are also trying to distinguish between arguments ‘where git fails’ and ‘whining about how GIT is hard to use’. You fail to understand that a bad interface is a failure. If I made an AI program that could answer all medical questions, but made the interface using ancient Latin encoded in a shifting form of BCD on punch cards that themselves had to be blessed by the pope before use it might be fair to say the overall package was a bit of a failure. GIT’s interface and concepts are part of GIT, even more firmly embedded in it’s DNA than the spurious example I listed above. It’s also worth asking what you think Version Control software is for, if you don’t think hard-to-use is an issue. In the real world, version control is used by coders, artists, designers, sound engineers, project managers all contributing to the same project. The user interface isn’t a minor aspect of the package, it’s the key aspect.
That’s much more stringent argumentation than mine :)
What I’d like to add: Version Control is about making a task easy. It should alleviate fears of losing work to allow for quick experimentation, simplify cooperation and stay out of the way as much as possible.
Well Robin, thanks for answer. I would like to point out that you surely didn’t code before I was born and be sure I have my own 8bit experience as well.
That said…
Reason why I’m even arguing here is that “git interface” is not GIT’s interface considering that that it follows same POSIX standards as any other well written UNIX CLI software so when someone is saying that GIT interface sucks it is same as he’s saying that POSIX sucks.
It is true that some people are having problem with GIT, however that doesn’t mean GIT interface is bad, it just means one should seek for other solution because GIT works good and has great interface for surprisingly high number of people, so if GIT is “too hard”, maybe one should use something more easy and admit to oneself that having problem with git doesn’t mean other people have the same problem.
@arnebab You need to understand that like many other GPL software, git is made in order to help his creator to do the job he couldn’t do before. If that mission is completed, then git wins. Having possibility to use git by other people is just one more feature of it. So, one that doesn’t like it, doesn’t need to use it and that’s about it. If you don’t have same requirements as creator, git shouldn’t be used.
Additionaly, I don’t think git is ever meant to be used via GUI and this actually complicates stuff IMHO.
For the end, I seriously doubt that git would ever become that popular if it is really HARD to use. I find it awesome, as many other people and I couldn’t care less if someone finds it hard. HARD is personal feeling, not general fact.
Don’t get me wrong. I don’t think it is for everybody. I’m just saying that “it is hard” is invalid argument.
Its not about console vs gui. I use Mercurial and SVN from both. I also use GIT from both. GIT still stinks.
Tomas – it’s nice to meet another old 8-bit coder :-). My comment was speculative, based on your position on what a ‘real’ programmer is. No such entity exists. I can’t comment on the POSIX side of things, as I don’t know anything about that. All I can go on is that in my experience, and clearly that of many other people git is a) complex and opaque in use, in terms of terminology and use flow, irrespective of interface and b) has a horrible interface and c) is powerful but d) because of the way the user is supposed to use the software being so badly thought out, utterly crippled for a great many people for whom a simple usage model is an important aspect of source control. I would argue that in *all* cases, a simple usage and comprehension model is what should be expected from any kind of Version Control. Do you think people will be using GIT, like it is now, in thirty years? You also suggest that if one finds git ‘too hard’ ( your words – a deliberate misrepresentation/simplification of the problems people have mentioned with GIT on this site ) one should use something else. Well that isn’t always an option – you turn up at a company and you use what they have in place. That’s still irrelevant to the main point. The Model T Ford is a bad car with terrible brakes. I can use another car. We can all use other cars. The Model T Ford is still shit. The problem isn’t that it’s ‘too hard’, it’s that it’s ‘viciously unpleasant and badly/foolishly thought out’. GIT that is. The Model T is just very outdated. Just because a system is complex or powerful, that’s no reason for the way in to be barred by opaque terminology, a horrible, inconsistent interface and too many steps for simple (i.e. most frequently used) operations. You suggest that people are merely ‘whining’ about a system you personally think is fabulous. Are we to understand that anybody who disagrees with your love of this system is just whining? That seems a little reductionist. We may as well say that you’re merely whining that people aren’t as impressed with GIT as you are. I’m not sure that either position advances the argument. However I think we may agree on more things than you realise.
Robin, I believe that we are talking about different things. Some people like GIT, some people don’t like it and that’s it, however just saying that git is ugly implies that you think every CLI command is ugly if it has POSIX style syntax :)
Take “ls” for example. It was written in 1971. and it still does great job.
I don’t want to open some GUI just to be able to do few simple commands to organize my code when I can make it in few keystrokes. I can script it, i can do whatever I want and it is great as it is.
Who doesn’t like it, doesn’t need to like it, but to say it is UGLY is just personal taste, nothing else.
Git does have many weird things, however 80% of comments are either “it is hard” or “it is ugly” which in my opinion is not measure of usability.
I can see your point, and it’s not unreasonable on the surface. However usability is not an abstract notion. There are real world metrics that can be applied to define how useable a particular interface is. GIT would fail spectacularly on these. That’s not a matter of personal taste, but a researched and well understood field. Nobody is discussing the POSIX model, which I think GIT fails to adhere to – but the fact that the whole thing is non-intuitive. Do all the commands work the same way? No. Please see the original blog post. Does all the terminology fit other VC software or even plain English, the most powerful communication model we have ever created? No. Does all the terminology fit GITs own internal model? No. Or rather, I have no idea. Does it make your code safe to use GIT without full knowledge of how every aspect of the software works? No. Not even close. I’m very glad that you prefer to use a command line for some basic GIT usage – it’s great that you’re familiar with the software and can use it in that way. However I still hate it, and even if in ten years I’m completely familiar with GIT (and am happy with the terrible life choices that got me to that state) I will still remember just how non-intuitive the software is to use, especially at first blush. I don’t use GIT from home, I’m forced to use it in a real world office environment. Nobody here likes it – only one person – the bespectacled autistic bloke who sits in corner, cradling his stapler, can even confidently use the basics. It’s not just ‘ugly’ – it’s objectively an overly complex model, both in terms of use and design. Your liking it is at best anecdotal evidence it its defence. I could be accused of the same thing of course. However I design user interfaces for a living and would be unhappy to have created something like GIT – I could checklist the reasons if I had time. ‘It is hard’ and ‘it is ugly’ – whilst slightly reductionist and unfair summaries of the criticisms on this site, are in fact very real measures of usability. Software is a tool, as are computers. GIT is a powerful tool, like a hammer with 19 hidden functions. However it is hard to use this tool because it is like a hammer with 19 extra buttons, and there are several knife blades sticking out of the handle. Your facility with GIT is to be admired :-)
Very nice blog post that sums up the biggest shortcomings and misgivings of git.
I might add that many of the described problems plague the GNU OSS world on a much wider scale; users are much too often implicitly assumed to know how a piece of software works, and having well-designed, separate user interface is quite rare indeed.
A simple example is iptables: I haven’t yet heard anyone adequately explain why an end-user would need to know about different chains. All they care for a packet is the interface, source and destination. I understand chains are how iptables internally works, but exposing this to the end-user serves no purpose.
You are correct.
In fact, there is no need for an end user to know anything at all. In fact, end users do not need computers at all.
End users need good nutrition, a safe place to sleep at night and adequate water, and they need exercise. Computers are simply not nutritious. This is why you should go out and buy a television set and watch it rather than waste your time reading.
All sarcasm aside, the fact is there’s simply no choice that anyone can make which satisfies everyone. People like to whine and complain, and the more popular something or someone is, the more criticism it attracts. Some of that is valid, but most of it will not be.
Sturgeon’s Law: 90% of everything is crud.
That applies to both git and to hg. Which is why we tend to be a bit suspicious when we hear only glowing praises of something new. And then try it anyways, perhaps until we find things to complain about.
The grass is always greener on the other side of the fence. For a little while.
Look! Look at the strawman! It’s huge! It’s the biggest strawman I ever did see! I think Edward Woodward is waving from somewhere near the top. He looks pissed!
I enjoyed your post, but it’s still bollocks. We’re not looking for something to be perfect, or that nobody will ever ‘whinge’ about. Those of us who are unimpressed with GIT aren’t a little bit annoyed about the interface and general design or just making a fuss for the hell of it – you’re going to have to grow up and face the facts – GIT is severely compromised (or held back from true greatness, if you prefer), mainly due to the interface and partly due to the design underpinning it. The people complaining (complaining is good – without it nothing improves) about GIT on this blog are not scullery maids, chimney sweeps or carpenters. Everyone here is some form of technology professional – is that a fair assumption? The people here are well educated or at least technology literate. I assume many are programmers. Nobody can know every aspect of technology – there’s too much stuff, too many protocols, too many languages. Most would be keen to embrace a Source Control system that is powerful, easy to use and good at protecting the inexperienced or mistaken against fatal data collision and loss. In some cases we have to use GIT because it is mandated by our companies. Because a few people have managed to embrace GIT, or think like GIT’s programmers, it’s unreasonable to assume that everybody has the time or inclination to do the same thing – nor that anybody who complains about GIT’s manifest inadequacies is merely whinging for the sake of it. I think we’re all quite capable of distinguishing in our own minds at least, the difference between a minor annoyance that is mentioned in passing and a comprehensive deep rooted antipathy towards various aspects of what is in the end still a very powerful piece of software. The blog poster has even provided reasonable analysis including diagrammatic evidence – that’s a little more analytical than a mere whinge.
It seems to me that the solution for many of our technological failures is better documentation.
In the case of git, I like to point people at http://marklodato.github.io/visual-git-guide/index-en.html
In the case of Linux… well, actually, I’ve switched to OpenBSD (and am seriously considering plan9, but I’m not quite up for that challenge).
Anyways… I am not at all convinced that “good user interface design” is a relevant issue when talking about low-level computational mechanisms. Instead, the challenge is writing good, comprehensive documentation in a context where the coders are involved.
In my experience what happens is that coders can often radically simplify the documentation by rewriting small parts of the system.
Now… in the case of git… there’s a nice clean system sitting in there, buried in the crud of lots of contributions. Mostly the right approach here is to ignore most of the contributions.
In the case of hg, something similar is going on, but the crud is more in the conflicts between addon modules. Since git comes with the equivalent of hg’s modules pre-installed, people can level complaints at git which are analogous to complaints leveled at hg+modules.
All of which is a lot of fun, I suppose.
That said, there’s nothing wrong with being a scullery maid. Nor with being a chimney sweep. Indeed, some of them are quite well educated. Perhaps I should look into becoming one. Or, maybe a carpenter.
I’m having a hard time deciding which I hate more: git or eclipse. Its really a tough choice, but if you put a gun to my head, I’d have to say git.
I hate having to use git, but I have to be very thankful for the people who made tortoise git. Also, I think the version for Mac is called stash? Or something. Either way, tortoise git, and even tortoise svn are a godsend. It helps us UI oriented folk. Only thing I still have to figure out is to remotely pull on the production servers.
Incisive article and mirrors my experience exactly. I add value by creating computer code, every other task is simply cost on top of that basic economic function. My clients dont pay for my specifications, or my unit tests, or my OO concepts – just for solid working software. A tool which gets in the way rather than expediting that added value activity is just extra cost. Concepts and tools which help me deliver working software to the client more swiftly and with less defects than when not using them are extremely welcome. Tools which make this more difficult than it absolutely needs to be are not welcome. Building working software isn’t easy, but its got a lot easier as tools have matured and been adapted based on user feedback. Typically, but not always, this is becasue the tools are purchased and therefore the vendor has a vested interest in making them better.
There are some developers who revel in tool complexity and opaqueness but in my opinion simply aren’t doing the economic maths and are fetishising complexity to raise the barrier between them, the “experts” and the others, “the noobs”.
Git is hard to understand, not fail-safe, and unless you actually need distributed source code control (as opposed to geographically seperated team members) is wildly over-complicated for the basic function of building computer systems for clients.
A splendid response, which hits the nail squarely on the head
Excellent post ! About the point:
” 6. Power for the maintainer, at the expense of the contributor
Interestingly, I don’t think this trade-off is inherent in Git’s design. It’s simply the result of ignoring the needs of normal users, ”
Hahaha, what else you could expect from Linus Torvalds ?
Pingback: Is Git hard? | gerleim
Another good ole time with git. Tech Lead dude (this is the typical “master” in a git project) wants only simple PR’s (code reviews); so, take the 30 file change project and commit and push to A. Then push to B. Now, go back to A and remove 10 files etc. So, now we can first code review A and then later B (based on a diff against A). Sounds easy? Works in theory but in practice the tools do not repull the files for B once you make your deletes in A and push it. So, how to fix? You need to do a fresh git clone -b B … (well maybe a reset hard would have worked. Forgot to try that. But, I checked out B and expected to get B. Not happening with git bash or egit, I still have A. Well, it might be an easy fix to run rest hard or git clone -b; but its user hostile. The point of the OP.
Ok, so here the main thing. I mean, GIT is user hostile but we all used Unix for years before Linux and survived. That’s a weakness but not a deal breaker. The main problem with GIT is the sociology it fosters. The typical thing is one person gets setup as a Tech Lead. Over time they behave more and more hostile towards the programmers on the team. For example, they will force a programmer to keep changing variable names and other junk to delay that programmer merging into the base (master/whatever). Of course, because of GIT’s process, that programmers branch becomes ever more out of date. He/she can spend time constantly trying to rectify the changes others are making. In specific, the Tech Lead(s) typically form one first class team where they commit+push willy nilly in the master (release branch stream) and the rest of the team is a horde which becomes ever less productive as they are forced to “fix” all the changes the Tech Team does in trying to make them work with the rest of the system. GIT ends up being a great tool for a few team members to bully and pick on the rest. Not really what you want if you want a TEAM.
Oh come on Max, git has enough real problems that you don’t have to make up things. A “Tech Lead” cabal can do exactly the same in any other VCS, maybe even more efficiently when it isn’t trivial to clone a project with full history.
This does not at all match my experiences with git. And I used it extensively in a corporate environment and I was not the lead in charge.
That said, the issues you describe do seem quite likely to arise when dealing with certain people. So I do not at all doubt the accuracy of your observations (except to note that these problems arise regardless of the technology involved).
I think you’re right that with great people every tool works well.
The problem Max describes is likely because Git makes it much easier to mask toxic behavior as useful.
In the Freenet project I saw 3 specific costs introduced due to git: Many not-quite-finished feature branches which did not get merged for months to years, pull-requests which were not merged because they were not perfect and a codebase which changed underneath, making the merges become more and more expensive. This keeps us from doing much-needed refactoring, because that would make the merges even more expensive. The codebase isn’t only entangled internally, but now also between forks with different states of the code which will need to be merged.
How does using something other than git prevent features from rotting as they lie unmerged? Using SVN or CVS or hg or whatever won’t magically integrate those features into the mainline code. *That* is the problem – patches withering away in project maintainer neglect (whether benign or malevolent) – not the choice of VCS.
The default per-developer namespaces in git as well as renaming branches make it much easier for developers to simply drop in some patches (=commits) and forget them – in my experience they often never even get pulled into the main repository and subsequently get forgotten. I had to remind the maintainer of a project multiple times that there were still unmerged branches lying around when he only remembered the pull-requests. And that wasn’t malevolent: The project has roughly 100 branches from some unreleased feature development here and then some unreleased feature development there – and actually a GSoC project which was only released in a personal github repository and then not pulled. At one point I went in and pulled every single branch from every single fork into my own reposiotry just to have a backup in case users delete their accounts. And this is partly the fault of the tool: Git makes it easiest to work on your own and to ignore the larger project.
Mercurial on the other hand by default provides a shared view of the branches, and its interface encourages developers to pull and merge often. This makes it easiest to collaborate on a shared view of the code instead of making it easiest to create your own view into which you later integrate some other changes.
Consider on the other hand subversion: It makes it very hard to do short-lived branches, so people create huge commits with lots of actual merges which aren’t visible, because they happened on update before they could commit.
The tool has an effect on the culture which develops around the tool. Things which are easy to do will inevitably become more common and things which are hard will become less common over time. And nt git, things which are easy to do even include rebasing, which even Linus nowadays asks people to avoid, because it is a huge smoking foot-gun.
This does not mean that avoiding git will magically get all features merged instantly. Avoiding git is not a magic bullet which solves all your problems. It just makes life a bit better by avoiding the unnecessary *extra* problems git forces on your project.
If the alternative were CVS or an unfree VCS, I’d choose git any day. But that’s not the case. There are alternatives to git which provide you with the same features but less foot-guns and less encouragement for behavior which creates problems for the project on the long run.
and all the above without involving bad intentions: All the changes were done to improve the project (I know the people involved). It’s very easy to fall in that trap simply due to “limited time at the moment, I’ll do it tomorrow”.
(yes, that means that people aren’t perfect, so problems of the tool crop into our development practices)
In summary, GIT is an overly complex tool for people who cannot work well with others. As stated above, it adds 10% to 20% to a project cost versus using Subversion. 1.25 years experience with GIT. Several years with SVN. 21 years with about 8 source control systems total.
Make that 30% to 50% high cost to use GIT if you consider the team productivity and human factors.
GIT is not perfect, but I have worked with SVN for several years and that was just a pain.
git helps weed out the script-weenies
Possibly. Is that a good thing?
Of course! Here at Terrifying Software Inc we have a Code Stabber, who wanders round the office, checking on code. Your code isn’t up to the same level as Bjarne Stroustrup? You get a stabbing. Hoping to learn on the job? That’s a stabbing. No code weenies here. Only muscular, virile code paragons, albeit mostly autistic and sweating profusely.
Thank GOODNESS for TortoiseGIT. At least now I can just about do a decent history analysis to see who did that ____. Funny when you track down freshman code from the person on the project who has playing the role of Architect and runs his mouth and tries to over-ride the conversations when he does join the meetings.
One more git PITA:
$ git status
On branch EPIC_XYZ
Your branch is up-to-date with 'origin/EPIC_XYZ'
…
.$ git pull
[git proceeds to pull down two changes]
EXCUSE ME? “up-to-date” is English for no changes. Who wrote this ____.?
Well, I didn’t mention this happened because I did a merge with Stash then went to Eclipse and did a new branch based on the mainline in eGit. The eGit did NOT get the latest files. Sure, there might be a timestamp issue between something. I’ve documented before and above that git/stash don’t work well across timezones. But, this is not expected and can lead to lots of issues. Basic feature of a source control system is reliable check-in and check-out. This is not.
Agreed. Git, despite being “distributed version control”, lives in an offline world. You have to manually synchronise the “remote branch” (held locally) against the actual “remote branch”. Maybe this made sense 10 years ago, but it’s really counterintuitive and somewhat bizarre now.
I don’t mind the offlineness. What I mind is the horrible message: It should not state that it is up to date with origin/. That’s a total user interface failure, because the actual meaning (up to date with the local branch) is the opposite of what the word origin implies.
That’s semantic drift for you. You can take heart, though – most of the english language has been subject to the same kind of issue. (For example, a few centuries ago, “genius” meant what we would now term “idiotic”. For example, “sick” can be a term of high praise, in some contexts. For example, sensitive topics tend to be discussed using euphemisms which tend to be replaced once they become well understood.)
That said, you do not need to understand all of git’s internals. You do need to understand some, but a system which does not require some understanding is a useless system.
That said, Mercurial proved that it’s possible to build a system with less capability than git and then add that capability back in using plugins. The downside, of course, is that plugins are a horrible user interface experience, due to design conflicts between independent plugins and a need to have a deep understanding of the underlying system in order to isolate and resolve problems.
That said, a system which does not require some understanding is a useless system.
origin/EPIC_XYZ is your local image of the remote. You might want to consider doing a fetch before status if you want to compare your system with the remote?
Or, you know, I guess instead we could wish that there were no actual work worth doing…. And I hear there’s good money to be made in making systems less capable and then claiming that that’s an improvement.
I blame it on git that people think that source control has to be complicated to be powerful.
Mercurial proved over and over again that it is possible to create a simple user interface which allows harnessing the same capabilities as with git – and then some on top with its powerful plugins.
Git however does not even try to be usable: Implementation details inevitably seep into your workflow and require you to understand all of git’s internals to use it effectively.
$ git merge FETCH_HEAD
merge: FETCH_HEAD – not something we can merge
OMG!
Just FYI: work-around for not being able to merge from EPIC (main) branch was to go find last branch merged into that EPIC and to merge from it. Of course, this would not have been possible if the team were truly working distributedly; but, the team is using Stash and putting all bug/feature/issue branches on the server also.
Here’s another fun one. In eGit create a new branch against an origin branch. Look in the files. They are not up to date. Why? I guess git uses the last pull against that origin rather than the actual origin. So, you have to perform a pull to get the latest file. New branch, one would think, should get the current files of the origin branch. It doesn’t if one has worked with that origin before.
Yeah, this is a BIG user experience design flaw in GIT. No telling how many bugs and how much time it has wasted. What git does is when you git checkout EPIC_BLAH then it does NOT go against origin but actually against a local copy. So you MUST next issue a “git pull”. To get the central code. Yes, I know git is designed for that high-and-might tech lead who feels the code on his/her computer is the golden source; but, in the normal world people work as teams and code gets pushed to a central server. Pulling, by default, from local when user wants to branch from the main (epic) branch is bad user experience design. But, hey, we are talking about git, aren’t we!
No use and no point ranting off git as git isn’t even targeted at beginners.
git isn’t targetted at beginners, or author should just find some nice GUI git frontend which can hide the complexity or use something he can understand.
Linus Torvalds originally developed git for use with the linux kernel development which has a very complex model.
I agree, that beginners should use something they can understand. But sadly git-using projects force beginners (of version tracking) to use Git when they want to contribute. You’re saying that any projects which wants people to contribute who don’t *already* know git well, should use another VCS, and I agree. I would add, though, that everyone starts out as a beginner, so if most projects use git, there isn’t any project in which beginners can contribute. But since in free software the turnover rate of developers is pretty high, all projects are dependent on getting new people to join.
So I’d say, that your assertion that git isn’t targeted at beginners leads to the conclusion that no free software project should use git.
The main beginner here is whomever wrote git. Or, rather, whoever thinks it should be used for teams. Its fine for the two cases for which it is designed.
This blog reminds me of the blog bashing Raven-DB, where the conclusion was, that the blogger misunderstood the concept of DocumentDB, and was trying to apply relational concepts on a document based database. They were having a bad time…
Subversion was my first experience with project/file versioning working with it for 5 years and loved it (with it’s faults). But after a go with Git in a couple of years, I would never dream of recommending going back. After migrating to Git the headaches of merging was simply gone. Less time was used on the revisioning system, and more time went to implementation.
Also had the pleasure with TFS, which tasted like subversion.
If you wanna make a subversion-like use-case, then why not just ad the developer as a contributor to avoid pull requests?
To avoid the two-step commit/push, then make an alias. I myself would not do so, since I find it powerfull that I can make partial commits/milestones locally, before pushing to a branch. Never had that situation, where you wish you’ve stuck with your first (un-pushed) solution while refactoring?
Atm I’m working in a small 4-man group using TFS. And the guys are using a lot of technical-excuses due to the lacks in TFS. Seems like Git is gonna get a go :)
> If you wanna make a subversion-like use-case, then why not just ad the developer as a contributor to avoid pull requests?
That kind of makes sense, but you’re speaking as repository manager, not developer. Anyway, it’s been two and a half years since I wrote this post. When I wrote it, my feeling was a very frustrated “I find Git so hard to use, am I the only one?” My feeling, having used it a lot since then is, “No, the designers and maintainers of Git have created a lot of unnecessary pain, and they have made only the slightest improvements to usability in that time”.
The complexity, steep learning curve, and vast number of edge cases and weird messes that are hard to resolve are a travesty, for a tool which is at the absolute heart of the vast majority of open source software development. The OSS world would be a much better place if they’d got this stuff right.
Although there is a element of ‘bashing’ in the original post, I think there are unavoidable criticisms: namely, that git’s informational model is very complicated, exacerbated by a messy, disorganised command-line structure, and that its disappointingly easy to get into a confused state where work is lost.
Unfortunately, the original post made these criticisms relative to Subversion rather than alternative DCVSs, which was a red herring. These points are strong but the comparison with Subversion undermined them because, good though Subversion is, it’s a very unconvincing alternative to git.
>Unfortunately, the original post made these criticisms relative to Subversion rather than alternative DCVSs, which was a red herring. These points are strong but the comparison with Subversion undermined them because, good though Subversion is, it’s a very unconvincing alternative to git.
Yeah, when I wrote the post, I wasn’t expecting 250,000 views. Back in 2012, I think Subversion was still the dominant version control system that people were migrating away from – certainly it was the one I knew best. My complaint was “my experience using Subversion was pretty simple. With Git(hub) it’s a nightmare. WTF?” Definitely not an apple-to-apples comparison.
Agreed. You argued passionately and captured the ‘WTF’ sentiment that git inspires for many many people. And you certainly have my sympathy for the mere 250,00 views ;)
It’s simple: If all you can handle or need is MS Paint, and you use Maya, you don’t get to bitch about Maya. Go back to your MS Paint. It’s the right tool for you.
But maybe you’re not smart enough to realize that either.
This is an oxymoron of a reply. You’re trying to claim an elite intellectual position while conducting the argument at the level of a child.
If you reword your argument as “if all you can handle or need is a bitmap paint program, you don’t get to bitch about 3d modelling software”, then sure. But virtually all software can be, and should be, made easier to use – probably Maya included.
Most software should be documented better. Better reference documentation, better task oriented documentation, and better tutorials, better cross linking between them are all good. And, it’s also good for the person writing the software to take part in the documentation process (because all too often changing the software to be easier to document is better than documenting some arbitrary decision).
That said, “easier to use” is not actually an “always thing”, even for software. Once software is in use, changing it or replacing it breaks existing uses which makes it harder to use (for some people).
Worse, easier for task A can often be harder for task B.
And that, I think, is related to what we are seeing here.
Leaving aside the merits of Git vs TFS vs “the World” I am surprised at the level of unprofessional reaction to what would otherwise be a dry subject about the merits of the functionality and accessibility of a source code control system. Steve’s original comments about Git being hard to learn and hard to master don’t seem (whether you think they are justified or not) to merit the really strong opinions that have been aired. What is it about the assertion that seems to rile technical people to throw their toys out of the pram ?
I happen to agree with Steve but also realise there are a host of people out there who get on with Git just fine. They are the “happy customers” of Git. There are also a whole bunch of “Unhappy Customers” it seems who find it overly difficult or its strengths relatively unhelpful in their working environment – if our reaction as a profession to our “Customers” is “the customer is wrong, the product is brilliant” as opposed to “If the Customer says they have a problem, then we ought to attend to that” we are in trouble.
You know, perhaps at the heart of the problem is that there are no true paying customers of Git ? In a true commercial offering, the authors would be beholden to make their product suit their customers (whether they liked what the customer was telling them or not) – you could sell Git on its powerful features, or perhaps TFS on its low friction user experience, but in both cases you would need to be flexible to provide what the customer demanded. Without the pressure of the market to shape the product, maybe vociferous opinion fills the gap ?
I will agree that I do not think of anybody in this conversation as my “customer”.
But to the authors of Git, we are their ‘customer’ even if we don’t pay. Building for your customer is a mindset where you build what your customer wants and needs, not what you wish them to have. My real thrust here is that because Git lacks a customer focused development team, we get what we are given, not what we want or need. To repeat my point; its perhaps because we are unwilling in the main to sponsor (with money) a customer focused development effort that we get stuck with “hard to use” freebies. Its just a way of looking at why a supposedly “premiere” software development tool seems to generate strong emotions of either euphoria (or defensiveness) or disappointment (or flame). Or put another way Steve Bennet says “gosh this is so hard to use, could it not have been done better ?” to which a reply might be “perhaps if we paid for it, the authors would listen to us because they’d value our opinion, because the opinions of customers are valuable to a commercial organisation”.
If Git is so painful to use, why is this happening?: http://www.google.co.uk/trends/explore#q=%2Fm%2F05vqwg%2C%20%2Fm%2F012ct9&cmpt=q&tz=
To be taken with a pinch of salt, as Google Trends hardly constitutes scientific research.
;-)
The number of searches on a topic isn’t a good indicator of its popularity, just how often people have to search about it. I could easily say that its because Git is so hard to use comparatively, that it turns up in search engines so much. This is a measure of the number of searches about Git, not the level of acceptance of Git.
Yeah, yeah: http://www.google.co.uk/trends/explore#q=paying%20tax
Nice comment. Yes, Git could do with much better documentation, and could have done for many years. Better in the sense of “more useful to the average user”.
>That said, “easier to use” is not actually an “always thing”, even for software. Once software is in use, changing it or replacing it breaks existing uses which makes it harder to use (for some people).
Git seems to have been unnecessarily conservative in this regard. The porcelain/plumbing distinction was supposed to make it possible to change the command line interface, but that has happened incredibly slowly. Occasionally, you get really useful information describing what just happened and what your options are. Mostly you don’t. There’s no good reason for this. And no reason not to fix it.
>Worse, easier for task A can often be harder for task B.
Agreed, but IMHO Git is most suited to a tiny fraction of its actual users.
Pingback: Git | PolyAwesomism
Git vs SVN comparisons are perilous because people rightly point out that distributed version control systems have a lot of advantages over strictly centralized ones, and that turns into an inference that Git is better than SVN because it’s distributed. If Git were the only way to do DVCS, maybe this would hold true, but it’s not.
Both Bazaar and Mercurial are easier to use and deliver all the benefits of DVCS. Hell, Bazaar can even support the centralized svn workflow while more advanced users can take advantage of distributed features.
Most of the stash/rebase/squashing commits/etc in Git is busy work you have to do to work around Git, not powerful features. Spend some time with either Mercurial and Bazaar and you’ll see this. Furthermore, Git discards what most VCS users would regard as branch histories whereas hg and bzr do not. Both of these systems map to our mental models of changes better than Git, which is why there’s so much confusion when people attempt to understand wtf Git is doing or how to dig themselves out of a problem.
See http://duckrowing.com/2013/12/26/bzr-init-a-bazaar-tutorial/ and http://www.cs.cmu.edu/~davide/howto/git_lose.html
Distributed version control can be a lot better than centralized version control, but there are much better and easier options than Git.
Great comments, thanks. Bazaar is kind of on the way out though, right?
I Totally agree that git is overly complex and counter intuitive at the point where it looks “almost” purposely. it is the developer to do ALL THE EFFORTS to learn understand and fix. The confusing and inconsistent command line makes it DANGEROUS too. The system gives no EASY way to actually FIX the problems but just DROPS them in an unfriendly manner to the face of the developer for him to deal with. You can easily as a beginner be blocked in the middle of the river : Cant commit/push/pull cant ‘t solve and can’t cancel and can’t roll back easily ! BROKEN.
This is a perfect example of a GOOD CONCEPT and a TERRIBLE IMPLEMENTATION that does GOOD – AND BAD because of it might slow down a better DVCS FREE OPEN SOURCE software tool adoption by its popularity.
I wish it will quickly die and be the seed of a better DVCS that works on same main ideas but a this time DECENT and CLEAN implementation that users can actually use.
ANYONE should be able to use this kind of tools WITHOUT have to take lessons and read extended manuals first !
if you need a degree in order to understand and checkin some code in some system something is wrong !
You might want to look at Mercurial. It developed side-by-side with git and they inspired each other, but different from git, it had a strong focus on clean user interface from the start.
If you’re used to git, the main stumbling block are small differences in philosophy. These have major impacts on branching (Mercurial avoids the need to branch everything explicitly because it easily copes with multi-head branches, but urges developers in the user interface to keep *public* branches to one head), tags (versioned tags as part of the history), history style (Mercurial favors slightly messy history over rewriting published data and in turn provides powerful tools to query the history) and project organization (Mercurial favors sharing history early – focussing at the project – git favors keeping it in private repositories until it is perfect – focussing on the individual developer).
I think people are approaching this completely the wrong way. Comparing two tools like this doesn’t really work when both are potentially viable and not one supercedes the other across the entire domain of software development. I can say with full confidence that for my requirements SVN is not only the best choice but superior to git in what it offers. I could talk a lot about SVN to prove this but it’s not all about just SVN. There is a 50/50 split here. The is tool/situation. We really see everyone focusing on tool with little focus on the situation.
My situation is simple and common but perhaps more hidden than the well known case of public opensource projects. I work on a small closed source project. We have a small team and it’s not likely to become significantly larger or distributed in any unmanageable way. Many projects, even very profitable ones, do not warrant hundreds or thousands of developers, especially not complete strangers.
Git is geared very much for a number of opposite extremes:
* Collaboration is anonymous. What this means is that collaborators are untrusted and that we cannot impose constraints or policies upon them, instead we must heavily guard the source tree.
* Project sizes can be huge an receive great numbers of contributions (ie, the Linux kernel).
* Projects are individual backed and not backed commercially. The original primary source may go down for example.
* Projects may be extremely long lived. This may also be the case for commercial projects but combined with the volume of contribution this can become a serious problem.
This might not be a lot but many problems fork from these facts. In this case the push pull requests make sense, committing locally makes sense to encourage complete submissions upstream rather than several partials (which may never be submitted in completion otherwise and burden a central repository). Local operations can also reduce the burden on the main repo and distribution can offer some interesting scalability benefits. Innate backups are also useful. Clearly, the design of git was very insightful about this situation and tailored to it.
That is exactly where the problem with git lies. It’s a great solution, but to a particular situation and all the problems that entails. I do not have such a situation or such problems. My situation is different.
* I am in close proximity to all programmers. They are contracted and employed. They must follow procedure and are trained appropriately. There is little need for hard restrictions either on the VCS front. They are not anonymous and if they do not conform adequately, I hate to say this but it is true and this is in the real world, they get fired. In the absolute worst case that they do something wrong (destructive, deleting files, etc) they get thrown in the dock. The VCS is also not our direct means of public or end customer distribution. While distributions are taken from the VCS, this is by us and is a controlled process. Code does not go straight from VCS to customers or nodes. Very few commercial ventures would use VCS in an uncontrolled way for distribution so this is the norm here. Git is different because people may be pulling straight from the VCS to contribute or build. For a commercial setup we often only need tight control at distribution which is where the hard restrictions go. VCS is a natural sandbox in such a case.
* From a management perspective, I need to monitor developers. That means that they commit often to a global repository so that I can review and give them the guidance they need as well as monitor progress, in particular to help them if they get stuck in a quagmire. From a close-knit team sync perspective we avoid a lot less collisions being able to see quickly what is going on. There’s no benefit from suspecting contributions or encouraging it. They are assigned tasks and expected to finish and in the rare case they turn out to be a lost cause we simply svn delete the attempts. In this case we have completely the opposite requirement that managing an open source project has. We share frequently, even if something is incomplete and svn makes this much easier as it is the default way to work. We have little need to inhibit developers when it comes to sharing.
* We need centralisation to manage and keep track of everything. It is both easy and cheap to set up a fast server with regular backup. If it is to be believe that git solved all backup issues then that might save us about 50 pence. When it comes to serious business, although git does have a fairly good chance of causing your repo to be backed up to a good extent by default, I would rather rely on a common place cheap yet reliable and guaranteed means of backup. This also comes at a cost for a large codebase because fetching the entirety of it to checkout is not cheap. Additionally git may encourage practices that result in more loss in failure. For example, a developer is given a large feature to work on. They branch and work on it for a day committing locally. Memory corruption (or any failure) breaks their repo and and they did not push remotely. It should be argued that the policy should prevent this from happening but git does not help much by making the whole procedure more complex. Distribution complicates the situation in general (who has what, where to push to share, etc). It adds an unnecessary element of flexibility and choice where none is needed. This can only result in chaos. There is no benefit in on developer being able to share with another and not the whole group.
I could add many more things but that should be enough. So, git just does not work out for me. It has a number of qualities that were added to deal with problems that I don’t have and those qualities are not innocuous. They tend to get in the way of things and impose some burden. I receive all the overhead but none of the benefit. With SVN all I get all the time is head and every man likes a bit of that. I think there’s a pretty solid consensus here that git is more complex. The question that leaves is does that complexity always pay? The answer from me is no, it does not.
I would use git without question if hosting an open source project where I want plenty of contributions and it would be stupid to use something like SVN for that but for a small internal team it makes no sense to me to use git either, given the right circumstances it would also be equally stupid to use git for such an endeavor.
I receive a lot of attitude from people who don’t really understand varying situations and crossover from the opensource world is not new. For example, I do not use database abstraction layers that offer portability too much. In the commercial world we often have the luxury of control over environments and the number of times I have had to change database for a large product is so infrequent that on probability portability wont pay for its self and has no value in actuality. Many people say these things are free but in reality very few things really are. When making a product to run on random machines portability might make sense. For an open source project it makes a lot more sense. For me it is like getting insurance when I buy a new phone. The chances of me breaking it are so small that after a while I will spend more money on insurance than on replacement phones.
You are quite right ! I fully subscribe to your analysis. For the majority of closed source (commercial) projects Git only offers headaches and solutions to non-existent problems. I use SVN in a commercial project and others (not Linux hacker types, but creative and artistic people) can easily use it, they are productive and are not hampered by the tool. I would never expose them to Git’s model, it would slow down everybody.
Also, as opposed to all the comments here that state that Git has become the standard VCS in open-source land, there are still very siginificant projects that use centralised VCS such as SVN. One project I know very well is the FreeBSD prjoject which uses SVN for code distribution and control. Perhaps Git and SVN can be seen as the exponents of Linux and FreeBSD – anarchy vs controlled. One only has to look at the rubbish heap that is the Linux kernel source code and compare it to the clean and orderly FreeBSD kernel source code to better understand the differences between Git and other VCS tools.
$ git push origin HEAD
…
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: ‘git pull …’) before pushing again.
So, try it:
git fetch origin devbranch
git merge FETCH_HEAD
$ git merge FETCH_HEAD
Already up-to-date.
Also tried git fetch issue_branch
WTH. So, my local branch cannot be behind its remote counterpart as I just had checkout from there 15 minutes ago before I made this change! The message is bullsgit. Who wrote this git?
3 years on, and I feel Git’s documentation has improved massively, both on the official website and at the command line. Additionally, there are dozens of very easy tutorials to get you into the Git mindset, of which this is my favourite: https://try.github.io
I wish I could agree, but I haven’t seen many changes in the command line documentation or man pages. The website is better, but that doesn’t count for much; there have been dozens of good tutorials around for ages.
My complaint is not simply that Git is hard to *learn*, it’s hard to *use*. Years on, I still constantly have to consult documentation because it’s not intuitive, and I frequently get into messes that are hard to fix.
3 years on. .. Why doesn’t git have the equivalent of:
[svn add]
svn commit
It’s really all I want to do..
git add -A
is basically the same assvn add
, isn’t it?Incorrect. `git add .` is roughly the same than `svn status | grep “?” | sed “s/^.* /svn add /” | bash`.
`git add -A` is the same than `svn status | grep “?” | sed “s/^.* /svn add /” | bash && svn status | grep “!” | sed “s/^.* /svn rm /” | bash`
Well, it’s almost exactly three years later, and I feel that things have gotten a lot better. However, I think that a lot of these weren’t arguments in the first place.
#1 – Any version control system will come with some learning curve. If you’d learned Git first, you’d be complaining about Subversion. It’s just the nature of learning a new tool. Can it suck? Sure, but that’s something you have to deal with any time you learn a new tool.
#2 – The commands aren’t standard with Subversion. That doesn’t mean they’re necessarily bad. I will agree that some things in Git don’t make that much sense, but again – if you’re coming from an SVN background, you’re going to be a little biased in what you expect. Try hg and then migrate to git. This really goes hand-in-hand with #1 – there’s a learning curve, and that is expected.
#3 – Yeah, I agree. Man pages suck. That’s not just a git thing, though – that’s just man pages in general. Man pages are designed for a developer audience due to the nature of the UNIX environment. That said, documentation has gotten better in the last three years.
#4 – This may depend on your usage. Most of the time, you’ll be adding, committing, and pushing. If you’re working in a shared repo, you might be pushing, pulling, and merging (and possibly rebasing depending on what you’re doing). Although I’m sure there are corner cases, I haven’t seen any in my regular usage. Not to say there aren’t any, but this may have stabilized over time.
#5 – This may have gotten much better over time, or you may be trying to do things that I have never attempted. Quite honestly, for tasks like these (even with other VCSes) I will Google the answer. I suppose that if you are working without an internet connection, this may apply.
#6 – I think GitHub has solved whatever this is?
#7 – Git can mutate history, yes. This is stated up front and as such is an expectation. Mercurial provides this functionality via plugins as well. This is a feature.
#8 – I think that this conflicts with #6, but again – GitHub solves this. If you wanted to do this without a server model (like GitHub provides), you still update and commit – update and commit. It’s the maintainer’s job to pull in nonlocal branches, so this is a nonargument.
#9 – git reflog.
#10 – The paradigm has changed – you’re using a non-DVCS workflow in a DVCS. You don’t need to push with every commit. Finish your local work, push, and then submit a pull request. It does take a bit of getting used to, but I personally think it’s much nicer than everyone committing to one server branch (and dealing with diff bombs when you don’t check in for a little while).
Again – three years late, and I know there have been a lot of responses to this – but I hope that people in 2015 are able to read this article, along with the comments, and realize that the paradigm has changed, not just the tools. I hope that all of these “problems” will be nonissues for current and new adopters. I don’t want to sound like a Git fanboy, but DVCSes are the future – they are the now, really – and progress doesn’t like to go backwards.
Happy DVCSing!
Three years on, it’s been a very long time since I’ve touched Subversion, and yet I still find Git unintuitive, hard to learn, and frequently have to consult help pages. So, it really, honestly, genuinely, is not a question of just being “what I’m used to”. I’ve now spent far too time using Git than I ever spent with Subversion.
>#3 – Yeah, I agree. Man pages suck. That’s not just a git thing, though – that’s just man pages in general. Man pages are designed for a developer audience due to the nature of the UNIX environment. That said, documentation has gotten better in the last three years.
IMHO, Git man pages are much more cryptic than average. Any examples of documentation that has “gotten better”?
>#4 – This may depend on your usage. Most of the time, you’ll be adding, committing, and pushing. If you’re working in a shared repo, you might be pushing, pulling, and merging (and possibly rebasing depending on what you’re doing). Although I’m sure there are corner cases, I haven’t seen any in my regular usage. Not to say there aren’t any, but this may have stabilized over time.
If you’re working solo, yeah, life is trivial. The rest of the time, you’re very likely to be making branches, rearranging them, reconstructing history – and it all gets very messy.
> #5 – This may have gotten much better over time, or you may be trying to do things that I have never attempted. Quite honestly, for tasks like these (even with other VCSes) I will Google the answer. I suppose that if you are working without an internet connection, this may apply.
Yep, I “Google the answer”, too. That’s the problem, not the solution.
> #6 – I think GitHub has solved whatever this is?
No, not really. It does make managing pull requests much more enjoyable though.
> #7 – Git can mutate history, yes. This is stated up front and as such is an expectation. Mercurial provides this functionality via plugins as well. This is a feature.
Calling it “a feature” doesn’t make it a good one :)
> #10 – The paradigm has changed – you’re using a non-DVCS workflow in a DVCS. You don’t need to push with every commit.
I find that makes life more confusing. I prefer work to be in one of two states: uncommitted, or committed and pushed. Adding a third state (committed but not pushed) is complexity with no benefit.
There is also a very nice and factual blog article by Benjamin Pollack describing the shortcomings of DVCS in general and Git in particular:
http://bitquabit.com/post/unorthodocs-abandon-your-dvcs-and-return-to-sanity/
That blog article does hit on some interesting points. But I think he has missed the biggest issue, which is perhaps best summed up by this Alan Perlis epigram: “Dealing with failure is easy: Work hard to improve. Success is also easy to handle: You’ve solved the wrong problem. Work hard to improve.”
Nothing could drag me back to Subversion, having broken free of it with git. What a breath of fresh air it was and remains every day. Firstly, the use case that Pollack dismisses, which is poor connectivity to the central store is my daily reality. If you need a network connection to use version control, it’s not a viable solution. Secondly, Subversion enforces the madness of maintaining branches in the folder hierarchy; this forces a damaging centralising decision over the folders structure for branches, which has not been done wisely, historically. Thirdly, Subversion lacks the notion of working privately under version control – so you have to do a dance with public versions that are organised by convention to be private – making the workflow more complicated for no real reason.
Pollack’s best point is the issue of storing large objects. We work in GIS and we need large objects to be versioned. One issue he doesn’t mention is the file size limit. Git has a file size limit of 2GB – so does Mercurial and (in practice) I found Subversion had a different but equally impractical limit. 2GB in GIS work is not a large file. So in reality we fall back on manual version control – which is really unsatisfactory.
The issue of large repositories that grow with history is an interesting issue – although his examples of 333MB or 1GB made me laugh, as that really seems quite small these days. But combined with large object store, it is a show stopper.
[It’s not difficult to design a solution to this – and git-annex is clearly not the way forward as Pollack rightly asserts. In essence, the answer is that BLOBs should be managed with a deferred download status. When you clone a repository, some files don’t get locally copied but deferred and the ‘shadow-copy’ that appears on the disk is a proxy for the remote file.]
Is git a good version control system? No. But Subversion is not a viable alternative and git/Mercurial is the best we have got right now. Personally I believe that a much better way to organise version control is around the idea of a virtual file system rather than a system sitting on top of a conventional filing system (and if anyone wants to learn more, nudge me – I am on a promise to write an article on it anyway.)
>If you need a network connection to use version control, it’s not a viable solution.
I agree – this is a must. But personally I could really do without all the manual pushing, pulling and fetching. At the very least, Git could have a constant background fetch process so that at least origin/master always represents the current state of the remote branch, not just the last time you manually synced it.
>Secondly, Subversion enforces the madness of maintaining branches in the folder hierarchy;
Yeah, that *sucked*.
>Thirdly, Subversion lacks the notion of working privately under version control
This is definitely much better under Git. It would be hard to go back.
>Is git a good version control system? No. But Subversion is not a viable alternative and git/Mercurial is the best we have got right now.
What bothers me more than anything is how little Git has improved in the last few years. It went through a rapid development process, then stabilised in a not very good state. If it was “the best we have got right now, but it will get much better soon”, that would be fine – but it’s really not improving significantly.
Well done
For our shop, the biggest Git danger is that a user Googles for help, finds some detailed code from a Russian teenager posted in a pirate forum. A few forces, merges, branches, and other efforts folow, and before we know what happened, that person can’t interact with the team anymore and we have to erase the whole repo to start fresh.
Still, seems there’s no realistic alternative. Subversion is quite nice, but so limiting.
Did you try Mercurial?
… whose “Definitive Guide” has not been updated in six years???
if you mean the official guide ( http://mercurial.selenic.com/guide ): It did not change much, because it needs to keep working for university clusters and such which ship you an age-old version of anything. And the old way still works well. Mostly it got some footnotes how never versions make it easier to do some stuff.
If you mean the book: Well, it’s a book, and not maintained by the project itself. Its author nowadays mostly blogs about Haskell. Most information in the book is still valid, though, because the core design of Mercurial proved to be good enough to withstand the test of time.
Yes, I meant the book. I think that Mercurial is way better than Git, mostly due to its proper accounting also for Windows and its much better command-line user interface.
But I was used to Subversion’s documentation, which is from a user’s perspective very convenient: one single main book, well written, complete, useful as intro and reference, and usually up-to-date.
Mercurial’s 2009 book is what keeps me off of it, as it seems that such an old book cannot be a good resource to learn and use a modern and rapidly evolving software. If fact, there is a danger (even if only felt and not real) of learning things, best practices and workflows long outdated. So the book is out, and I’m forced to learn about Mercurial from fragments scattered over the internet. And that unfortunately leaves me in a situation that is, as much as it pains me saying it, worse than with Git.
He is a frequent slashdot contributor!
More than my project I had to work more on Git to understand to get things done.
I cannot say I am an expert on Git. I have personal projects and I find Git the best solution for me to keep track of the things I did on the source and keep versions of them.
But this is unbelievable, during the time of this writing, the code I wrote for months was not tracked by Egit. I am losing my mind since I am doing an android project and wrote myself a content providers and done so many refactoring. I kept on pressing commit and push and none of the new files I created weren’t included in the branch. What the fuck is this? I have not encountered this anywhere else on my other projects. I am in a situation where I have deleted my original files confidently believing that it was tracked and I have my versions backed up. But that wasn’t the case. I am starting to hate this whole shebangs all together.
Now I need to go back to read a voluminous read-this-all-to-become-a-technological-GIT-GOD and undergo 4 year course understanding Git just to make sure this won’t happen again.
So far, I am still inclined to use git no matter what, but the gotchas using this technology is very costly. So I warn beginners using this.
@Neon, sorry to hear that you’ve ended up in this situation. Speaking as someone who has been using IDEs for over thirty years, I am not a fan of using integrated source-control tools like Egit for exactly this kind of reason. My guess is the problem does not lie with git but more likely some issue with Egit. I think it is fair to say that sooner-or-later every single integrated source-control tool I have ever used has broken in the kind of way you describe.
My recommendation is that you use a dedicated source control tool. My favourite is SmartGit (http://www.syntevo.com/smartgit/) but Atlassian’s SourceTree looks pretty nice too. I use SmartGit on a daily basis with Eclipse, Visual Studio and Sublime and it works just the way I want, cleanly separating code development from version management. The only IDE that struggles with file being modified under its feet this is VC6, which I am obliged to use to maintain some ancient legacy code, and even that isn’t a big deal.
Since I switched to this way of working I have found my workflow significantly smoother as well as more flexible and powerful. I no longer find myself having to disentangle the IDEs bizarre decisions and incorrect reporting using a hopelessly inadequate interface.
Just my opinion – and your mileage may vary – but it works for me & may work better for you.
Oh boy, just hit a few more. Forgot the one from yesterday night but today realized doing a “merge” on the Stash website does not actually merge!!!! What the HELL! Had
epic->A->B->C
Merged C to B.
Then merged B to A.
Then merged A to epic.
Guess what!! the B and C work is not present in epic. Each has to be merged directly. What the hell. (Stash is Atlassian’s git server. I assume github and others operate the same, equally bad.)
git – sht that works sometimes and breaks in almost ALL non-happy path cases. But, did we mention it lets one dude lord it over everyone else? :-) Maybe its just a Stash problem.
(It might be the merge worked but someone over-wrote with old code. Well, the “history” doesn’t reflect the merge having worked.) BTW, there’s a third one. When reviewing history in Android Studio I don’t see any branch info. That sucks. Shows me the date the file was created and that is all. But I know it was created in another branch. And merged, twice. When looking at the history of another file I see similar… shows the date of the change but not the fact it was on another branch. maybe its just Andorid Studio.
Note those are really about Stash and about Developer Studio, two GUI’s atop git; so, not exactly about git. Also, note the merge issue was with the Stash button called “merge” and not executing the command to git from command line.
Use recycle bin for local version system: delete a file just before saving it again, and you can always “restore” previous versions from the recycle bin.. ;)
@eevee on twitter:
git people trying to use hg: “WHY WON’T IT LET ME DO THIS”
hg people trying to use git: “WHY DID IT LET ME DO THAT”
With one main difference: The answer.
– git people trying to use hg: “WHY WON’T IT LET ME DO THIS” ⇒ hg people answer: “just activate extension X when you really need it”
– hg people trying to use git: “WHY DID IT LET ME DO THAT” ⇒ git people answer: “that’s how DVCS has to be”
though hg people are more likely to say: “why did that happen? I wanted to do this!”
OK. So here is one of the top 10 things I hate about git. Having used it over a year now and used it on a medium large project, here we are at the rapid fire phase of the project where we are making changes left and right. GIT is an ABSOLUTE mess for this style of development. Things are constantly out of sync. Changes are hung up in the PR (code review) process so other changes miss them. GIT is simply an absolute mess to try to use for teamwork on a large project because the style of use is lots of branches. Its perfectly find probably for small effort projects where each effort can be one Agile task and is orthogonal to other efforts; and, clearly, this is probably what most teams are doing these days.
+1
All I want is to concentrate on my development, and dump the code into a repository. I do not want to waste time “learning” another VCS.
What is the need for a local repository (which everyone says is an advantage). I dont need one. Unless I push the code changes to a remote, no other developer gets my changes. So why ?
It was so easy with SVN where my local folder structure would mirror the SVN structure, branches and all. In case of merge conflicts, I had scripts backup my changes, override and update. Then I would manually merge back my changes from the backup.
Let’s state the obvious: if you do not need a local repository, then there’s no advantage in it for you. By contrast, I am often in places with no internet connection and it is great to still be working under version control. Also, when I am doing work on a several connected features, I like to work with local private branches so my colleagues aren’t exposed to the minute details of how I am putting the changes together.
As for SVN making your local folder structure mirror the central structure, git does the same – at least the way I am using it – so I don’t follow the point you’re making here.
>> By contrast, I am often in places with no internet connection and it is great to still be working under version control.
I may not have internet for a few hours. After that I need internet connection to share the code. For me, no internet connection = no version control.
>> As for SVN making your local folder structure mirror the central structure, git does the same – at least the way I am using it – so I don’t follow the point you’re making here.
I do not say git checkout branchname to switch branches when using SVN. https://svnrepo.mycompany.com/branchOne/src/main/java and https://svnrepo.mycompany.com/branchTwo/src/main/java are on separate folders on hard disk.
I avoid all that headache of stash and local repos and remote repos. I have a simple view of things. My changes on local versus others’ changes on SVN repository.
Very good analysis on git software. It should be made even simpler form user perspective and useless commands/duplicates should be removed. I enjoyed a lot especially “Keep using Git, and more concepts will occasionally drop out of the sky: refs, tags, the reflog, fast-forward commits, detached head state (!), remote branches, tracking, namespaces”
I reached this page by googling “git sucks” after a year of struggling with it. This page is one of the top results.
If a tool involves a much higher learning curve for the benefits of what it offers, I believe it loses in the cost benefit analysis. It is not that I am slow to pick up things. I have to pick up a new framework almost every six months. IMHO, there are many more exciting things I should be spending my time learning, rather than git. I do not see the need to be a git expert.
Resolving merge conflicts is a pain. With a good SVN Eclipse plugin like Subclipse or Subversive, I can simply see where there are conflicts. In case of merge conflicts, simply save my changes into another location (I had shell scripts for that). Right click and select “Override and update”. Apply my changes from the previous copy at another location. Done. Simple. I have been told that this is inefficient. Maybe it is, but it works well for me. Git may be good at automatically merging – but the day it messes up the merge, it takes away all the time I had saved.
If I want to create a branch for my development, I can have that in SVN too. The branch will not be private, but it is still my branch for my experiments. If I need a local repository when I am offline, I would rather generate tarballs after each signficant milestone.
Git is fast – I accept this and count this as a major plus.
If Subversion works for you, that’s lovely. And I agree that the command-line git learning curve is absurdly steep. Which is why I recommend using SmartGit (or SourceTree). These tools make git very approachable indeed.
Once you have given a tool like SmartGit a go, you might find the cost-benefit suddenly tilts very hard in git’s favour: you can work under full version control without a connection to the repo, you can branch and merge fluidly without worrying your co-workers will go insane or you’ll fill up the server, you can work on your project without having some dodgy plug-in, you’ll not have to suffer said plug-in get desperately confused when you move a folder without saying ‘simple simon said’ first, you’ll be delighted by the speed (as you said), be relived by one-click cleanup and you’ll enjoy not having your folder hierarchy polluted with hundreds of .svn files,
Subversion was the very first VC system I regarded as usable. It was bulletproof and effective. I loved it. But, now, those days seem dreadfully quaint. I will never swap back to working in such an antiquated fashion, it would make no more sense than starting to program in assembler. It’s not that assembler is “bad”, it is merely that the situations where it out-competes higher level languages are few and far between. Much the same is true of SVN and git.
I have tried sourceTree earlier in one of my projects. And I use GitExtensions personally. It did not make anything simpler.
I agree that SVN isnt perfect either. Maybe we all are still waiting for the perfect versioning system. I have not tried out any of the commercial tools like perforce or Team foundation though.
Do try SmartGit/Hg. It’s my tool of choice. SourceTree is free but I find SmartGit/Hg simpler and cleaner.
“Subversion was the very first VC system I regarded as usable.” Honestly? Perforce (commercial product) is close to identical to SVN except the merge tool in Perforce sucks. There have been good source control systems around for decades. Git is just a complex mess designed for two special use cases:
1. guy wants to develop locally and keep versioning without installing server software on his/her computer
2. MAINTAINER wants to lord it over anyone else contributing to that tree in Linux and enforce that all changes are really to be made by him/her.
Amazingly, people created Windows, Unix, and most all other major software before git was even dreamt. And they certainly used source control systems. Of course the systems costed north of $100k 25 years ago; but they did work. I guess the big brain break-through then was being able to to intra-file merges automatically. Well, git still sucks for that. Sucks big time. You’ll end up doing lots of those manually.
I didn’t think I’d defend Git here, but it wins clearly on quickly starting a small project and on projects surviving the disappearance of its maintainer.
And it is Free Software. That’s a huge enabler for many people. I clearly prefer Mercurial over Git, but even the difference in barrier to usage of complex, inconsistent Git compared to Subversion or any commercial product is striking.
People created high quality software by keeping backups as directory copies and exchanging plain diffs. Libre, decentralized version control just removes a lot of the error-prone manual steps in that.
Stop making critics and come up with a good solution. Post it and see if you get as many votes. I think git has provided a fair solution to many SVN/CVS/TFS/Perforce/RC problems. Bright minds don’t only see needs or defects, they also come up with solutions. What are your recommendations on simplifying the fundamental problems of source control? Please advice.
In the update (August 3, 2012) at the end of the article, Steve wrote a solution:
> 5. “Use Mercurial instead!” Sure, if you’re the lucky person who gets to choose the VCS used by your project.
The problems aren’t as fundamental as the git UI makes you think.
Mercurial also has its issues, but instead of still trying to fix Git after 3 years of failed tries since this article was written, let’s curtail the losses and fix Mercurial together.
You are right! I’,m using version control as backup and for “what have i done and maybe get it back”… (single developer)
git is different in my case sometimes more complex, so i’m using svn with a notebook server working with visual svn linked to nas. It works, is easy to use… that’s what i want.
I will never store my source on cloud anywhere (also not at github), why should i? My source resist at my ipfire shielded home… nowhere else…
This article is so accurate, however I think it is missing the biggest problem with Git – IDE support (have you tried EGit? Just search on StackOverflow).
I don’t want to hack a perl script from a file editor. No, I want to have access to diagrams, integrated test tools, user story correlation tools and search tools whilst I develop to make sure I do it right as quickly as possible. You need an IDE for that.
For us that write proper industrial-strength software for a living, I would suggest the tools required to use Git do not yet exist, so stick to SVN.
Yeah, it’s really nice when you can just sleep because someone else is doing all the work for you.
I guess the point is that none of this stuff is really necessary. What you need to get something done is a willingness to invest the effort. If you don’t have the will, none of the bells and whistles help the slightest bit. Fortunately, at this point there are millions and millions of programmers. So 80% of them can just whine and complain and the remaining 20% can still get a lot done.
(I actually have nothing against SVN, … nor against Mercurial, … nor against Git. I think they each have roles where they are best suited. But I *do* have a problem with the social thing where people overgeneralize these kinds of issues. If you’re bored there’s plenty of problems which need to be solved.)
Assuming you write software for a living as opposed to bedroom coding (is that why you are focussing on sleeping?), then maybe you ought to think about what you are being paid to do: Write Software. Not administer a version control system.
Then again some of us programmers are not blessed with the ability to focus on what matters…. maybe 20%?
“What you need to get something done is a willingness to invest the effort”
Sorry, I forgot to mention that I am not training for an ironman triathlon, I am trying to write good software quickly, which is what I was doing before I was told to use Git.
“problem […] where people overgeneralize these kinds of issues”
OK, let me be even less general…. I am trying to assert that when you are working on a large, complex product in a demanding environment, e.g. you have a browser client, a server with hardware access, and maintain a multitude of services for many diverse clients – which is what I meant by “industrial strength software” – it is difficult to do it well without a good IDE. From my experience one can’t have that and Git at the moment.
I have worked with IDEs and without. My best work was done without – but I don’t find it difficult to get work done in either way.
But frankly at this point, I have mostly ceased to care – largely because I have begun to recognize that no one else cares, either. They’ll offer strong opinions, mostly about stuff that doesn’t matter.
However… since you sort of asked: I write software because it pleases me and I enjoy that. But I don’t get paid to write software. I get paid to solve problems and to help other people get their jobs done.
Pingback: Git repo created | Cognitive Dissonance
I agree with this article. To use GIT safely you simply must learn it inside out to avoid screw ups and that is something I do not want to waste my time on but must.
Can anyone comment if Mercurial has less ways to ‘shoot yourself in the foot’ ? I understand the history is immutable.
So why not using aliases for git commands, if you like writing less text so much?
I just want to say, that when I use SVN and commit my changes to my branch in the remote repository; if my hard drive goes bad, nothing is lost.
If GIT is local and my hard drive goes wrong, I lost all my job.
Or your co-worker forgets to ‘push’ and just commits locally.
I think the point that @Daniel is making is that git has a marginally more complex model of code submission, as it distinguishes local check-in (commit) from shared check-in (push), whereas subversion only has shared check-in. However, this does not eliminate the need for a version that is local/private to a developer and, if you are working in subversion, you typically end up simulating this through branches that the team agree are private to developers. Having worked in both situations, the git solution is better in every respect. So, for a marginal increase in complexity, you get a tidier shared workspace, an improved workflow, plus the ability to work offline with no loss of functionality.
Although there are plenty of valid criticisms one can make against git, this is not one of them.
This is a particularly weak point, confusing version control with back-up. SVN can be used locally and the same issue arises. We have >100 SVN repositories used in this way. Our solution is to back-up our drives.
I think GIT is at best it’s moderately more complex. GIT gives you too much ability to shot your self in the foot. Fast forward `–force` push anyone – at lest Mercurial got this part right by making history immutable.
The more I learn GIT the less elegant it gets – but I do recognize it could be just a case of grass is greener on the other side.
Normally, no one will use SVN locally: the point of using SVN is to have the code secure in a different location – again, normally a more secure location than your local hard drive. If someone uses SVN locally, by definition is doing something risky, and sometimes, just wrong.
Backing up the drives is a lot more complex than having a SVN central repository in a secure place and do a click to perform the commit.
So I don’t think that this is a weak point: is just the way that SVN works, and the way that GIT works. Obviously, this GIT “weakness” can be compensated easily (and without the need of backing up hard drives): just ask to GIT users to Push their work more often.
@Santiago: “the point of using SVN is to have the code secure in a different location” – this gives a high priority to an incidental benefit. Surely the main point of using SVN is to control the evolution of code. The fact that it can be a low-tech recovery strategy may be, I agree, a benefit for solo developers if they haven’t got a backup strategy sorted out – which can be relevant while you are a student, for example. But you can’t use it exclusively as a disaster recovery solution and, unlike thirty years ago, there are so many really good “zero-config” solutions. I use Apple’s superb Time Machine for my personal work and my company uses a well-known distributed backup solution.
I think there is a general confusion with the term backup here. I’d like to split that into History and Disaster Recovery. When talking about DR you are absolutely correct. This is something that needs handled by some other means than a VCS. GIT acts like a time machine in that it can change history. This is something i fundamentally disagree with. A VCS should be able to give you the code as it was at any point in its history. History is essential to version control. I dont accept the “thats why you tag” argument.
Its essential to be able to audit/account everything that ever happened in your VCS.
On the other hand, if the server goes dead, at least with git you still have a local copy of everything. Less relevant in a corporate setting, but for open source it can be a lifesaver.
You have a local copy of many things, but most likely not the branches of you co-workers. That’s my main qualm with the very private branching system in Git: People forget pushing, or forget to push the relevant branch, or they only push to their clone and don’t file a pull-request, and so on. Then they close their Github Account and all their work on the project is lost – as in permanently lost.
Jan, I have more than 10 years working in IT, and I have never see a server goes dead and lost the repository. It may happen: yes; but it’s easier to lost a HD in a desktop or in a laptop that a corporative server.
Am I wrong to think of ‘Pull requests’ as a mechanism to bring some centralization back to GIT? The problem with them is they are part of the hosting provider not the control system.
You’re right with that. This meant for example, that it was necessary for workable interaction with scheme requests for implementation to provide alternate workflows. See http://permalink.gmane.org/gmane.lisp.scheme.srfi.announce/120
Pull requests are not a feature of Git, but rather of GitHub, which is a Git hosting service with additional features thrown in. In Git, there is no mechanism for issuing pull requests, although you can generate a pull request e-mail via the `git-request-pull` and then manually send it to the upstream maintainer.
Pull requests are not a feature of Git, but rather of GitHub, which is a Git hosting service with additional features thrown in. In Git, there is no mechanism for issuing pull requests, although you can generate a pull request e-mail via the `git-request-pull` and then manually send it to the upstream maintainer.
You are right. git pull is the ubiquitous way to merge in changes from other trees, basically from the central repo. You could do merge and stuff to effect bringing down the code if you don’t like the word “pull”
sfkleach: Since SVN was created before GIT, I would not say that Subversion is “simulating” a private version of the code. Is in fact, giving to the developer a private version of the code.
However, after have compared both tools, I couldn’t find a real benefit of using one over another; as usual, the best tool is the one that works better for your project.
In my specific case, I always work online and I don’t have the need of working offline. Also, I prefer to do only 1 click to perform a commit and know that the code is secure in my branch, that give 2 clicks.
Could you please tell me more about “tidier shared workspace” and “improved workflow”, I’m very interested in this subject.
Thank you.
So i’ve had a couple of attempts using online learning to get into GitHub and without a workgroup around me using it just end up giving it away. I’m the opposite of an expert although no a bit about UI/UX as a designer and can’t agree more. I still like the idea of learning GitHub because it’s become ubiquitous in open source world but the learning curve has steep early steps. I can understand why pro-devs don’t care, they don’t have to sell Git to anyone at all.
Oh shgit. More git shgit.
So, disk was getting low on space. What does git do? It totally shgits itself. Your GUID references become all fubar and git cannot recover. Couple of SO’s on it.
http://stackoverflow.com/questions/18480174/git-stash-fails-error-unable-to-resolve-reference-refs-stash-no-such-file-or/19409320#19409320
http://stackoverflow.com/questions/20663239/git-pull-fails-error-refs-stash-does-not-point-to-a-valid-object
In their case they were LUCKY. Git only messed up the stash references. In my case, git messed up the references back to head. I’ll have to re-clone and resetup. Another day wasted due to using git instead of a solid source control system (NEVER, EVER, EVER, EVER have seen such shgit with SVN, Perforce, or any other of a 1/2 dozen source control systems I have used heavily.) Out of disk space is a computer programming problem. Instead of just shoving shgit together the GIT programmers should have properly handled that error case. (I am running Android Studio; so, one might argue the bug is in that.) GIT? SNAFU.