Agile Zone is brought to you in partnership with:

I am a programmer and architect (the kind that writes code) with a focus on testing and open source; I maintain the PHPUnit_Selenium project. I believe programming is one of the hardest and most beautiful jobs in the world. Giorgio is a DZone MVB and is not an employee of DZone and has posted 638 posts at DZone. You can read more from them at their website. View Full User Profile

What you need to know about your version control system

10.06.2010
| 14440 views |
  • submit to reddit

Here's the picture: you have introduced a version control system such as Subversion or Git in your organization, and your programmers store their code in it and integrate the changesets of other in their work, using commands like svn add, svn up and svn commit. This is really a no-brainer: the Joel Test requires a version control system to be in place, and most of us would never work without.

After having taught the benefits of source control to the growing programmers in your workplace, the next question to ask yourself is: are we sure we're taking full advantage of the power of our shiny new system?

For example, yesterday a colleague of mine attached a patch to an email in our private mailing list. Events like this happen, but since we are recently switched to Git over Subversion, an upgrade which is not common in enterprises, this made me wonder if there was a better way to manage this hanging code.

It turns out there is: Git has very cheap branching and a private feature branch would solve the problem, even if the changeset sent initially via email break the build. It's perfectly acceptable to break a branch during development: the issue is that with Subversion we were discouraged from creating a branch, due to the slowness of the operation and the pain of subsequent merging.

Thus, here are a set of questions that should make you think about your version control policies and standards, a sort of version control subsection of the Joel Test. Feel free to add your rethorical questions and answers with your Subversion or Git gotchas: by no means this is a complete list (I'm always open to learn), but if you already know all the described practices, you're definitely in the upper segment of the programmers population.

Subversion

Do you tag?

Tags are read-only copies of your trunk, placed in the /tags folder of the repository. Creating tags for each release is mandatory: the alternative is writing down the revision number of the trunk at the time of the release. Tag have nice names instead, and everyone looking for your releases will instantly open /tags.

Do you ever branch for a major or minor release?

Subversion branches are whole lazy-copied duplicates of your trunk placed under the /branches directory of the repository. These branches are somewhat heavier to create than in the case of distributed VCS, but you really have no excuse for not managing a release branch.

Branches named 1.2 or 1.6 remain available for further bugfixing, or can be referred to by svn:externals properties. They're not normally merged back into trunk, which removes the pain of svn merge. I suggest having one branch for each line of development you support - for example the Doctrine ORM, when managed via Subversion, had the 1.0, 1.1 and 1.2 and 2.0 branches, with the first two slowly moving to an halt.

Do you ever send code via email?

All the non-illustrative code should be kept in the system for it to work. If you can't (it breaks the build for example), at least trac or some wiki can be used for temporary storage.

Does your repository include everything you need for your application to be built and deployed?

Libraries, frameworks, tools, and everything the application depends on must be included in the repository, either via svn:externals or via a periodical import. A frssh checkout on a new machine shouldn't take you more than a minute of configuration before you are able to run the test suite.

Do you use svn revert?

When you make a mistake, or insert print statements, don't waste time removing them one by one: svn diff and svn revert [-R] are at your service for resetting the working copy changeset.

Do you setup svn:externals?

Dependencies towards a component stored in a public Subversion repository (typically an open source project) can be pulled in via the svn:externals property. You'll remove a lot of code from your repository and you'll be sure that the vendore code is never modified, even slightly.

Do you write meaningful commit messages?

Needless to say, commit messages are a mean to tell information that is not already included in the commit log: there is no need to link the interested files, but surely the methods you have added or modified are a good target.

Git

Most of the questions (And answers) are still valid if you have transitioned to Git. But given the versatility of Git, even more questions come to mind.

Do you branch before developing a feature?

Branching is very cheap in Git, taking only seconds and a handful of bytes on disk. There is no reason to avoid using git branch (of if you prefer git checkout -b) for every single feature that takes more than one day to complete.

Do you commit very often?

One of the advantages of Git over Subversion is that commits are local, and until git push is run, they do not affect the origin repository. You can commit every time you want.

Do you favor atomic and short commits?

Small and cohesive commits are easily revertable, and can be harnessed to generate a change log. Read git diff and git status and never forget to commit a green bar if it contains an advancement over HEAD.

Do you use the index?

One of Git's most enviable features is its index, which allows you to select the single filed and directories you want to include in a commit. Basically, unless you execute git add, a created or modified file won't be committed. This leaves open the possibility of atomic commits even if you have already modified too much files. You can reset the index (but not your modifications) by running git reset (which by defaults is --mixed.)

Do you send patches via email?

The whole point of version control systems is to maintain all the code in one place, and provide a management system over it. While with centralized VCS code is sometimes kept out of the loop, you have no excuses while using Git (or Mercurial): creating a simple branch with your modifications and push it is a matter of seconds.

In the open source world, Github has substituted the need for uploading patches into a bug tracker, leaving it available only for discussions between humans. You can post code in the repository too, for ease of merging.

Do you use Git for local folders or projects or just when you need to publish code?

There is no need for an external repository, only of an hidden .git folder inside your main code directory: versioning /etc is becoming a common practice. You can version your personal projects with an overhead of two commands and be covered for httpd.conf simplifications that surprisingly break the web server.

Do you use reset --hard and checkout?

git reset --hard will take you to the situation, throwing away all the modifications (like svn revert -R .). git checkout $file will extract the single $file overwriting the current working copy one with its original content from HEAD.

Do you run commands from wherever in the repository?

The majority of git commands, such as git status, git reset and git commit, act by default on the whole working copy, even if you run it from an obscure tests/Zend/Filter subfolder. This prevents incomplete commits: for instance, the ones where you commit only tests/ without the relative production code. It's also faster than relocating to the main directory if you don't need it.

Do you use git log to filter commits or only HEAD^^ or HEAD~5?

git log executed on a file or folder shows the commits that have affected it. You can then generate a diff by using the first 4-6 characters of the commit hash, as long as they are unique (for example, git diff 39446 3ad42 to generate the diff between 394469d4b7b9d9442ab15fdd0e4e81c186cd2fc5 and 3ad429a5aac5a5090e0c9e6e316e0225e0edb9b0).

Do you use colors?

git config --global color.ui auto will set all the options for colorizing git's output, with red and green colors included in diff generation and index visualization (git status). It's quite helpful, like xUnit colored bars.

I hope you're already learning as much as possible on your version control system, which is one of the best friends a developer has, beside his pairing partners. Mastering the single commands leads to an improved workflow, and a facility of usage that will give you the confidence to do the right thing even when the command seems a little scary at first.

Published at DZone with permission of Giorgio Sironi, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Heikki Rauhala replied on Wed, 2010/10/06 - 5:04am

Do you send patches via email?

The whole point of version control systems is to maintain all the code in one place, and provide a management system over it.

I would argue that one of the key points of a DVCS is that you do not have a single place to maintain all code, instead the DVCS's acknowledge that an edited working copy is a topic branch regardless of whether you can make commits to it (as in git) or not (as in svn).

One of the key features of Git is that it facilitates working with distributed commits that can be transported for example as patches. There's a whole set of tools for working with patches in Git and even a specific tool for sending them in emails. Patches created and applied with these tools are just like pushed/pulled commits, they just use a different medium for transport.

Vassil Dichev replied on Wed, 2010/10/06 - 6:17am

git reset is --mixed by default, not --soft:

 

http://linux.die.net/man/1/git-reset

Liran Mendelovich replied on Wed, 2010/10/06 - 6:18am

There is also Mercurial as known, pretty much like Git.

Giorgio Sironi replied on Wed, 2010/10/06 - 6:25am in response to: Heikki Rauhala

I did not express myself correctly; I intended keeping the code in the same infrastructure, instead of multiple source control systems: emails, trac, wiki, single source files and Git. I work every day with Git disconnected from origin, but I never feel the need for sending my changesets via email for manual application. :)

