# HG changeset patch # User pnathan # Date 1450867750 28800 # Wed Dec 23 02:49:10 2015 -0800 # Node ID b3dbd4a64e914603f9af4e3a476bfbed61b1f638 # Parent 4fb559b7a3c8f36118efbec1effea5cfcccc078e # Parent ebd668c1a5822df1b8671f6f097d48a5994c8f58 Merge. Tested to run on 2.9 (no errors) and 3.6+ aka tip. 3.6 had some cosmetic errors, but no substantiative errors visible in the tests. diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -255,6 +255,14 @@ guest repository. This prevents the update from causing a merge with local changes. +The --clean option allows you to "disable" (by running the "hg up null" +command) any non-guest repository found under the shell directory. This allows +the user to ensure the shel repository is really in the state described by the +.hgguestrepo file (on can also purge each of theses non-guest repositories by +adding the --purge option). This is usefull for example to run tests (in a +controller environment) in a setup where there are several branches in the +shell repository, with different set of guest repositories referenced among the +branches. ###Freeze diff --git a/guestrepo/__init__.py b/guestrepo/__init__.py --- a/guestrepo/__init__.py +++ b/guestrepo/__init__.py @@ -133,7 +133,8 @@ "grupdate": (grupdate, localopt + threadopt # TODO: clean may be the wrong term. - + [('C', 'clean', False, 'ensure every non-guest subrepo is updated to revision -1')] + + [('C', 'clean', False, 'ensure every non-guest repos is updated to revision -1')] + + [('P', 'purge', False, 'also run a "hg purge" in guest repos when cleaning (--clean)')] + [('p', 'pull', False, "grpull before running grupdate")] + [('f', 'file', '', "update using a .hgguestrepo file", 'FILE')], "hg grupdate [REPO [+]] [options]"), diff --git a/guestrepo/guestrepo.py b/guestrepo/guestrepo.py --- a/guestrepo/guestrepo.py +++ b/guestrepo/guestrepo.py @@ -56,6 +56,8 @@ from mercurial import pathutil except ImportError: from mercurial import scmutil as pathutil +from mercurial import extensions + SUPPORTS_PHASES = None try: from mercurial.phases import draft @@ -85,6 +87,18 @@ return func(ui, repo, *args, **kwargs) return wrapper +ADDED_INDEX = 1 +UNKNOWN_INDEX = 4 + +def findrepos(root, excludes=[]): + excludes = excludes[:] + excludes.append(root) + for loc, dirs, files in os.walk(root): + if '.hg' in dirs: + if loc not in excludes: + yield loc + dirs.remove('.hg') + ##################### # Commands ##################### @@ -117,6 +131,7 @@ local = opts.get('local') clean = opts.get('clean') + purge = opts.get('purge') and extensions.find('purge') if opts.get('file'): guests = getguests(ui, repo, opts.get('file'), local=opts.get('local')) else: @@ -556,14 +571,58 @@ ##################### -def findrepos(root, excludes=[]): - excludes = excludes[:] - excludes.append(root) - for loc, dirs, files in os.walk(root): - if '.hg' in dirs: - if loc not in excludes: - yield loc - dirs.remove('.hg') + +class guestrepo(object): + '''An aggregate representing a guest repository''' + def __init__(self, name, configpath, canonpath, uri, csid, root): + self.name = name + self.configpath = configpath + self.canonpath = canonpath + self.uri = uri + self.csid = csid + self.root = root + + def isrepo(self, warn=False): + return os.path.exists(os.path.join(self.root, '.hg')) + + def to_dict(self, ui): + ''' + Output all of the metadata associated with a Guestrepo as a dict + ''' + guestrepo = hg.repository(ui, self.root, create=False) + guestctx = guestrepo[None] + + # Set up GR attributes in JSON + json_dict = {'path' : self.canonpath} + json_dict['branch'] = guestctx.branch() + json_dict['remote_name'] = self.name + + parents = guestctx.parents() + json_dict['id'] = (' '.join(['+'.join([node.hex(p.node()) for p in parents]), ]))[:12] + + if guestctx.tags(): + json_dict['tags'] = '/'.join(guestctx.tags()) + + if guestctx.bookmarks(): + json_dict['bookmarks'] = '/'.join(guestctx.bookmarks()) + + current_bookmark = bookmarks.readcurrent(guestrepo) + + if current_bookmark: + json_dict['current_bookmark'] = current_bookmark + + if changed(guestrepo): + json_dict['changed'] = True + + return json_dict + + def to_gr_entry(self, ui): + guestrepo = hg.repository(ui, self.root, create=False) + changeset_id = node.hex(guestrepo[None].parents()[0].node()) + return "%s = %s %s\n" % self.configpath.ljust(10), self.name.ljust(10), changeset_id + + def to_mapping_entry(self, ui): + return "%s = %s" % self.configpath.ljust(10), self.name def showerrors(ui, workers): @@ -847,16 +906,6 @@ if work: workers.run(work, guest) -def readconfig(filename, ctx): - ''' read a config file at a context - - throws IOError when config file missing from the working directory, - error. LookupError if config is missing from a changeset - ''' - p = config.config() - p.parse(filename, ctx[filename].data()) - return p - def makestatestr(states): ''' Create a description string for a list of state. @@ -941,61 +990,3 @@ in_records.append(loaded_object) return in_records - - - -# N.b., might be dead code. -class guestrepo(object): - '''An aggregate representing a guest repository''' - def __init__(self, name, configpath, canonpath, uri, csid, root): - self.name = name - self.configpath = configpath - self.canonpath = canonpath - self.uri = uri - self.csid = csid - self.root = root - - def isrepo(self, warn=False): - return os.path.exists(os.path.join(self.root, '.hg')) - - def to_dict(self, ui): - ''' - Output all of the metadata associated with a Guestrepo as a dict - ''' - guestrepo = hg.repository(ui, self.root, create=False) - guestctx = guestrepo[None] - - # Set up GR attributes in JSON - json_dict = {'path' : self.canonpath} - json_dict['branch'] = guestctx.branch() - json_dict['remote_name'] = self.name - - parents = guestctx.parents() - json_dict['id'] = (' '.join(['+'.join([node.hex(p.node()) for p in parents]), ]))[:12] - - if guestctx.tags(): - json_dict['tags'] = '/'.join(guestctx.tags()) - - if guestctx.bookmarks(): - json_dict['bookmarks'] = '/'.join(guestctx.bookmarks()) - - try: - current_bookmark = bookmarks.readcurrent(guestrepo) - except AttributeError: - currentbookmark = bookmarks.readactive(guestrepo) - - if current_bookmark: - json_dict['current_bookmark'] = current_bookmark - - if changed(guestrepo): - json_dict['changed'] = True - - return json_dict - - def to_gr_entry(self, ui): - guestrepo = hg.repository(ui, self.root, create=False) - changeset_id = node.hex(guestrepo[None].parents()[0].node()) - return "%s = %s %s\n" % self.configpath.ljust(10), self.name.ljust(10), changeset_id - - def to_mapping_entry(self, ui): - return "%s = %s" % self.configpath.ljust(10), self.name