Sunday, March 8, 2009

why should a human being use git?

we started using git instead of subversion at our company a while ago. and i had to defend git against though opposite ideas occasionally, but i can't say i was too successful. so i decided to write my advocacy on paper, maybe i can be more convincing in this way.

actually, "why is git better than other version control systems?" question is answered at here very well.

i can summarize my own motives to prefer, as:

* it allows you to commit some part of your work.
* you will love interactive mode with 'git add -p' command.
* it makes it usual to work on branches.
* it's possible to edit past like merging/splitting previos commits, editing previos commit logs.
* there is no difference between main repository and clonned repository, actually there is no main repository.
* you can make commits with other people's name.
* "git-am" is really making easy to share commits with email.

bekir had told once, during migration from rcs to svn at parkyeri people had reacted as "what now? do the revision of whole repository will change when a file is changed". by migrating to git now, file only commits feature came back, and even more, we are able to do commit by hunk as well.

we can say, there are 3 phases of git commits. first commit is with "git add" to index stage, then second with "git commit" to record changes to branch you work on; and at the end if there is a main repository, it's time for "git push", if there is a main branch, it's time for "git merge".

people may find this unnecessarily complicated, because it was very easy with "svn commit" at old times. first of all, the job done with "svn commit" and in these 3 stages of git is definately not equal. before git, whenever i do a long period development (for ex: one week), i would prefer to use rcs to keep my local history of uncompleted work, and was doing final commit to svn when my work is finished completely. otherwise my patch was becoming too big, and it was becoming impossible to review. using rcs for local history was solving this problem for me, but it was also bringing some new problems as well. git became a perfect medicine for me, i think they had solved local history issue very clean. now during development whenever i got an idea that i'm not so sure with the end, i'm just committing all stuff i want to keep at this point to index stage with "git add", then i'm feeling free to do whatever i want on code without any fear. when i realise i'm not on the right way, i'm just returning back to clean point at index stage with "git co ." command. and if i'm supposed to do a three-day job, at the end of every day i'm reviewing what i've done with "git add -p", committing permanent changes to index. in this way instead of a big review at the end of three days, i can do it day by day and i'm reducing possibility to miss some problem during review.

interactive commit mode with "git add -p" is really making your life easier. it prompts every change hunk by hunk, and asking if you accept it or not. by this way, i'm reviewing every change i've done, and adding permanent ones to index, if i see any thing to be fixed before committing, i'm doing the changes at background, when interactive mode ends i'm repeating this process to commit changes i've done at background until all permanent codes are committed, then i'm shooting rubbish with "git co ." command.

some may ask "why you didn't use use svn branches instead of a mix usage of svn-rcs for local history problem? isn't it more reasonable?". believe me i tried, and i can say using branches in svn is not as practical as mentioned in documentations. first of all, why am i opening a branch? to be able to do things i can't do in trunk, right? and what can't i do in trunk? for example i won't prefer to commit something that is experimental, and i won't prefer to move on with one line commits in order not to mess commit log. and i'm now able to do whatever i want in my branch, very nice, but what about merging your changes into trunk? personally i was taking a big diff between the point i forked my branch and the last point i came with it, and i was applying this patch into trunk. by this way i wasn't carrying garbage codes and one line commits to trunk, but i was losing connection between my branch and trunk. i wasn't using "svn merge" command, in other words i was not really using svn branch. the only difference between opening a branch and working with svn-rcs mix usage was publishing my changes for other people. actually i can't say i was never using "svn merge", i was just using it in one direction, for getting changes from trunk to my branch, and i'm remembering i was never sure if X is included or not when i say "svn merge -rX:Y ..." :). after committing everything i've done in my branch to trunk, synchronizing my branch with trunk's new state was another problem. for this, i was returning back to forking point in my branch, i was merging changes done between this point and head in trunk to my branch. it was really becoming troublesome and i gave up using svn branches in a short time and went on with svn-rcs mix usage.

ok, it seems hard to work with branches on svn, isn't it hard with git? actually not, because all the system is designed on branches for git, that's why all branch operations become regular, and all the stuff you try to stay away in svn turns into reflexes in a short time at git. and also "git rebase" command solves many problems. for example, you forked a branch and went on hacking, meanwhile people keeps developing on base branch, only thing you need to do is "git rebase MAINBRANCH" in order to get the further changes to your new branch. and also, now you can feel free to do whatever you want at your new branch, because in git it's possible to change past, you can join your one line commits into a big commit or you can edit a past commit log or you can transfer a specific change to your branch from any branch and from any time with "git cherry-pick" command.

for svn, to be able to change the past you need a command like svnadmin and some privalages, for git there is no main repository, so when you clone a repository, you're really clonning it, you're able to run any command that you can run on the base repository you clonned from. you don't need to send an email to system admins to change something for you.

and "git am" really rules. we were used to do code reviews with emails at parkyeri. when someone comletes the development s/he would send an email labeled with "[PATCH]" keyword on subject and with patch attached, if someone says it's ok to apply, then patch sender would commit. if someone doesn't like it, patch sender would do the related changes and sends a new email. i think this procedure should be better in this way: developer sends patch, the other developer gets it and applies to his/her own repository, sees it works really, does the changes s/he wants and commits it. in this way we may get rid of situations in which same patch is sent 8 times because of small changes. and also to do code review by overlooking from email post is not a good method. when you apply the patch in your repository, you'll find yourself testing the changes as well. so you'll be more likely to catch problems that you can't by overlooking the patch from email. but in this procedure, for svn there is a serious drawback as losing code ownership because you're not able to do commit with another man's name, but for git you can commit with any user info you want. and especially git makes it very easy to share commits with email by "git am" command. it becomes possible to apply a patch sent with email to your repository and to prepare a patch email from your commits at your local branch with one command.

in conclusion, i think git is a well-designed tool, and solved many personal problems i did have. git provides the feautures that other version control systems does provide and beyond. that's why a person who uses git can use any other version control systems, but it's hard to say vice versa. therefore people who are used to common version control systems finds it strange and unneccessarily complicated. i think even if we accept that it's more complicated, it's not unnecessarily! i had produced much more complicated solutions that git solves in a very clean way. and actually i don't agree that it's complicated, it's just different in some way, and after you got used to it, it's not making you more or less exhausted than other version control systems for daily usage.

i think git is the right choice.

No comments: