0

Despite the decentralized nature of Mercurial, we have a centralized server that we all push to and that does nightly builds, packaging, etc...

Here's what we want to achieve: One of the files that is source controlled contains the major+minor version numbers which ideally would have to be increased with every commit. Since centralized numbering is not possible on developer's machines, we were thinking of a precommit script on the main server that would write a new minor version number to that file for each commit that is pushed. The question is/are:

  • since it's precommit, can this file change be part of the same commit?
  • if not, can precommit cause another commit and how do you prevent it from cascading/recursing?
  • how would one do that?
  • is there a better solution?
Rok
  • 1,482
  • 3
  • 18
  • 37

2 Answers2

4

A "precommit" script is triggered only at commit time. By the time users are pushing to the "central" server they have already committed, and it's too late for a precommit hook to do anything at all. You can have changegroup and incoming hooks that are triggered to run on the "central" server when the developers push, but those can't modify the commits -- the commits are already committed/baked/done at that point, they can only react to them.

As a suggestion don't actually put the version string in the file -- having a file that changes with every commit just makes merging a pain. Instead do one or more of these:

  • have a CI server (like Jenkins) do builds on every push and use the Jenkins build number, which can be passed into your build script
  • use the Mercurial nodeid (hash) as part of your version string so you can always knew exactly what revision is in a build -- and don't put it in a file, just query for it in your build (or deploy) script
  • use a changegroup hook to automatically tag-on-push, which applies a pretty (possibly sequential) name to the commits (note, this pretty much doubles your number of commits since every tag is a commit)

Personally, I use something like this in my build script:

build.sh --version_string=$(hg log -r . --template '{latesttag}.{latesttagdistance}-{node|short}')

That gets me version strings that look like "1.0.3-5fd8ed67272e" which can be roughly read as "built from the changeset three commits since version 1.0 was tagged with nodeid 5fd8ed67272e", which is pretty darn good -- and it's never saved into a file it's either baked into the compile (for compiled languages) or written into a VERSION file when my deploy script uploads it to the server.

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • Hi Ryan,well we cannot get around having the version number inside a file issue since metadata inside that file is used to import database, track sequential module upgrades, etc. Moreover, we cannot use alphanumeric version identifier since the software we're using does not allow it, must be integers, X.Y.Z. – Rok Apr 16 '12 at 11:03
  • 1
    Right, but you're still better off building that file dynamically from what's in source control. For example, an `update` hook can automatically create an un-tracked file with exactly the string you need in it. That file wouldn't be stored in version control, but it would **always** be present in any checkout because you never have a working directory without `update` having been run. – Ry4an Brase Apr 16 '12 at 16:35
  • Great tip on the update hook. It'll help me on every repo (except the one with the issue that brought me to this page). – Daniel H Feb 06 '13 at 07:43
0

See this page in the Mercurial documentation for some comments and ideas about this issue. See also How to expand some version keywords in Mercurial? and the other SO answers referenced there.

Community
  • 1
  • 1
David Pope
  • 6,457
  • 2
  • 35
  • 45