How to test the date of a changeset in Mercurial API

430 views Asked by At

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!

2

There are 2 answers

2
Benjamin Pollack On BEST ANSWER

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.

0
Clare Macrae On

I got it working in the end, and put the functionality into the python_internal_date() helper function below:

from mercurial import ui, hg
import datetime, time

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

def python_internal_date( year, month, day ):
    # From http://stackoverflow.com/a/7852891/104370
    start_date = datetime.datetime( year,  month, day )
    return time.mktime( start_date.timetuple() )

start_date = python_internal_date( 1997, 01, 01 )
end_date   = python_internal_date( 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