It was really hard to keep reading after this line. It's like saying painting your bedroom red will make you better at sex. It's like saying getting a gas-powered golf cart will make you better at golf. It's like saying changing your mouse to be inverted on the Y-axis will make you better at computer games. All of these things change the experience, but they don't make you inherently better at anything. Just like branching during development.
Most of it is about what is discussed when walking between holes; to that end, a golf cart would be detrimental to the 'purpose'.
Of course advice to "just use branches" is not going to make up for core deficits in your programming knowledge. But in my experience a lot of the trouble we get into on software teams is due to workflow problems and misunderstandings rather than "bad programming".
Merge commits can also hide lots of information, like exactly how any merge conflicts were resolved, since they're buried in what is basically a squashed commit of everything in the merged branch since it diverged.
And finally, they make the commit history much harder to understand. I had to bug everyone on my team to run "git config --global pull.rebase true" just to have a somewhat sane, linear history without tons of merges in day-to-day development.
I agree with this, but disagree that avoiding branching is a good way to do it. In my experience, the solution is more, smaller, feature-specific branches that get merged back to master quickly (within a couple of days if possible). If you need to maintain a long-running feature branch, it should frequently be rebased on top of master so that at any given point the likelihood of major conflicts is reduced.
At least, that's how I code. I generally just jam code in down different paths, often refactoring whatever I'm doing when a new understanding of something comes along, but often this results in another incorrect branch and I need to back up to 'semi-working' code.
I had the experience that having to switch back to SVN made my workflow significantly worse, lowering my productivity a tiny bit and thereby making me a slightly worse programmer overall.
The importance and convenience of cheap local branches is nothing that will be known to someone who hasn't used them. If you are used to them, using a system without them makes you feel you are doing the job that the tool should do.
I can do with only a single branch if necessary, but how the f*ck are you supposed to develop anything locally and roll back changes in subversion if you are never allowed to commit because it might break someone else's stuff?
I think there are other svn-alikes that might solve this problem (svk?), but with pure subversion it is the biggest roadblock for me (and I bet, a lot of other new coders).
In the old days, before git existed, we used to have a space in the repo for each developer. You could put whatever you wanted in there. So if you wanted to go off on a tangent you just copied the code via svn, switched to that copy, do your work, commit as you please. When you were happy you could cherrypick / merge into the main branches of the code.
Git makes this stuff easier, but it was all possible with svn. Hell, it was probably even possible with cvs if you jumped through the right hoops.
As to the features mentioned in the article, I agree in principal, and someday I'll even learn git well enough to be feel like trying to use them isn't a huge, mental drain from the focus of my actual work :-)
Nevertheless, branches are really just a (albeit nice) side-effect of the fact that Git (and Mercurial, for that matter) explicitly tracks _changesets_, not just _revisions_.
Do you have a counter-example?
Besides Git, Mercurial and BitKeeper, there is also Monotone, which is also a DVCS.
Also try looking into the history of the DaggyFixes idea (that a bug fix should be committed against the earliest revision to contain the bug and then merge into the active branches, rather than committed against current head).
Now, if we look at Subversion, we see that given a particular revision there's no way to reliably determine its' "parent", because the fact that r6 is followed by r7 doesn't mean that changes in r7 were based off of r6.
If we look at any DVCS, each commit would have an explicit reference to its' parent(s), so there's always a non-ambiguous way to reconstruct the entire "chain" of relationships between commits.
Crazy idea.
Where I work we use master as the release-production-ready code. We branch of version branches from there. So a 2.5 release will be based off of master.
We work off of develop, and branch out topical branches from there, once complete merge to develop, test, once approved merge develop towards master.
And so on and so forth. It's very clean and makes it easy to test out other developer's feature as everything is encapsulated in a branch.
Branches are good for isolating longer-running changes but the merges are often not small. The longer the branch the more chance the merge will introduce subtle bugs. And the merge has so many lines change, where do you begin to see where the bug is once you've combined branch A and B?
I've had a coworker argue that NOT having long lived branches avoids this. And he said at Microsoft they were just fine with mainline - and as soon as they started branching the trouble always started during the merge.
So what about that?
I've found this to be very useful with large refactorings. It eases the pressure of having to stabilize everything before a release. If the refactoring isn't ready for this release, don't merge it back in.
However, don't believe me ;-) I recommend you download the free trial from our website and see for yourself.
Also I miss the deterministic nature of SVN Revert, when I run that in SVN it really makes my working directory exactly as it was that morning before I started typing. With Git, well with EGit this isn't too hard, Team | Reset | Hard | References | ORIG_HEAD. It works for me.
My first attempt at "revision control" was multiple copies of files: "main.cpp", "main_2.cpp", "main_2final.cpp", "main_2finalb.cpp", "main_2finalb_forreal.cpp", and so on.
This scheme clearly doesn't work.
So, in highschool, we started using SVN. We used it less for its versioning abilities than we did for its ability to function like a distributed file share (this was before Dropbox, which sucks rocks anyways). We stored lots of binary files in it (images, models, etc.), and sadness resulted, but it beat the hell out of the alternative.
In college, my SVN-foo upgraded--we used SVN properly: updating, resolving conflicts, and committing changes. It worked well enough, though it still sucked for binary stuff--and merging conflicts was a pain in the neck.
After college, we started using SVN more cleverly. We started limiting our commits to functional changes, and documenting very carefully what changed and why. We tagged branches for release, and kept the repo clean. We moved binaries off into their own repo.
At my first gig, we used SVN with Eclipse, which was pretty awesome. It had great merge functionality, it had great team support, and I even learned how to branch from mainline development in order to do my own projects. I did not learn, however, how to merge said branches back in any way which did not involve madness and suffering. Oh, and people would sometimes break the build, and if you were lucky you read that email (if they sent it!) before you updated in the morning.
My first few encounters with git were again using it as a distributed file share, this time hosted on Github--from hackathons and the like. I did not receive a very good explanation of it other than "that's what we're using for this project"; I suspect that unless you are really careful it is hard to explain to somebody new to git how to use it if you have experience yourself.
I later learned to use git to have multiple repos to push to, one for code, one for staging, and one for production. It was the most magical thing in the world--`git push production master` and then Heroku is showing my new website.
I finally learned branching and merging when doing my startup earlier this year; I'd heard about doing topic/feature branches, and we developed a workflow somewhat like GitFlow. I learned how that worked, and barring the occasional screwup found it very, very useful.
I'm currently implementing a helper tool for CI and issue tracking with GitFlow-style workflows. I've had to learn more about how to use the tool, how to manage branches, and all other things.
~
git is a much more complicated tool to use, effectively, than SVN--at the same time, I think that getting there is worth it.
I further think that people starting out learning a VCS would be well-served to use SVN; combine it with TortoiseSVN on Windows and it's pretty simple. `svn update`, `svn commit`.
That done, when you have a workflow where it makes sense, switch to git. Git shines for letting you rapidly test things out, and keeping you from stepping on other people's toes.
I have used SVN for remote team work, and for certain things it's great--library development, things where you need people not to sit on commits easily, etc. I think that SVN is a great tool for newer developers, and I think that it has uses to this day.
That said, once everyone is up to speed on basic git, your team should make the transition, because it enables you to have more complex workflows and do more powerful work.