My current work relies on using tags in CVS for an automated build process (ANT currently) to build for respective environments (development, QA, production). From our research, neither Git or Subversion support tagging in the same manner.

If we use Subversion or Git, they don't support tags (in the same manner - please correct me?). So how would ANT or Maven know what to pick up for the respective build?


For a webapp, when viewing our repository say for the web.xml file -- the history would look like:

web.xml  v1
web.xml  v1.2.3  Tag: Prod
web.xml  v1.2.4 
web.xml  v1.2.5  Tag: QA
web.xml  v1.2.6
web.xml  v1.2.7  Head

The ANT build scripts are run as CRON jobs, at different times & intervals for different environments. The environment build is based on the repository checkout, based on the tag.

Development continues, and eventually the respective tags are moved:

web.xml  v1
web.xml  v1.2.3  
web.xml  v1.2.4 
web.xml  v1.2.5  
web.xml  v1.2.6  Tag: Prod
web.xml  v1.2.7  Tag: QA
web.xml  v1.2.8  Head
  • Isn't the git tagging system a superset of the one that's available in CVS? Jan 21, 2011 at 21:01
  • @blueberryfields: Dunno, the info is secondhand to me.
    – OMG Ponies
    Jan 21, 2011 at 21:03
  • Could you describe your procedure in more detail. I would strongly suppose that whatever you do today can be done more efficient with git.
    – user1249
    Jan 21, 2011 at 22:47
  • @Thorbjørn Ravn Andersen: Hope the update is what you're looking for
    – OMG Ponies
    Jan 25, 2011 at 17:18
  • Am I right in assuming that you promote a build to QA and not individual files?
    – user1249
    Jan 31, 2011 at 23:09

3 Answers 3


There is one aspect that you may want to take into consideration. For CVS state is kept per file - for git state is kept for the whole repository.

This means that probing and updating operations are much, much faster in git than in CVS, and that made a huge difference for our Continuous Integration engine when we switched.

Also, I am pretty certain that whatever you do in CVS, can be modelled in other systems too, or adapted to work better.

EDIT: As requested, my comment about how to emulate this workflow with git: "You have one repository and you work on master (git lingo for HEAD). You then have a QA branch where you merge in from master as needed, and a PROD branch where you merge QA in as needed. You register the revision (SHA1) of the commit you work on with the build so you can reproduce as appropriate given a build id."

bzr and hg users, feel free to translate as appropriate.

  • And the per-repo vs per file state is great until your customer wants to see an unchanged repo but there is development in a section of the repo they don't see. Jan 31, 2011 at 21:31
  • @Tim, why would they want to see an unchanged repo?
    – user1249
    Jan 31, 2011 at 21:55
  • So they know that the only changes they are getting are the 3 they cherry-picked from the last year of development i.e. all the files ins the systems bar N have the same rev numbers as the last software issue. Jan 31, 2011 at 22:58
  • 1
    @Tim, strange requirement. I would assign them their own branch in git immediately.
    – user1249
    Jan 31, 2011 at 23:07

Both git and subversion support the concept of tags, but since they both allow you to reference the state of your whole code base at any time you don't depend on it. CVS let's you checkout code from a specific point in time too, so you could use a time reference for your bookkeeping instead of relying on tags.

There are other compelling reasons to upgrade from CVS though.

  • The dates will be different for each file that makes up a release. Based on the current setup, we need to retrieve particular versions of files that have an arbitrary relationship between them.
    – OMG Ponies
    Jan 21, 2011 at 21:21
  • @OMG I was pointing towards cvs co -D. You mean that checking out the e.g. latest from CVS wouldn't give you a reasonable, compilable version of your codebase? That sounds like a lot of headache in your current workflow at least. Jan 21, 2011 at 21:24
  • The past is the past - Not my call, it's not how I've used CVS in previous situations.
    – OMG Ponies
    Jan 21, 2011 at 21:28

Sounds like a profile or a classifier situation

Typically, the Maven release process involves tagging the source code that was used to build the artifact. For example, let's say you are building a WAR artifact. The release process essentially does the following:

  1. Verifies that the current build does not depend on any SNAPSHOT builds (since they could change at any moment and affect production code)
  2. Updates the pom.xml to provide a version number that represents the release (e.g. 0.0.1-SNAPSHOT becomes 0.0.1)
  3. Checks the updated pom.xml into version control and tags all source with the release version number (e.g. cvs/tags/0.0.1)
  4. Deploys the built artifact into the release repository so that teams can share it

In Subversion, this approach is fully supported through the normal tagging process. I can't comment on Git, I'm afraid.

And for our situation with special environments?

Typically, Maven encourages the use of a single released artifact that does not change as it moves through different environments (think external configuration through property files and/or JNDI). If a problem is found within a released artifact it is pushed back to the developers (who are now working on 0.0.2-SNAPSHOT) and 0.0.1 is effectively canned. The developers try again with 0.0.2 and so on. There are variations obviously, but that's a common approach.

If your artifacts need to be different for each environment then Maven can build a different artifact based on either a profile setting (very customisable) or a classifier. From the Maven documentation:

The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number. As a motivation for this element, consider for example a project that offers an artifact targeting JRE 1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the second one with jdk14 such that clients can choose which one to use.

Another common use case for classifiers is the need to attach secondary artifacts to the project's main artifact. If you browse the Maven central repository, you will notice that the classifiers sources and javadoc are used to deploy the project source code and API docs along with the packaged class files.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.