Mercurial repository log including subrepositories

377 views Asked by At

In our build scripts I use the templated hg log command to get a changelist for a particular build. This works great, but unfortunately it does not include changes in the subrepos (we have more than 10 of them). I would like to include them too, but there seems to be no such command.

I'm thinking about writing a script that:

  1. Enumerates the .hgsubstate file at the starting revision
  2. Finds out the subrepos and their starting revisions
  3. Runs hg log for them
  4. Merges and sorts the results by date.

Is there any other simpler way? Maybe a command I'm missing?

1

There are 1 answers

0
Catskul On

Since it's apparently on the todo for a while years and otherwise unavailable, I wrote my own subtools.py:

from __future__ import print_function
import hglib
import os
import sys

def get_substate(client, rev=None):
    substate_filename = os.path.join(client.root(), '.hgsubstate')
    if os.path.isfile(substate_filename):
        lines = client.cat([substate_filename], rev).split('\n')
        return { key : value for (value,key) in [ line.split() for line in lines if line ]}
    else:
        return {}


def substate_diff(client, revA, revB):
    substate_a = get_substate(client, revA)
    substate_b = get_substate(client, revB)
    key_union = set(substate_b) | set(substate_a)

    diff = {}
    for key in key_union:
       diff[key] = (substate_a[key], substate_b[key])

    return diff

def recursive_log(path, revA, revB):
    logtree = { 'logs': [], 'subrepos': {}}

    try:
        client = hglib.open(path)
    except:
        return logtree

    if revA == revB:
        print("no changes on {}".format(client.root()))
        return logtree

    print("Checking {} between {} and {}...".format(client.root(), revA, revB))

    for key, revisions in substate_diff(client, revA, revB).iteritems():
        if revisions[0] and revisions[1]:
            logtree['subrepos'][key] = recursive_log(os.path.join(client.root(),key), revisions[0], revisions[1])
        elif revisions[0] and not revisions[1]:
            print("removed subrepo with path: %s"%key, file=sys.stderr)
        elif revisions[1] and not revisions[2]:
            print("added subrepo with path: %s"%key, file=sys.stderr)

    logtree['logs'] = client.log("%s:%s"%(revA,revB))
    return logtree

use as such:

In [15]: log = subtools.recursive_log('./', '947', '951')