qsync: support for synchronisation with applied patches from outer space and more
:more:
- also add some tests
- kill OLDBRANCHNAME
- several minor cleaning
--- a/hgext/qsync.py Wed May 02 14:08:21 2012 +0200
+++ b/hgext/qsync.py Fri May 04 14:33:35 2012 +0200
@@ -1,7 +1,7 @@
import re
-
from cStringIO import StringIO
+import json
from mercurial.i18n import _
from mercurial import commands
@@ -13,18 +13,12 @@
from mercurial import scmutil
from mercurial import error
from mercurial import extensions
-
-
-import re
-
-import json
-
+from mercurial import phases
### old compat code
#############################
BRANCHNAME="qsubmit2"
-OLDBRANCHNAME="pyves-qsubmit"
### new command
#############################
@@ -59,7 +53,6 @@
interleaved changeset will appear interleaved.
'''
- review = None
review = 'edit'
if opts['review_all']:
review = 'all'
@@ -67,10 +60,7 @@
try:
parent = mqrepo[BRANCHNAME]
except error.RepoLookupError:
- try:
- parent = mqrepo[OLDBRANCHNAME]
- except error.RepoLookupError:
- parent = initqsubmit(mqrepo)
+ parent = initqsubmit(mqrepo)
store, data, touched = fillstore(repo, parent)
if not touched:
raise util.Abort('Nothing changed')
@@ -78,15 +68,45 @@
# 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, ctxhex) for ctxhex, name in olddata])
+
for patch_name in touched:
try:
store.getfile(patch_name)
review_list.append(patch_name)
except IOError:
- pass
+ oldnode = oldfiles[patch_name]
+ obsolete = extensions.find('obsolete')
+ newnodes = obsolete.newerversion(repo, oldnode)
+ if newnodes:
+ newnodes = [n for n in newnodes if n] # 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:
+ message += '\n'.join('* applied %s' % x for x in applied_list)
message += '\n'.join('* %s ready for review' % x for x in review_list)
memctx = patch.makememctx(mqrepo, (parent.node(), nullid),
message,
@@ -122,7 +142,7 @@
return []
def get_current_data(repo):
- """Return what would be exported if not previous data exists"""
+ """Return what would be exported if no previous data exists"""
data = []
for ctx in repo.set('draft() - (obsolete() + merge())'):
name = makename(ctx)
@@ -188,6 +208,7 @@
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):
@@ -196,7 +217,7 @@
def fillstore(repo, basemqctx):
- """file store with patch data"""
+ """fill store with patch data"""
olddata = get_old_data(basemqctx)
newdata = get_current_data(repo)
store = patch.filestore()
@@ -207,7 +228,6 @@
store.setfile('series', series, (False, False))
# export data to ease futur work
- series ='\n'.join(d[1] for d in data) + '\n'
store.setfile('qsubmitdata', json.dumps(data, indent=True),
(False, False))
finally:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-qsync.t Fri May 04 14:33:35 2012 +0200
@@ -0,0 +1,212 @@
+ $ cat >> $HGRCPATH <<EOF
+ > [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 "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> $HGRCPATH
+ $ 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 unstables 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]