tech-repository archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

tagging releases [was Re: scm migration: htdocs conversion]

On Tue, Jul 18, 2023 at 09:25:20AM +0200, Thomas Klausner wrote:
> Adding release tags will (sadly) be a manual task we'll have to do
> after the migration, when the repository conversion is final.
> The actual tagging will be easy:
>     hg tag -r $REVISION -d $DATE -u $COMMITTER $TAG_NAME
> The work will be finding the values for $REVISION, $DATE, $COMMITTER,
> If you have any ideas how to automate this, please let me know!

Based on an idea proposed by martin (using a cvs checkout, cvslatest
to find the last commit timestamp, and then hg log to get the matching
commit), I came up with the attached script.

It's slow (does a complete cvs checkout) and not perfect since it
fails in some cases (I think when there are commits with different
file time stamps), but sometimes it works!


Not working:

./ -c /path/to/cvsroot -H /path/to/hgroot -r othersrc tnftp-20030228
no Mercurial commit found for CVS tag tnftp-20030228 corresponding to time stamp 2003-02-28 10:04:47 +0000


./ -c /path/to/cvsroot -H /path/to/hgroot -r othersrc tnftp-20050514
hg tag -r 245771a05ff81e0cf104f3ba0a3540db105957e2 -u "Luke Mewburn <>" -d "2005-05-14 04:46:26 +0000" tnftp-20050514

If you run that 'hg tag' you'll get the following commit:

changeset:   2487:a8bea5167654
tag:         tip
user:        Luke Mewburn <>
date:        Sat May 14 04:46:26 2005 +0000
summary:     Added tag tnftp-20050514 for changeset 245771a05ff8

Thanks, Martin!

Next we need to find a list of tags for a repository (that are not
already branches).
#!/usr/bin/env python3

import argparse
import subprocess
import tempfile

parser = argparse.ArgumentParser(description='Find Mercurial commit to a CVS tag')
parser.add_argument('-c', dest='cvsroot',
                    help='CVSROOT to use')
parser.add_argument('-H', dest='hgroot',
                    help='where to look for Mercurial repositories ("path/repo.hg")')
parser.add_argument('-r', dest='repository', default='othersrc',
                    help='repository in which to look for the tag')
parser.add_argument('tag', help='tag to look for')
args = parser.parse_args()

with tempfile.TemporaryDirectory() as tmpdirname:
    cvs_command = ['cvs', '-d', args.cvsroot, 'co', '-r', args.tag,
                   args.repository], capture_output=True, check=True,
    cvs_latest_command = ['cvslatest', tmpdirname + '/' + args.repository]
    date_process =, capture_output=True,
                                  check=True, text=True)
    date_command = ['date', '-u', '-r', date_process.stdout.strip(),
                    '+%Y-%m-%d %H:%M:%S']
    human_date_process =, capture_output=True,
                                        check=True, text=True)
    time_stamp = human_date_process.stdout.strip() + ' +0000'
    hg_command = ['hg', '-R', args.hgroot + '/' + args.repository + '.hg',
                  'log', '-d', time_stamp, '--template',
                  'hg tag -r {node} -u "{user}" -d "' + time_stamp + '" ' + args.tag]
    # some commits are on both 'default' and the vendor branch
    hg_process = + ['-r', 'not branch(default)'],
                                capture_output=True, check=True, text=True)
    # some are only on 'default'
    if len(hg_process.stdout) < 10:
        hg_process =, capture_output=True,
                                    check=True, text=True)
    if len(hg_process.stdout) < 10:
        print(f'no Mercurial commit found for CVS tag {args.tag} ' +
              f'corresponding to time stamp {time_stamp}')

Home | Main Index | Thread Index | Old Index