# HG changeset patch # User Pierre-Yves David # Date 1389139663 28800 # Node ID 60a2fad036500e2caa072c5962f16b30c51c6c59 # Parent bbb3a0e1dfea67795e4b92398800e464b0b8c8e8 removed the qsync extension. The only user I knew about (logilab) is not using it anymore. It not compatible with coming Mercurial version 2.9. diff -r bbb3a0e1dfea -r 60a2fad03650 README --- a/README Tue Jan 07 15:52:47 2014 -0800 +++ b/README Tue Jan 07 16:07:43 2014 -0800 @@ -46,6 +46,8 @@ - add verbose hint about how to handle corner case by hand. This should help people until evolve is able to to it itself. +- removed the qsync extension. The only user I knew about (logilab) is not + using it anymore. It not compatible with coming Mercurial version 2.9. 3.2.0 -- 2013-11-15 diff -r bbb3a0e1dfea -r 60a2fad03650 hgext/qsync.py --- a/hgext/qsync.py Tue Jan 07 15:52:47 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,266 +0,0 @@ -# Copyright 2011 Logilab SA -"""synchronize patches queues and evolving changesets""" - -import re -from cStringIO import StringIO -import json - -from mercurial.i18n import _ -from mercurial import commands -from mercurial import patch -from mercurial import util -from mercurial.node import nullid, hex, short, bin -from mercurial import cmdutil -from mercurial import hg -from mercurial import scmutil -from mercurial import error -from mercurial import extensions -from mercurial import phases -from mercurial import obsolete - -### old compat code -############################# - -BRANCHNAME="qsubmit2" - -### new command -############################# -cmdtable = {} -command = cmdutil.command(cmdtable) - -@command('^qsync|sync', - [ - ('a', 'review-all', False, _('mark all touched patches ready for review (no editor)')), - ], - '') -def cmdsync(ui, repo, **opts): - '''Export draft changeset as mq patch in a mq patches repository commit. - - This command get all changesets in draft phase and create an mq changeset: - - * on a "qsubmit2" branch (based on the last changeset) - - * one patch per draft changeset - - * a series files listing all generated patch - - * qsubmitdata holding useful information - - It does use obsolete relation to update patches that already existing in the qsubmit2 branch. - - Already existing patch which became public, draft or got killed are remove from the mq repo. - - Patch name are generated using the summary line for changeset description. - - .. warning:: Series files is ordered topologically. So two series with - interleaved changeset will appear interleaved. - ''' - - review = 'edit' - if opts['review_all']: - review = 'all' - mqrepo = repo.mq.qrepo() - if mqrepo is None: - raise util.Abort('No patches repository') - - try: - parent = mqrepo[BRANCHNAME] - except error.RepoLookupError: - parent = initqsubmit(mqrepo) - store, data, touched = fillstore(repo, parent) - try: - if not touched: - raise util.Abort('Nothing changed') - files = ['qsubmitdata', 'series'] + touched - # mark some as ready for review - message = 'qsubmit commit\n\n' - review_list = [] - applied_list = [] - if review: - olddata = get_old_data(parent) - oldfiles = dict([(name, bin(ctxhex)) for ctxhex, name in olddata]) - - for patch_name in touched: - try: - store.getfile(patch_name) - review_list.append(patch_name) - except IOError: - oldnode = oldfiles[patch_name] - newnodes = obsolete.successorssets(repo, oldnode) - if newnodes: - newnodes = [n for n in newnodes if n and n[0] in repo] # remove killing - if not newnodes: - # changeset has been killed (eg. reject) - pass - else: - assert len(newnodes) == 1 # conflict!!! - newnode = newnodes[0] - assert len(newnode) == 1 # split unsupported for now - newnode = list(newnode)[0] - # XXX unmanaged case where a cs is obsoleted by an unavailable one - #if newnode.node() not in repo.changelog.nodemap: - # raise util.Abort('%s is obsoleted by an unknown node %s'% (oldnode, newnode)) - ctx = repo[newnode] - if ctx.phase() == phases.public: - # applied - applied_list.append(patch_name) - elif ctx.phase() == phases.secret: - # already exported changeset is now secret - repo.ui.warn("An already exported changeset is now secret!!!") - else: - # draft - assert False, "Should be exported" - - if review: - if applied_list: - message += '\n'.join('* applied %s' % x for x in applied_list) + '\n' - if review_list: - message += '\n'.join('* %s ready for review' % x for x in review_list) + '\n' - memctx = patch.makememctx(mqrepo, (parent.node(), nullid), - message, - None, - None, - parent.branch(), files, store, - editor=None) - if review == 'edit': - memctx._text = cmdutil.commitforceeditor(mqrepo, memctx, []) - mqrepo.savecommitmessage(memctx.description()) - n = memctx.commit() - finally: - store.close() - return 0 - - -def makename(ctx): - """create a patch name form a changeset""" - descsummary = ctx.description().splitlines()[0] - descsummary = re.sub(r'\s+', '_', descsummary) - descsummary = re.sub(r'\W+', '', descsummary) - if len(descsummary) > 45: - descsummary = descsummary[:42] + '.' - return '%s-%s.diff' % (ctx.branch().upper(), descsummary) - - -def get_old_data(mqctx): - """read qsubmit data to fetch previous export data - - get old data from the content of an mq commit""" - try: - old_data = mqctx['qsubmitdata'] - return json.loads(old_data.data()) - except error.LookupError: - return [] - -def get_current_data(repo): - """Return what would be exported if no previous data exists""" - data = [] - for ctx in repo.set('draft() - (obsolete() + merge())'): - name = makename(ctx) - data.append([ctx.hex(), makename(ctx)]) - merges = repo.revs('draft() and merge()') - if merges: - repo.ui.warn('ignoring %i merge\n' % len(merges)) - return data - - -def patchmq(repo, store, olddata, newdata): - """export the mq patches and return all useful data to be exported""" - finaldata = [] - touched = set() - currentdrafts = set(d[0] for d in newdata) - usednew = set() - usedold = set() - evolve = extensions.find('evolve') - for oldhex, oldname in olddata: - if oldhex in usedold: - continue # no duplicate - usedold.add(oldhex) - oldname = str(oldname) - oldnode = bin(oldhex) - newnodes = obsolete.successorssets(repo, oldnode) - if newnodes: - newnodes = [n for n in newnodes if n and n[0] in repo] # remove killing - if len(newnodes) > 1: - newnodes = [short(nodes[0]) for nodes in newnodes] - raise util.Abort('%s have more than one newer version: %s'% (oldname, newnodes)) - if newnodes: - # else, changeset have been killed - newnode = list(newnodes)[0][0] - ctx = repo[newnode] - if ctx.hex() != oldhex and ctx.phase(): - fp = StringIO() - cmdutil.export(repo, [ctx.rev()], fp=fp) - data = fp.getvalue() - store.setfile(oldname, data, (None, None)) - finaldata.append([ctx.hex(), oldname]) - usednew.add(ctx.hex()) - touched.add(oldname) - continue - if oldhex in currentdrafts: - # else changeset is now public or secret - finaldata.append([oldhex, oldname]) - usednew.add(ctx.hex()) - continue - touched.add(oldname) - - for newhex, newname in newdata: - if newhex in usednew: - continue - newnode = bin(newhex) - ctx = repo[newnode] - fp = StringIO() - cmdutil.export(repo, [ctx.rev()], fp=fp) - data = fp.getvalue() - store.setfile(newname, data, (None, None)) - finaldata.append([ctx.hex(), newname]) - touched.add(newname) - # sort by branchrev number - finaldata.sort(key=lambda x: sort_key(repo[x[0]])) - # sort touched too (ease review list) - stouched = [f[1] for f in finaldata if f[1] in touched] - stouched += [x for x in touched if x not in stouched] - return finaldata, stouched - -def sort_key(ctx): - """ctx sort key: (branch, rev)""" - return (ctx.branch(), ctx.rev()) - - -def fillstore(repo, basemqctx): - """fill store with patch data""" - olddata = get_old_data(basemqctx) - newdata = get_current_data(repo) - store = patch.filestore() - try: - data, touched = patchmq(repo, store, olddata, newdata) - # put all name in the series - series ='\n'.join(d[1] for d in data) + '\n' - store.setfile('series', series, (False, False)) - - # export data to ease futur work - store.setfile('qsubmitdata', json.dumps(data, indent=True), - (False, False)) - except: - store.close() - raise - return store, data, touched - - -def initqsubmit(mqrepo): - """create initial qsubmit branch""" - store = patch.filestore() - try: - files = set() - store.setfile('DO-NOT-EDIT-THIS-WORKING-COPY-BY-HAND', 'WE WARNED YOU!', (False, False)) - store.setfile('.hgignore', '^status$\n', (False, False)) - memctx = patch.makememctx(mqrepo, (nullid, nullid), - 'qsubmit init', - None, - None, - BRANCHNAME, ('.hgignore',), store, - editor=None) - mqrepo.savecommitmessage(memctx.description()) - n = memctx.commit() - finally: - store.close() - return mqrepo[n] diff -r bbb3a0e1dfea -r 60a2fad03650 tests/test-qsync.t --- a/tests/test-qsync.t Tue Jan 07 15:52:47 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ - $ cat >> $HGRCPATH < [defaults] - > amend=-d "0 0" - > [web] - > push_ssl = false - > allow_push = * - > [phases] - > publish = False - > [alias] - > qlog = log --template='{rev} - {node|short} {desc} ({phase})\n' - > mqlog = log --mq --template='{rev} - {desc}\n' - > [diff] - > git = 1 - > unified = 0 - > [extensions] - > hgext.rebase= - > hgext.graphlog= - > hgext.mq= - > EOF - $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH - $ echo "qsync=$(echo $(dirname $TESTDIR))/hgext/qsync.py" >> $HGRCPATH - $ mkcommit() { - > echo "$1" > "$1" - > hg add "$1" - > hg ci -m "add $1" - > } - -basic sync - - $ hg init local - $ cd local - $ hg qinit -c - $ hg qci -m "initial commit" - $ mkcommit a - $ mkcommit b - $ hg qlog - 1 - 7c3bad9141dc add b (draft) - 0 - 1f0dee641bb7 add a (draft) - $ hg qsync -a - $ hg mqlog - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - -basic sync II - - $ hg init local - $ cd local - $ hg qinit -c - $ hg qci -m "initial commit" - $ mkcommit a - $ mkcommit b - $ hg qlog - 1 - 7c3bad9141dc add b (draft) - 0 - 1f0dee641bb7 add a (draft) - $ hg qsync -a - $ hg mqlog - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - - $ echo "b" >> b - $ hg amend - $ hg qsync -a - $ hg mqlog - 3 - qsubmit commit - - * DEFAULT-add_b.diff ready for review - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - - $ hg up -r 0 - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ echo "a" >> a - $ hg amend - 1 new unstable changesets - $ hg graft -O 3 - grafting revision 3 - $ hg qsync -a - $ hg mqlog - 4 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 3 - qsubmit commit - - * DEFAULT-add_b.diff ready for review - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - -sync with published changeset - - $ hg init local - $ cd local - $ hg qinit -c - $ hg qci -m "initial commit" - $ mkcommit a - $ mkcommit b - $ hg qlog - 1 - 7c3bad9141dc add b (draft) - 0 - 1f0dee641bb7 add a (draft) - $ hg qsync -a - $ hg mqlog - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - - $ hg phase -p 0 - $ hg qsync -a - $ hg mqlog - 3 - qsubmit commit - - * applied DEFAULT-add_a.diff - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - - $ mkcommit c - $ mkcommit d - $ hg qsync -a - $ hg mqlog - 4 - qsubmit commit - - * DEFAULT-add_c.diff ready for review - * DEFAULT-add_d.diff ready for review - 3 - qsubmit commit - - * applied DEFAULT-add_a.diff - 2 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 1 - qsubmit init - 0 - initial commit - - $ cd .. - $ hg qclone -U local local2 - $ cd local2 - $ hg qlog - 3 - 47d2a3944de8 add d (draft) - 2 - 4538525df7e2 add c (draft) - 1 - 7c3bad9141dc add b (draft) - 0 - 1f0dee641bb7 add a (public) - $ hg strip -n 1 --no-backup - $ hg up - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg up --mq 4 - 6 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg qseries - DEFAULT-add_b.diff - DEFAULT-add_c.diff - DEFAULT-add_d.diff - $ hg qpush - applying DEFAULT-add_b.diff - now at: DEFAULT-add_b.diff - $ hg qfinish -a - $ hg phase -p . - $ hg qci -m "applied DEFAULT-add_b.diff" - $ cd ../local - $ hg pull ../local2 - pulling from ../local2 - searching for changes - no changes found - $ hg pull --mq ../local2/.hg/patches - pulling from ../local2/.hg/patches - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - (run 'hg update' to get a working copy) - $ hg qlog - 3 - 47d2a3944de8 add d (draft) - 2 - 4538525df7e2 add c (draft) - 1 - 7c3bad9141dc add b (public) - 0 - 1f0dee641bb7 add a (public) - $ hg mqlog -l 1 - 5 - applied DEFAULT-add_b.diff - $ hg status --mq --rev tip:-2 - M series - A DEFAULT-add_b.diff - $ hg qsync -a - $ hg status --mq --rev tip:-2 - M qsubmitdata - $ hg mqlog -l 1 - 6 - qsubmit commit - - * applied DEFAULT-add_b.diff - $ hg qsync -a - abort: Nothing changed - [255] - -mixed sync - - $ hg init local - $ cd local - $ hg qinit -c - $ mkcommit a - $ mkcommit b - $ hg qlog - 1 - 7c3bad9141dc add b (draft) - 0 - 1f0dee641bb7 add a (draft) - $ hg qsync -a - $ hg mqlog - 1 - qsubmit commit - - * DEFAULT-add_a.diff ready for review - * DEFAULT-add_b.diff ready for review - 0 - qsubmit init - $ hg phase -p 0 - $ echo "b" >> b - $ hg amend - $ hg qsync -a - $ hg mqlog -l 1 - 2 - qsubmit commit - - * applied DEFAULT-add_a.diff - * DEFAULT-add_b.diff ready for review -