Search code examples
pythonmercurialmercurial-api

How to test the date of a changeset in Mercurial API


I want to use the Mercurial Python API on only changesets that fall within a certain range, and from reading the docs, I haven't been able to work out how to do it.

My code looks like this:

from mercurial import ui, hg
import datetime

repo = hg.repository(ui.ui(), 'path_to_repo' )

start_date = datetime.datetime( 1997,  01, 01 )
end_date   = datetime.datetime( 2000,  12, 31 )

# Print every changesetid in required range
for changesetid in repo:
    #print repo[changesetid]
    changeset = repo.changectx( changesetid )
    date = changeset.date()[0]
    if ( date > start_date and date < end_date):
        # Do stuff...
        pass

And the output I get is:

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    if ( date > start_date and date < end_date):
TypeError: can't compare datetime.datetime to float

Example output dates are:

  • 645630248.0
  • 887802818.0

I've also seen 'hg help dates', but can't tell from this how to convert from a day/month/year date to Mercurial's internal representation.

How do I convert my cutoff dates to a numeric format that is suitable for comparison the date value returned by changectx.date(), please?


PS I know that for an example this trivial, there are better ways of doing this using the hg command directly... what I haven't included in my example code is the complex steps I wish to add at the "Do stuff" point!


Solution

  • Firstly, please remember that the internal Mercurial API is not stable. You should seriously consider using Mercurial's command-line directly if at all possible. Remember that there are XML templates (by passing --style=xml) if you find parsing the default output too annoying.

    That said, this is most easily done with revsets, just as you would do at the command line:

    from mercurial import ui, hg
    repo = hg.repository(ui.ui(), '/some/path/to/repo')
    changesets = repo.revs("date('>1999-01-01') and date('<2000-12-31')")
    

    As a bonus, this will go through Mercurial's internal revset optimizer.