Mercurial > evolve
changeset 3212:6ffd0c36ccc1
branching: merge with stable
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 30 Nov 2017 12:14:36 -0500 |
parents | df8d535216af (current diff) 3b33e00a4868 (diff) |
children | 7bc587557e4f |
files | |
diffstat | 10 files changed, 506 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGELOG Thu Nov 30 21:31:14 2017 -0800 +++ b/CHANGELOG Thu Nov 30 12:14:36 2017 -0500 @@ -1,6 +1,16 @@ Changelog ========= +7.1.0 - in progress +------------------- + + * verbosity: respect --quiet for prev, next and summary + +topic (0.6.0) + + * add a new 'serverminitopic' extension for minimal server support + (see `hg help -e serverminitopic` for details) + 7.0.1 -- 2017-11-14 -------------------
--- a/hgext3rd/evolve/__init__.py Thu Nov 30 21:31:14 2017 -0800 +++ b/hgext3rd/evolve/__init__.py Thu Nov 30 12:14:36 2017 -0500 @@ -831,17 +831,10 @@ raise def summaryhook(ui, repo): - def write(fmt, count): - s = fmt % count - if count: - ui.write(s) - else: - ui.note(s) - state = _evolvestateread(repo) if state is not None: # i18n: column positioning for "hg summary" - ui.write(_('evolve: (evolve --continue)\n')) + ui.status(_('evolve: (evolve --continue)\n')) @eh.extsetup def obssummarysetup(ui): @@ -2031,7 +2024,8 @@ finally: lockmod.release(tr, lock) - displayer.show(target) + if not repo.ui.quiet: + displayer.show(target) def _findprevtarget(repo, displayer, movebookmark=False, topic=True): target = bookmark = None @@ -2174,7 +2168,8 @@ tr.close() finally: lockmod.release(tr, lock) - displayer.show(c) + if not ui.quiet: + displayer.show(c) result = 0 elif children: ui.warn(_("ambigious next changeset:\n"))
--- a/hgext3rd/evolve/metadata.py Thu Nov 30 21:31:14 2017 -0800 +++ b/hgext3rd/evolve/metadata.py Thu Nov 30 12:14:36 2017 -0500 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -__version__ = '7.0.2.dev' +__version__ = '7.1.0.dev' testedwith = '4.1.3 4.2.3 4.3.2 4.4.1' minimumhgversion = '4.1' buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obshistory.py Thu Nov 30 21:31:14 2017 -0800 +++ b/hgext3rd/evolve/obshistory.py Thu Nov 30 12:14:36 2017 -0500 @@ -787,8 +787,15 @@ verb = 'split' return {'verb': verb} +# Use a more advanced version of obsfateverb that uses effect-flag +if util.safehasattr(obsutil, 'obsfateverb'): + + @eh.wrapfunction(obsutil, 'obsfateverb') + def obsfateverb(orig, *args, **kwargs): + return _successorsetverb(*args, **kwargs)['verb'] + # Hijack callers of successorsetverb -if util.safehasattr(obsutil, 'obsfateprinter'): +elif util.safehasattr(obsutil, 'obsfateprinter'): @eh.wrapfunction(obsutil, 'obsfateprinter') def obsfateprinter(orig, successors, markers, ui):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/serverminitopic.py Thu Nov 30 12:14:36 2017 -0500 @@ -0,0 +1,226 @@ +"""enable a minimal verison of topic for server + +Non publishing repository will see topic as "branch:topic" in the branch field. + +In addition to adding the extensions, the feature must be manually enabled in the config: + + [experimental] + server-mini-topic = yes +""" +import hashlib +import contextlib + +from mercurial import ( + branchmap, + context, + encoding, + extensions, + node, + registrar, + util, + wireproto, +) + +if util.safehasattr(registrar, 'configitem'): + + configtable = {} + configitem = registrar.configitem(configtable) + configitem('experimental', 'server-mini-topic', + default=False, + ) + +def hasminitopic(repo): + """true if minitopic is enabled on the repository + + (The value is cached on the repository) + """ + enabled = getattr(repo, '_hasminitopic', None) + if enabled is None: + enabled = (repo.ui.configbool('experimental', 'server-mini-topic') + and not repo.publishing()) + repo._hasminitopic = enabled + return enabled + +### make topic visible though "ctx.branch()" + +class topicchangectx(context.changectx): + """a sunclass of changectx that add topic to the branch name""" + + def branch(self): + branch = super(topicchangectx, self).branch() + if hasminitopic(self._repo) and self.phase(): + topic = self._changeset.extra.get('topic') + if topic is not None: + topic = encoding.tolocal(topic) + branch = '%s:%s' % (branch, topic) + return branch + +### avoid caching topic data in rev-branch-cache + +class revbranchcacheoverlay(object): + """revbranch mixin that don't use the cache for non public changeset""" + + def _init__(self, *args, **kwargs): + super(revbranchcacheoverlay, self).__init__(*args, **kwargs) + if 'branchinfo' in vars(self): + del self.branchinfo + + def branchinfo(self, rev): + """return branch name and close flag for rev, using and updating + persistent cache.""" + phase = self._repo._phasecache.phase(self, rev) + if phase: + ctx = self._repo[rev] + return ctx.branch(), ctx.closesbranch() + return super(revbranchcacheoverlay, self).branchinfo(rev) + +def reposetup(ui, repo): + """install a repo class with a special revbranchcache""" + + if hasminitopic(repo): + repo = repo.unfiltered() + + class minitopicrepo(repo.__class__): + """repository subclass that install the modified cache""" + + def revbranchcache(self): + if self._revbranchcache is None: + cache = super(minitopicrepo, self).revbranchcache() + + class topicawarerbc(revbranchcacheoverlay, cache.__class__): + pass + cache.__class__ = topicawarerbc + if 'branchinfo' in vars(cache): + del cache.branchinfo + self._revbranchcache = cache + return self._revbranchcache + + repo.__class__ = minitopicrepo + +### topic aware branch head cache + +def _phaseshash(repo, maxrev): + """uniq ID for a phase matching a set of rev""" + revs = set() + cl = repo.changelog + fr = cl.filteredrevs + nm = cl.nodemap + for roots in repo._phasecache.phaseroots[1:]: + for n in roots: + r = nm.get(n) + if r not in fr and r < maxrev: + revs.add(r) + key = node.nullid + revs = sorted(revs) + if revs: + s = hashlib.sha1() + for rev in revs: + s.update('%s;' % rev) + key = s.digest() + return key + +# needed to prevent reference used for 'super()' call using in branchmap.py to +# no go into cycle. (yes, URG) +_oldbranchmap = branchmap.branchcache + +@contextlib.contextmanager +def oldbranchmap(): + previous = branchmap.branchcache + try: + branchmap.branchcache = _oldbranchmap + yield + finally: + branchmap.branchcache = previous + +_publiconly = set([ + 'base', + 'immutable', +]) + +def mighttopic(repo): + return hasminitopic(repo) and repo.filtername not in _publiconly + +class _topiccache(branchmap.branchcache): # combine me with branchmap.branchcache + + def __init__(self, *args, **kwargs): + # super() call may fail otherwise + with oldbranchmap(): + super(_topiccache, self).__init__(*args, **kwargs) + self.phaseshash = None + + def copy(self): + """return an deep copy of the branchcache object""" + new = self.__class__(self, self.tipnode, self.tiprev, self.filteredhash, + self._closednodes) + new.phaseshash = self.phaseshash + return new + + def validfor(self, repo): + """Is the cache content valid regarding a repo + + - False when cached tipnode is unknown or if we detect a strip. + - True when cache is up to date or a subset of current repo.""" + valid = super(_topiccache, self).validfor(repo) + if not valid: + return False + elif not mighttopic(repo) and self.phaseshash is None: + # phasehash at None means this is a branchmap + # coming from a public only set + return True + else: + try: + valid = self.phaseshash == _phaseshash(repo, self.tiprev) + return valid + except IndexError: + return False + + def write(self, repo): + # we expect (hope) mutable set to be small enough to be that computing + # it all the time will be fast enough + if not mighttopic(repo): + super(_topiccache, self).write(repo) + + def update(self, repo, revgen): + """Given a branchhead cache, self, that may have extra nodes or be + missing heads, and a generator of nodes that are strictly a superset of + heads missing, this function updates self to be correct. + """ + super(_topiccache, self).update(repo, revgen) + if mighttopic(repo): + self.phaseshash = _phaseshash(repo, self.tiprev) + +def wrapread(orig, repo): + # Avoiding to write cache for filter where topic applies is a good step, + # but we need to also avoid reading it. Existing branchmap cache might + # exists before the turned the feature on. + if mighttopic(repo): + return None + return orig(repo) + +# advertise topic capabilities + +def wireprotocaps(orig, repo, proto): + caps = orig(repo, proto) + if hasminitopic(repo): + caps.append('topics') + return caps + +# wrap the necessary bit + +def wrapclass(container, oldname, new): + old = getattr(container, oldname) + if not issubclass(old, new): + targetclass = new + # check if someone else already wrapped the class and handle that + if not issubclass(new, old): + class targetclass(new, old): + pass + setattr(container, oldname, targetclass) + current = getattr(container, oldname) + assert issubclass(current, new), (current, new, targetclass) + +def uisetup(ui): + wrapclass(context, 'changectx', topicchangectx) + wrapclass(branchmap, 'branchcache', _topiccache) + extensions.wrapfunction(branchmap, 'read', wrapread) + extensions.wrapfunction(wireproto, '_capabilities', wireprotocaps)
--- a/hgext3rd/topic/__init__.py Thu Nov 30 21:31:14 2017 -0800 +++ b/hgext3rd/topic/__init__.py Thu Nov 30 12:14:36 2017 -0500 @@ -174,7 +174,7 @@ 'topic.active': 'green', } -__version__ = '0.5.2.dev' +__version__ = '0.6.0.dev' testedwith = '4.1.3 4.2.3 4.3.3 4.4.1' minimumhgversion = '4.1'
--- a/setup.py Thu Nov 30 21:31:14 2017 -0800 +++ b/setup.py Thu Nov 30 12:14:36 2017 -0500 @@ -19,6 +19,7 @@ return get_metadata()['minimumhgversion'] py_modules = [ + 'hgext3rd.serverminitopic', ] py_packages = [ 'hgext3rd',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-minitopic.t Thu Nov 30 12:14:36 2017 -0500 @@ -0,0 +1,238 @@ + $ . $TESTDIR/testlib/common.sh + +setup + $ cat >> $HGRCPATH << EOF + > [extensions] + > share= + > blackbox= + > [web] + > allow_push = * + > push_ssl = no + > [phases] + > publish = False + > [paths] + > enabled = http://localhost:$HGPORT/ + > disabled = http://localhost:$HGPORT2/ + > EOF + + $ hg init ./server-enabled + $ cat >> server-enabled/.hg/hgrc << EOF + > [extensions] + > serverminitopic= + > [experimental] + > server-mini-topic = yes + > EOF + + $ hg share ./server-enabled ./server-disabled + updating working directory + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cat >> server-disabled/.hg/hgrc << EOF + > [extensions] + > serverminitopic= + > [experimental] + > server-mini-topic = no + > EOF + + $ hg init client-disabled + $ hg init client-enabled + $ cat >> client-enabled/.hg/hgrc << EOF + > [extensions] + > topic= + > EOF + + $ hg serve -R server-enabled -p $HGPORT -d --pid-file hg1.pid --errorlog hg1.error + $ cat hg1.pid > $DAEMON_PIDS + $ hg serve -R server-disabled -p $HGPORT2 -d --pid-file hg2.pid --errorlog hg2.error + $ cat hg2.pid >> $DAEMON_PIDS + + $ curl --silent http://localhost:$HGPORT/?cmd=capabilities | grep -o topics + topics + $ curl --silent http://localhost:$HGPORT2/?cmd=capabilities | grep -o topics + [1] + +Pushing first changesets to the servers +-------------------------------------- + + $ cd client-enabled + $ mkcommit c_A0 + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + $ mkcommit c_B0 + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new head +---------------- + + $ hg up 'desc("c_A0")' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit c_C0 + created new head + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + abort: push creates new remote head 22c9514ed811! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + abort: push creates new remote head 22c9514ed811! + (merge or see 'hg help push' for details about pushing new heads) + [255] + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 0ab6d544d0efd629fda056601cfe95e73d1af210 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default 0ab6d544d0efd629fda056601cfe95e73d1af210 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new topic +----------------- + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ mkcommit c_D0 + $ hg log -G + @ changeset: 3:9c660cf97499 + |\ tag: tip + | | parent: 2:22c9514ed811 + | | parent: 1:0ab6d544d0ef + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_D0 + | | + | o changeset: 2:22c9514ed811 + | | parent: 0:14faebcf9752 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_C0 + | | + o | changeset: 1:0ab6d544d0ef + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_B0 + | + o changeset: 0:14faebcf9752 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_A0 + + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 2 changesets with 2 changes to 2 files + $ hg up 'desc("c_C0")' + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ hg topic topic_A + marked working directory as topic: topic_A + $ mkcommit c_E0 + active topic 'topic_A' grew its first changeset + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + abort: push creates new remote head f31af349535e! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files (+1 heads) + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf + default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf f31af349535e413b6023f11b51a6afccf4139180 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new head to a topic +--------------------------- + + $ hg up 'desc("c_D0")' + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg topic topic_A + marked working directory as topic: topic_A + $ mkcommit c_F0 + $ hg log -G + @ changeset: 5:82c5842e0472 + | tag: tip + | topic: topic_A + | parent: 3:9c660cf97499 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_F0 + | + | o changeset: 4:f31af349535e + | | topic: topic_A + | | parent: 2:22c9514ed811 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_E0 + | | + o | changeset: 3:9c660cf97499 + |\| parent: 2:22c9514ed811 + | | parent: 1:0ab6d544d0ef + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_D0 + | | + | o changeset: 2:22c9514ed811 + | | parent: 0:14faebcf9752 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_C0 + | | + o | changeset: 1:0ab6d544d0ef + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_B0 + | + o changeset: 0:14faebcf9752 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_A0 + + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + abort: push creates new remote head 82c5842e0472 on branch 'default:topic_A'! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf + default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error
--- a/tests/test-prev-next.t Thu Nov 30 21:31:14 2017 -0800 +++ b/tests/test-prev-next.t Thu Nov 30 12:14:36 2017 -0500 @@ -3,7 +3,7 @@ > EOF $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH -hg prev -B should move active bookmark +hg prev & next move to parent/child $ hg init test-repo $ cd test-repo $ touch a @@ -12,6 +12,18 @@ $ touch b $ hg add b $ hg commit -m 'added b' + $ hg prev + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [0] added a + $ hg next + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [1] added b + +hg prev & next respect --quiet + $ hg prev -q + $ hg next -q + +hg prev -B should move active bookmark $ hg bookmark mark $ hg bookmarks * mark 1:6e742c9127b3
--- a/tests/test-topic-stack.t Thu Nov 30 21:31:14 2017 -0800 +++ b/tests/test-topic-stack.t Thu Nov 30 12:14:36 2017 -0500 @@ -864,13 +864,13 @@ | rewritten(parent, content) as dde94df880e9, e7ea874afbd5 by test (Thu Jan 01 00:00:00 1970 +0000) | x 907f7d3c2333 (18) c_G - | rewritten as b24bab30ac12 by test (Thu Jan 01 00:00:00 1970 +0000) + | rewritten(content) as b24bab30ac12 by test (Thu Jan 01 00:00:00 1970 +0000) | x 3ab2eedae500 (13) c_G - | rewritten as 907f7d3c2333 by test (Thu Jan 01 00:00:00 1970 +0000) + | rewritten(parent) as 907f7d3c2333 by test (Thu Jan 01 00:00:00 1970 +0000) | x c7d60a180d05 (6) c_G - rewritten as 3ab2eedae500 by test (Thu Jan 01 00:00:00 1970 +0000) + rewritten(user) as 3ab2eedae500 by test (Thu Jan 01 00:00:00 1970 +0000) $ hg export . # HG changeset patch