Question

I have written following script:

#!/usr/bin/python

import os

os.system('hg tags > tags.txt')

file = 'tags.txt'

path = os.path.join(os.getcwd(), file)

fp = open(path)

for i, line in enumerate(fp):

    if i == 1:

    latestTagLine = line`      

    elif i == 2:

        previousTagLine = line    

    elif i > 4:

        break

fp.close()

revLatestTag = latestTagLine.split(':')

l = revLatestTag[0].split(' ')

revPreviousTag = previousTagLine.split(':')

p = revPreviousTag[0].split(' ')

command = 'hg log -r {}:{} > diff.txt'.format(l[-1],p[-1])

os.system(command)

Is there any way in which i don't have to parse the output of "hg tags' command to get the revision numbers ?

Is there any pythonic way to do this ?

o/p of "hg tags" command:

tip 523:e317b6828206

TOOL_1.4 522:5bb1197f2e36

TOOL_1.3 515:7362c0effe40

TOOL_1.1 406:33379f244971

Was it helpful?

Solution

As I've said in answers before, when playing with Mercurial revsets are your friend. That said, what you want doesn't appear to be covered by the revset documentation, but is mentioned in the help for the log command.

In your code you appear to be wanting a diff of what has changed between the "newest" two tags, and the following should do the job for you:

hg diff -r "last(tagged(),2)"

I realise you're working in Python, but the above command will do the grunt work, and your Python code can focus on less menial tasks. The important part is the bit in the quotes, which I'll explain.

tagged() is a list of all revisions that are tagged - it should refer to the same revisions as hg tags, however it will only list each revision once, whereas hg tags will show multiple tags for a single revision, if that's the case.

last(set,[n]) filters the set (in this case the tagged sets) to show the last n items (n is 1 if omitted).

The result of this is a revset that contains the last two tagged changes, which in the example above we pass into hg diff.


Update: OK, I was thrown by the diff in your Python. On reading again, it looks like you want basically the log output between the last two tags? Using revsets this becomes a little more convoluted, but using the above knowledge you can create a revset like so:

hg log -r "last(tagged(),2):last(tagged())"

We're effectively picking the last two tags, and the last one tag (!!) and performing a log of all inclusive sets between them. The log output can be tweaked with --template, as LazyBadger has shown in his answer. I would go for a simplistic --template "{node}\t{tags}\n", but have a look here for more information on the fun you can have.

OTHER TIPS

  • As revset's identifier in hg log -r, you can use any identity, which uniquely identifies the changeset - tag name is OK

With

>hg tags
tip                             1126:cb4dccc90ff1
1.6                             1104:7d47a0f73135
...

log in form

>hg log -r "1.6"
changeset:   1104:7d47a0f73135
tag:         1.6
...

will find correct changeset, as you can see

  • Using revsets, you can eliminate variables from the resulting command totally

Step-by-step

All tags: hg log -r "tag()"

Latest tag: hg log -r "last(tag())"

Penultimate tag: hg log -r "first(last(tag(),2)))" (maybe min() instead of first() in some cases)

Final command becomes

hg log -r "((first(last(tag(),2))):(last(tag())))"

for used it tests hgsubversion repository polished version of log

hg log -r "((first(last(tag(),2))):(last(tag())))" --template "changeset: {node|short}\n{if(tags, 'Tag: {tags}\n')}\n"

produced such output (middle-noise skipped)

changeset: d0f3a5c2cb56
Tag: 1.5.1

changeset: b5b1fce26f1f

...

changeset: 6e1dbf6cbc92

changeset: 7d47a0f73135
Tag: 1.6

FIX: for redundant parentheses and missing quotes

hg log -r "first(last(tag(),2)):last(tag())" ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top