def revset_firefoxrelease(repo, subset, x): """``firefoxrelease([channel=], [platform=]) Changesets that have Firefox releases built from them. Accepts the following named arguments: channel Which release channel to look at. e.g. ``nightly``. Multiple channels can be delimited by spaces. platform Which platform to limit builds to. e.g. ``win32``. Multiple platforms can be delimited by spaces. If multiple filters are requested filters are combined using logical AND. If no filters are specified, all revisions having a Firefox release are matched. """ args = revset.getargsdict(x, 'firefoxrelease', 'channel platform') channels = set() if 'channel' in args: channels = set( revset.getstring(args['channel'], _('channel requires a string')).split()) platforms = set() if 'platform' in args: platforms = set( revset.getstring(args['platform'], _('platform requires a ' 'string')).split()) db = db_for_repo(repo) if not db: repo.ui.warn(_('(warning: firefoxrelease() revset not available)\n')) return revset.baseset() def get_revs(): for rev, builds in release_builds_by_revision(db, repo).iteritems(): for build in builds: if channels and build.channel not in channels: continue if platforms and build.platform not in platforms: continue yield rev break return subset & revset.generatorset(get_revs())
def _oldworkingcopyparent(repo, subset, x): """``oldworkingcopyparent([index])`` previous working copy parent 'index' is how many undoable commands you want to look back. See 'hg undo'. """ args = revset.getargsdict(x, 'oldoworkingcopyrevset', 'reverseindex') reverseindex = revsetlang.getinteger(args.get('reverseindex'), _('index must be a positive interger'), 1) revs = _getoldworkingcopyparent(repo, reverseindex) return subset & smartset.baseset(revs)
def underwayrevset(repo, subset, x): args = revset.getargsdict(x, 'underway', 'commitage headage') if 'commitage' not in args: args['commitage'] = None if 'headage' not in args: args['headage'] = None # We assume callers of this revset add a topographical sort on the # result. This means there is no benefit to making the revset lazy # since the topographical sort needs to consume all revs. # # With this in mind, we build up the set manually instead of constructing # a complex revset. This enables faster execution. # Mutable changesets (non-public) are the most important changesets # to return. ``not public()`` will also pull in obsolete changesets if # there is a non-obsolete changeset with obsolete ancestors. This is # why we exclude obsolete changesets from this query. rs = 'not public() and not obsolete()' rsargs = [] if args['commitage']: rs += ' and date(%s)' rsargs.append( revsetlang.getstring(args['commitage'], _('commitage requires a string'))) mutable = repo.revs(rs, *rsargs) relevant = revset.baseset(mutable) # Add parents of mutable changesets to provide context. relevant += repo.revs('parents(%ld)', mutable) # We also pull in (public) heads if they a) aren't closing a branch # b) are recent. rs = 'head() and not closed()' rsargs = [] if args['headage']: rs += ' and date(%s)' rsargs.append( revsetlang.getstring(args['headage'], _('headage requires a string'))) relevant += repo.revs(rs, *rsargs) # Add working directory parent. wdirrev = repo['.'].rev() if wdirrev != nullrev: relevant += revset.baseset(set([wdirrev])) return subset & relevant
def _olddraft(repo, subset, x): """``olddraft([index])`` previous draft commits 'index' is how many undoable commands you want to look back an undoable command is one that changed draft heads, bookmarks and or working copy parent. Note that olddraft uses an absolute index and so olddraft(1) represents the state after an hg undo -a and not an hg undo. Note: this revset may include hidden commits """ args = revset.getargsdict(x, 'olddraftrevset', 'reverseindex') reverseindex = revsetlang.getinteger(args.get('reverseindex'), _('index must be a positive integer'), 1) revs = _getolddrafts(repo, reverseindex) return subset & smartset.baseset(revs)
def _localbranch(repo, subset, x): """``_localbranch(changectx)`` localbranch changesets Returns all commits within the same localbranch as the changeset(s). A local branch is all draft changesets that are connected, uninterupted by public changesets. Any draft commit within a branch, or a public commit at the base of the branch, can be passed used to identify localbranches. """ # executed on an filtered repo args = revset.getargsdict(x, 'branchrevset', 'changectx') revstring = revsetlang.getstring(args.get('changectx'), _('localbranch argument must be a changectx')) revs = repo.revs(revstring) # we assume that there is only a single rev if repo[revs.first()].phase() == phases.public: querystring = revsetlang.formatspec('(children(%d) & draft())::', revs.first()) else: querystring = revsetlang.formatspec('((::%ld) & draft())::', revs) return subset & smartset.baseset(repo.revs(querystring))
def smartlogrevset(repo, subset, x): """``smartlog([master], [recentdays=N])`` Changesets relevent to you. 'master' is the head of the public branch. Unnamed heads will be hidden unless it's within 'recentdays'. """ args = revset.getargsdict(x, 'smartlogrevset', 'master recentdays') if 'master' in args: masterstring = revsetlang.getstring(args['master'], _('master must be a string')) else: masterstring = '' recentdays = revsetlang.getinteger(args.get('recentdays'), _("recentdays should be int"), -1) revs = set() heads = set() rev = repo.changelog.rev ancestor = repo.changelog.ancestor node = repo.changelog.node parentrevs = repo.changelog.parentrevs books = bookmarks.bmstore(repo) ignore = re.compile(repo.ui.config('smartlog', 'ignorebookmarks', '!')) for b in books: if not ignore.match(b): heads.add(rev(books[b])) # add 'interesting' remote bookmarks as well remotebooks = set() if util.safehasattr(repo, 'names') and 'remotebookmarks' in repo.names: ns = repo.names['remotebookmarks'] remotebooks = set(ns.listnames(repo)) for name in _reposnames(repo.ui): if name in remotebooks: heads.add(rev(ns.namemap(repo, name)[0])) heads.update(repo.revs('.')) global hiddenchanges headquery = 'head()' if remotebooks: # When we have remote bookmarks, only show draft heads, since public # heads should have a remote bookmark indicating them. This allows us # to force push server bookmarks to new locations, and not have the # commits clutter the user's smartlog. headquery = 'heads(draft())' allheads = set(repo.revs(headquery)) if recentdays >= 0: recentquery = revsetlang.formatspec('%r & date(-%d)', headquery, recentdays) recentrevs = set(repo.revs(recentquery)) hiddenchanges += len(allheads - heads) - len(recentrevs - heads) heads.update(recentrevs) else: heads.update(allheads) masterrevset = _masterrevset(repo.ui, repo, masterstring) masterrev = _masterrev(repo, masterrevset) if masterrev is None: masterrev = repo['tip'].rev() masternode = node(masterrev) # Find all draft ancestors and latest public ancestor of heads # that are not in master. # We don't want to draw all public commits because there can be too # many of them. # Don't use revsets, they are too slow for head in heads: anc = rev(ancestor(node(head), masternode)) queue = [head] while queue: current = queue.pop(0) if current not in revs: revs.add(current) # stop as soon as we find public commit ispublic = repo[current].phase() == phases.public if current != anc and not ispublic: parents = parentrevs(current) for p in parents: if p > anc: queue.append(p) # add context: master, current commit, and the common ancestor revs.add(masterrev) return subset & revs
def smartlogrevset(repo, subset, x): """``smartlog([master], [recentdays=N])`` Changesets relevent to you. 'master' is the head of the public branch. Unnamed heads will be hidden unless it's within 'recentdays'. """ args = revset.getargsdict(x, 'smartlogrevset', 'master recentdays') if 'master' in args: masterstring = revsetlang.getstring(args['master'], _('master must be a string')) else: masterstring = '' recentdays = revsetlang.getinteger(args.get('recentdays'), _("recentdays should be int"), -1) revs = set() heads = set() rev = repo.changelog.rev branchinfo = repo.changelog.branchinfo ancestor = repo.changelog.ancestor node = repo.changelog.node parentrevs = repo.changelog.parentrevs books = bookmarks.bmstore(repo) ignore = re.compile(repo.ui.config('smartlog', 'ignorebookmarks', '!')) for b in books: if not ignore.match(b): heads.add(rev(books[b])) # add 'interesting' remote bookmarks as well remotebooks = set() if util.safehasattr(repo, 'names') and 'remotebookmarks' in repo.names: ns = repo.names['remotebookmarks'] remotebooks = set(ns.listnames(repo)) for name in _reposnames(repo.ui): if name in remotebooks: heads.add(rev(ns.namemap(repo, name)[0])) heads.update(repo.revs('.')) global hiddenchanges headquery = 'head() & branch(.)' if remotebooks: # When we have remote bookmarks, only show draft heads, since public # heads should have a remote bookmark indicating them. This allows us # to force push server bookmarks to new locations, and not have the # commits clutter the user's smartlog. headquery = 'draft() &' + headquery allheads = set(repo.revs(headquery)) if recentdays >= 0: recentquery = revsetlang.formatspec('%r & date(-%d)', headquery, recentdays) recentrevs = set(repo.revs(recentquery)) hiddenchanges += len(allheads - heads) - len(recentrevs - heads) heads.update(recentrevs) else: heads.update(allheads) branches = set() for head in heads: branches.add(branchinfo(head)[0]) masterrevset = _masterrevset(repo.ui, repo, masterstring) masterrev = _masterrev(repo, masterrevset) if masterrev is None: masterbranch = None else: masterbranch = branchinfo(masterrev)[0] for branch in branches: if branch != masterbranch: try: rs = 'first(reverse(branch("%s")) & public())' % branch branchmaster = repo.revs(rs).first() if branchmaster is None: # local-only (draft) branch rs = 'branch("%s")' % branch branchmaster = repo.revs(rs).first() except Exception: branchmaster = repo.revs('tip').first() else: branchmaster = masterrev # Find all draft ancestors and latest public ancestor of heads # that are not in master. # We don't want to draw all public commits because there can be too # many of them. # Don't use revsets, they are too slow for head in heads: if branchinfo(head)[0] != branch: continue anc = rev(ancestor(node(head), node(branchmaster))) queue = [head] while queue: current = queue.pop(0) if current not in revs: revs.add(current) # stop as soon as we find public commit ispublic = repo[current].phase() == phases.public if current != anc and not ispublic: parents = parentrevs(current) for p in parents: if p > anc: queue.append(p) # add context: master, current commit, and the common ancestor revs.add(branchmaster) # get common branch ancestor if branch != masterbranch: anc = None for r in revs: if branchinfo(r)[0] != branch: continue if anc is None: anc = r else: anc = rev(ancestor(node(anc), node(r))) if anc: revs.add(anc) return subset & revs