Giorgio Sironi replied on Wed, 2010/10/06 - 6:26am in response to: Liran Mendelovich

I do not have experience with Mercurial so I cannot report on it, feel free to add your points or link to some resources.

Giorgio Sironi replied on Wed, 2010/10/06 - 6:29am in response to: Vassil Dichev

Fixed, thanks. The behavior described was in fact the one of git reset --mixed.

Liran Mendelovich replied on Wed, 2010/10/06 - 6:56am in response to: Giorgio Sironi

"I do not have experience with Mercurial so I cannot report on it, feel free to add your points or link to some resources."

I wrote about Mercurial, but just for start with it, not about the branches and other options.
From there, it's good to commit a lot, every time you want or need' like you wrote.
Here is the link:
http://java.dzone.com/articles/mercurial-guide

Sam S replied on Wed, 2010/10/06 - 12:31pm

A very good Mercurial tutorial is http://hginit.com/ by Joel Spolsky.

Giorgio Sironi replied on Wed, 2010/10/06 - 2:09pm in response to: Liran Mendelovich

I guess for all DVCS is the same: you are free to commit at the time of your choosing, since you're not integrating your changes with the trunk/master at the same time.

Otengi Miloskov replied on Wed, 2010/10/06 - 3:21pm

Where is Mercurial?, I use Mercurial, It is the more easy DVCS around.

Michael Hönnig replied on Thu, 2010/10/07 - 12:46am

svn:externals is evil.  Moving the external repository will break all your revisions.  I don't consider this a proper configuration management.

Giorgio Sironi replied on Thu, 2010/10/07 - 2:51am

svn:externals is used successfully when depending on public open source projects. It prevents the developers from trying to modify the vendor source code more than an import with svn add.

Mladen Girazovski replied on Thu, 2010/10/07 - 7:33am

Does your repository include everything you need for your application to be built and deployed?

Libraries, frameworks, tools, and everything the application depends on must be included in the repository, either via svn:externals or via a periodical import. A frssh checkout on a new machine shouldn't take you more than a minute of configuration before you are able to run the test suite.

Actually, this is a bad practice, at least in Java.

A Source Control/Versioning System is not supposed to store compiled libraries.

For that purpose there are build tools with dependency management features, for Java there is Maven2, Ant + Ivy, Gradle, Buckminster etc. pp.

 

 

Giorgio Sironi replied on Fri, 2010/10/08 - 2:57am in response to: Mladen Girazovski

Thanks for you point of view. I work mostly in PHP where the libraries are shipped as source code (interpreted language). Importing them gives us the possibility of doing a simple diff to see what is changed during upgrades.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.