Git Immersion
gitimmersion.com
gitimmersion.com
So, is there a concise explanation somewhere of what makes git better than subversion?
Branching & merging are also insanely easy to do, so I find that I develop almost all new features in their own branch, and I can easily just throw them away if I want, I never did this with subversion.
The kicker with Git is that all these branch operations take on the order of milliseconds because Git stores the entire project history -- all past revisions of files, etc -- locally. Sure, you pay in a bit of disk space, but consequently almost all common operations can be done without hitting the network and are crazy fast. Even when you execute a commit, you're not committing to a server, but to your working copy of the repository. Later, you can push your changes somewhere else and merge accordingly.
Obviously, if you add a 1GB random file then delete it, the git entire history will have 1GB more data than an SVN checkout. but usually, it's smaller.
I've switched to using gitsvn exclusively for svn projects I'm involved with since I noticed that -- I save space and have complete project history locally. What more could you ask for?
(p.s: git svn is a better svn client than svn. really)
Here's an example scenario I described in my blog an year back. http://tuxychandru.blogspot.com/2010/01/how-git-shines-above...
|
| file p.txt contains "X"
|
+<---(branch)--------+
| |
* file p.txt renamed |
| to f/p.txt, which |
| contains "X" |
| * the content of file p.txt is updated to
| | contain "Y"
| |
| |
+----(merge)-------->+ file p.txt is deleted and file f/p.txt is created
| with the content "X"
|
| BUT expected/wanted content is: "Y" (or at least a conflict)
VEffective branching is the killer feature of git or any source control system, to me. And in that regard:
svn < mercurial < git
svn: Three way merges are close to impossible. When you do a three way merge of a file you need to find the common ancestor of all three versions. This is just an incredibly difficult problem in svn that to my knowledge can't be solved in a way thats durable. In mercurial and git you can simply walk the graph to the common ancestor.
mercurial: Somewhat fails at the concept of a short lived local branch. You can't create a local branch in place--without cloning the entire repository to a different folder--to try out some feature and then delete the branch if it doesn't work out. At least not without using bookmarks or extensions: mq, localbranch. With these you get a bookmark, a patch queue, or an in-repository clone, respectively. None of these are branches in the fundamental sense.
git: You can get a short lived local branch, a long lived one, a release branch, a bug fix branch, a feature branch, branch, branch, branch. In git branching just works, and that, to me, if compared to mercurial, means specifically working local branches that are not fundamentally different to the rest of the repository.
Offline commits also make it easy to switch contexts quickly: to go from adding a new feature to fixing a bug you just noticed.
Fast because every clone is a local copy of the complete repository with all commits and branches.
Small because of the way it stores it's diffs.
Subversion tends to be really slow when doing branching, merging and getting commit logs because it always needs to communicate with the remote server to transfer files and data.
Subversion checkouts seem to be really huge because it will have a version of the latest head and a version of what you are currently working on.
That being said, I've witnessed the main gains of git after using it for a while. It is no longer a chore to branch and merge, it's instantaneous. It takes no time to commit. There is no penalty to committing -- my commits don't make it to everyone else until I'm ready to send my commits. This means that in a git environment I find myself committing, branching and merging more often.
Over time, you find that the increased number of commits and branches helps you to collaborate with others in ways that you just weren't used to thinking about in subversion.
If you are always working on things very linearly and are never context switching (and your peers aren't context switching), then you will notice no change with git. However, I have never worked at a place where this is the case.
To sum up, git solves what Ryan Tomayko calls "The Tangled Working Copy Problem" with amazing ease. If you have a working copy filled with changes, git add --patch lets you pick and chose which files, and even which changes within a file, to commit. It's obviously possible to do this manually with svn (or even cvs) but git just makes it so easy.
But to pull a page from Linus's playbook, since no one mentioned it: git fsck. No other SCM I am aware of can fix itself in the event of a small corruption. I have on rare occasion had to deal with these corruptions on network shares, and a "git fsck" brought me back to life in a jiffy. This is really useful for recovering work on your unshared local branches.
You're working on something in SVN. You've made progress that you'd hate to lose, but it's not great yet. Which do you do?
1) Don't commit until it's great. This prevents bugs from hurting your colleagues, but puts you at risk of losing work or being unable to undo mistakes - in other words, it's just like not having version control.
2) Commit a lot. Opposite problem - your teammates get your bugs.
Distributed version control lets you have both benefits: commit locally as often as you want, and push it up when it's good.
(I think I stole this explanation from Joel Spolsky. Whoever said it, it was what made me realize I should learn a distributed VCS.)
P.S. If your answer to the dilemma above was "use a branch until you're ready," well, OK, but branching in SVN is painful and slow, requiring making a copy of every file in the repo.
So far I only heared that git does not handle large binary files well and supposedly it is good to keep your large source tree (larger than the Linux-kernel !?) into many smaller git-repositories.
And you have to learn something new and unlearn bad habbits.
The no-easy-GUI-problem has been solved, right ?
A major problem with git is that if you try to use it without realizing its fundamental model is different, it will seem awkward and complicated. Don't think about it as "like svn, but distributed"; start from zero.
When I added this alias to my gitconfig I found an old alias I had for a pretty log, you may like it. http://www.jukie.net/bart/blog/pimping-out-git-log