Git (and a rant on subversion)
Git (and a rant on subversion)
- Subject: Git (and a rant on subversion)
- From: Jonathan deWerd <email@hidden>
- Date: Tue, 3 Jul 2007 22:30:34 -0600
I briefly mentioned this in the thread about ObjC3D (which, by the
way, is now up at http://sourceforge.net/projects/objc3d). I thought
I would make a separate thread so it got the discussion it deserved.
Many of you are probably familiar with subversion. Some of you might
actually use it. I did too, until another SCM system named git was
mentioned to me by a friend. I started liking it almost from the very
start, and my opinion of it quickly soared past my opinion of
subversion.
I will start with some of my gripes with subversion.
1) Branching and merging. Ack! It's horrific! Branching is easy, but
merging is a nightmare. Sure, there are some utilities that are
supposed to help you, but the reality is that merging is still
painful (or at least has a steep learning curve). You still need to
initialize merge tracking and manually mess with something that
should be fairly automatic. I avoided branching (because of merging)
like the plague when possible.
2) No offline support. Say I don't have an internet connection but I
have reached a logical point for a commit. What do I do? Nothing. I
have to wait, make a manual copy in the finder, or just continue
programming without the safety of a revert as fallback.
3) No sort of local branch support. This problem is so bad that apple
hacked around it in XCode 3 with snapshots. Any SCM system should be
able to make local branches, commits, etc. on your own system, so
that you can take full advantage of SCM for development as well as
master-copy-management.
4) You need to set up a server, even for local projects. There is a
project (svk) that aim to try to fix this, but judging from my
experience with building subversion for its bindings they it is
probably more difficult, slower, and less feature-reach than git.
5) No history editing to speak of. What if I botched the last commit
and I need to go back and fix something? Too bad! What if I bugfixed
on a development branch and I want to add those fixes to the trunk
and a few tags as well? Sucks to be me.
6) It's slow. I didn't realize this until I experienced git. Git can
check out an entire repository, history and all, in a fraction of the
time it takes svn to check out the head.
7) Using the command line to rename, delete, or move files sucks. SVN
is also prone to serious barfing if you do something "stupid" like
copy a folder from one working copy to another.
8) You must perform voodoo to import an existing project (see above.
You need to set up your own server, make a repository, and import
into it.)
Actually, svn is so cumbersome that many users simply stick to
zipping their project folder.
Git fixes all of that, and it adds an elegant (but different)
development model. In git, there is no central repository! This may
come as a shock to svn users. The implications of this are profound.
Actually, contrary to what you may be thinking, git's style is much
more natural. This is how it works:
To create a repository, simply create a repository folder. No
server, no nothing. You just initialize version control on a project
folder. Behind the scenes, git makes a .git folder in the specified
folder. There is no .git in subdirectories, so you can copy them
willy-nilly (try this in svn for some fun). That's all! The project
folder simply becomes your working copy (and your "server" and your
repository all in one)!
To share a project, the person doing the sharing needs to set up a
git-daemon server (which is very painless compared to svn, you really
only need git-daemon, which comes with git) or a file server
("Personal File Sharing" works great). The person on the receiving
end then clones the sender's repository and works on their copy. They
can then pull changes from the sender's repository when it changes
and they can send patches or push their modifications when they have
something to contribute. Meanwhile they can use as much local version
control goodness as they please, weather they are online or offline.
This leads to a network-of-trust setup. If Alice trusts Bob who
trusts Charlie, then Alice implicitly trusts Charlie. This can be
cumbersome for big projects, however, and repository access can
easily get out of control. With git, Charlie would send changes to
Bob who would in turn send those changes to Alice. A nice side effect
of git's insanely easy branching and merging is that you are likely
to actually use it. If you use branching and patches, a very natural
workflow ensues (Charlie invents a new feature Foo, which Bob likes
so he takes it (all wrapped in a neat branch). Alice likes Bob's
featureset so she takes it, and so Foo gets into Alice's copy without
Charlie having to bug Alice about Foo directly).
You may be thinking that checking out an entire repository is
inefficient and slow. All I have to say is: just try it. You will be
astounded. I didn't believe it actually happened the first time I
tried and git checked out a 300 commit repo it about a fifth the time
it took svn to check out the head. You may also think that it is
insecure: what if an evildoer wanted to change something way back in
history or smear another person's reputation by putting bad code in
their name? This is a non-issue: git uses hashes to identify
everything. Rather than a version number like svn, each commit
actually uses it's hash to identify it. Cryptographic signing is also
involved with commits (to go back to the example above, Alice's repo
would show feature Foo as created by Charlie and signed off by Bob).
In short, it beats subversion's global permissions by a mile.
Have I convinced you to try git? Build instructions (don't fear, it's
the most simple and painless build I have yet to encounter) follow:
0) Read the replies to this message to make sure there are no issues
with these instructions!
0) Regular disclaimer rules apply: know what this does before you run
it and I am not responsible if it kills your system even though it
shouldn't. Do not run this on a critical system or a system that is
otherwise fragile with libexpat and/or things in /usr/local.
1) Download and decompress expat from http://sourceforge.net/project/
showfiles.php?
group_id=10127&package_id=10780&release_id=513851 . Assuming you
decompressed to the desktop (if not drag the resulting folder to the
desktop) run this in terminal without quotes: "cd ~/Desktop/
expat-2.0.1; ./configure; make; sudo make install". The last part
needs your password.
2) Grab the latest tarball of git from http://www.kernel.org/pub/
software/scm/git/ . As of writing that would be http://www.kernel.org/
pub/software/scm/git/git-1.5.2.tar.gz . Also grab the latest htmldocs
or manpages if you want them (it's all available online anyways, but
sometimes man is handier than google). Decompress it and put the
resulting folder on your desktop. Then run this command in terminal
(substituting the name of the folder you downloaded if it is not
1.5.2): "cd ~/Desktop/git-1.5.2; make prefix=/usr/local; sudo make
prefix=/usr/local install; echo 'export PATH=$PATH:/usr/local/bin' >>
~/.bash_profile; exit;".
3) Typing "git" in a new terminal window should display a list of
commands.
Further Reading:
http://git.or.cz/course/svn.html
google
Caveat:
The only caveat is that xcode doesn't have git integration. This is
probably acceptable, seeing as its subversion integration pretty much
sucks as well.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden