# HG changeset patch # User Pierre-Yves David # Date 1344274464 -7200 # Node ID b86e062f233596ad44607a20e1ea8fd80e7aada3 # Parent 9720ac97445f7bbec2e5d07615a3a2f0822680bf# Parent 37cba4324ccfa6cba182e9d33e7a4c583d95cc92 merge with stable diff -r 37cba4324ccf -r b86e062f2335 .hgignore --- a/.hgignore Mon Aug 06 19:31:52 2012 +0200 +++ b/.hgignore Mon Aug 06 19:34:24 2012 +0200 @@ -5,6 +5,8 @@ ^html/ \.pyc$ ~$ +\.swp$ \.orig$ \.rej$ \.err$ +^tests/easy_run.sh$ diff -r 37cba4324ccf -r b86e062f2335 contrib/nopushpublish.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contrib/nopushpublish.py Mon Aug 06 19:34:24 2012 +0200 @@ -0,0 +1,36 @@ +# Extension which prevent changeset to be turn public by push operation +# +# Copyright 2011 Logilab SA +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + + +from mercurial import extensions, util +from mercurial import discovery + +def checkpublish(orig, repo, remote, outgoing, *args): + + # is remote publishing? + publish = True + if 'phases' in remote.listkeys('namespaces'): + remotephases = remote.listkeys('phases') + publish = remotephases.get('publishing', False) + + npublish = 0 + if publish: + for rev in outgoing.missing: + if repo[rev].phase(): + npublish += 1 + if npublish: + repo.ui.warn("Push would publish %s changesets" % npublish) + + ret = orig(repo, remote, outgoing, *args) + if npublish: + raise util.Abort("Publishing push forbiden", + hint="Use `hg phase -p ` to manually publish them") + + return ret + +def uisetup(ui): + extensions.wrapfunction(discovery, 'checkheads', checkpublish) diff -r 37cba4324ccf -r b86e062f2335 docs/evolve-faq.rst --- a/docs/evolve-faq.rst Mon Aug 06 19:31:52 2012 +0200 +++ b/docs/evolve-faq.rst Mon Aug 06 19:34:24 2012 +0200 @@ -96,9 +96,9 @@ Getting changes out of a commit ------------------------------------------------------------ -the ``hg uncommit`` commands allow you to rewrite the current commit to not -include change for some file. The content of target files are not altered on -disk and back as "modified":: +The ``hg uncommit`` command lets you rewrite the parent commit without +selected changed files. Target files content is not altered and +appears again as "modified":: $ hg st M babar @@ -112,8 +112,7 @@ Split a changeset ----------------------- -I you just want to split whole file, you can just use the ``uncommit`` command. - +To split on file boundaries, just use ``uncommit`` command. If you need fine-grained split, there is no official command for that yet. However, it is easily achieved by manual operation:: @@ -223,8 +222,8 @@ Extinct changesets are hidden using the *hidden* feature of mercurial. -Only ``hg log`` and ``hgview`` support it. ``hg glog`` Only support that since -2.2. Other visual viewer don't. +Only ``hg log``, ``hg glog`` and ``hgview`` support it, other +graphical viewer do not. diff -r 37cba4324ccf -r b86e062f2335 docs/from-mq.rst --- a/docs/from-mq.rst Mon Aug 06 19:31:52 2012 +0200 +++ b/docs/from-mq.rst Mon Aug 06 19:34:24 2012 +0200 @@ -84,7 +84,7 @@ hg qref -X ```````````` -To remove change from you current commit use:: +To remove changes from you current commit use:: $ hg uncommit not-ready.txt diff -r 37cba4324ccf -r b86e062f2335 docs/tutorials/tutorial.t --- a/docs/tutorials/tutorial.t Mon Aug 06 19:31:52 2012 +0200 +++ b/docs/tutorials/tutorial.t Mon Aug 06 19:34:24 2012 +0200 @@ -223,7 +223,7 @@ adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) - (run 'hg update' to get a working copy) + (run 'hg heads .' to see heads, 'hg merge' to merge) I now have a new heads. Note that this remote head is immutable @@ -585,7 +585,7 @@ | | @ ffa278c50818 (draft): bathroom stuff | | - o | 8a79ae8b029e (draft): bathroom stuff + x | 8a79ae8b029e (draft): bathroom stuff |/ o a2fccc2e7b08 (public): SPAM SPAM | @@ -610,7 +610,7 @@ pushing to $TESTTMP/other searching for changes abort: push includes an unstable changeset: 9ac5d0e790a2! - (use 'hg stabilize' to get a stable history (or --force to proceed)) + (use 'hg stabilize' to get a stable history or --force to ignore warnings) [255] @@ -723,7 +723,7 @@ $ hg log -G o ae45c0c3092a (draft): SPAM SPAM SPAM | - o 437efbcaf700 (draft): animals + x 437efbcaf700 (draft): animals | @ ffa278c50818 (draft): bathroom stuff | diff -r 37cba4324ccf -r b86e062f2335 enable.sh --- a/enable.sh Mon Aug 06 19:31:52 2012 +0200 +++ b/enable.sh Mon Aug 06 19:34:24 2012 +0200 @@ -3,8 +3,8 @@ here=`python -c "import os; print os.path.realpath('$0')"` repo_root=`dirname "$here"` -if !( hg --version -q | grep -qe 'version 2\.[2-9]' ); then - echo 'You need mercurial 2.2 or later' >&2 +if !( hg --version -q | grep -qe 'version 2\.[3-9]' ); then + echo 'You need mercurial 2.3 or later' >&2 exit 2 fi diff -r 37cba4324ccf -r b86e062f2335 hgext/evolve.py --- a/hgext/evolve.py Mon Aug 06 19:31:52 2012 +0200 +++ b/hgext/evolve.py Mon Aug 06 19:34:24 2012 +0200 @@ -634,7 +634,11 @@ lock.release() def graftwrapper(orig, ui, repo, *revs, **kwargs): + kwargs = dict(kwargs) + revs = list(revs) + kwargs.get('rev', []) + kwargs['rev'] = [] obsoleted = kwargs.setdefault('obsolete', []) + lock = repo.lock() try: if kwargs.get('old_obsolete'): diff -r 37cba4324ccf -r b86e062f2335 hgext/obsolete.py --- a/hgext/obsolete.py Mon Aug 06 19:31:52 2012 +0200 +++ b/hgext/obsolete.py Mon Aug 06 19:34:24 2012 +0200 @@ -31,47 +31,15 @@ Usage and Feature ================= -Display and Exchange --------------------- - -obsolete changesets are hidden. (except if they have non obsolete changeset) - -obsolete changesets are not exchanged. This will probably change later but it -was the simpler solution for now. New commands ------------ Note that rebased changesets are now marked obsolete instead of being stripped. -Context object --------------- - -Context gains a ``obsolete`` method that will return True if a changeset is -obsolete False otherwise. - -revset ------- - -Add an ``obsolete()`` entry. - -repo extension --------------- - -To Do -~~~~~ - -- refuse to obsolete published changesets - -- handle split - -- handle conflict - -- handle unstable // out of sync - """ -import os +import os, sys try: from cStringIO import StringIO except ImportError: @@ -79,7 +47,6 @@ from mercurial.i18n import _ -import base64 import json import struct @@ -104,6 +71,8 @@ from mercurial import localrepo from mercurial import cmdutil from mercurial import templatekw +from mercurial import obsolete +obsolete._enabled = True try: from mercurial.localrepo import storecache @@ -116,14 +85,6 @@ ### Patch changectx ############################# -def obsolete(ctx): - """is the changeset obsolete by other""" - if ctx.node()is None: - return False - return bool(ctx._repo.obsoletedby(ctx.node())) and ctx.phase() - -context.changectx.obsolete = obsolete - def unstable(ctx): """is the changeset unstable (have obsolete ancestor)""" if ctx.node() is None: @@ -161,44 +122,51 @@ ############################# def revsethidden(repo, subset, x): - """hidden changesets""" + """``hidden()`` + Changeset is hidden. + """ args = revset.getargs(x, 0, 0, 'hidden takes no argument') - return [r for r in subset if r in repo.changelog.hiddenrevs] + return [r for r in subset if r in repo.hiddenrevs] def revsetobsolete(repo, subset, x): - """obsolete changesets""" + """``obsolete()`` + Changeset is obsolete. + """ args = revset.getargs(x, 0, 0, 'obsolete takes no argument') return [r for r in subset if r in repo._obsoleteset and repo._phasecache.phase(repo, r) > 0] -# XXX Backward compatibility, to be removed once stabilized -if '_phasecache' not in vars(localrepo.localrepository): # new api - def revsetobsolete(repo, subset, x): - """obsolete changesets""" - args = revset.getargs(x, 0, 0, 'obsolete takes no argument') - return [r for r in subset if r in repo._obsoleteset and repo._phaserev[r] > 0] - def revsetunstable(repo, subset, x): - """non obsolete changesets descendant of obsolete one""" + """``unstable()`` + Unstable changesets are non-obsolete with obsolete ancestors. + """ args = revset.getargs(x, 0, 0, 'unstable takes no arguments') return [r for r in subset if r in repo._unstableset] def revsetsuspended(repo, subset, x): - """obsolete changesets with non obsolete descendants""" + """``suspended()`` + Obsolete changesets with non-obsolete descendants. + """ args = revset.getargs(x, 0, 0, 'suspended takes no arguments') return [r for r in subset if r in repo._suspendedset] def revsetextinct(repo, subset, x): - """obsolete changesets without obsolete descendants""" + """``extinct()`` + Obsolete changesets with obsolete descendants only. + """ args = revset.getargs(x, 0, 0, 'extinct takes no arguments') return [r for r in subset if r in repo._extinctset] def revsetlatecomer(repo, subset, x): - """latecomer, Try to succeed to public change""" + """``latecomer()`` + Changesets marked as successors of public changesets. + """ args = revset.getargs(x, 0, 0, 'latecomer takes no arguments') return [r for r in subset if r in repo._latecomerset] def revsetconflicting(repo, subset, x): - """conflicting, Try to succeed to public change""" + """``conflicting()`` + Changesets marked as successors of a same changeset. + """ args = revset.getargs(x, 0, 0, 'conflicting takes no arguments') return [r for r in subset if r in repo._conflictingset] @@ -215,7 +183,9 @@ return cs def revsetprecursors(repo, subset, x): - """precursors of a subset""" + """``precursors(set)`` + Immediate precursors of changesets in set. + """ s = revset.getset(repo, range(len(repo)), x) cs = _precursors(repo, s) return [r for r in subset if r in cs] @@ -241,7 +211,9 @@ return cs def revsetallprecursors(repo, subset, x): - """obsolete parents""" + """``allprecursors(set)`` + Transitive precursors of changesets in set. + """ s = revset.getset(repo, range(len(repo)), x) cs = _allprecursors(repo, s) return [r for r in subset if r in cs] @@ -260,7 +232,9 @@ return cs def revsetsuccessors(repo, subset, x): - """successors of a subset""" + """``successors(set)`` + Immediate successors of changesets in set. + """ s = revset.getset(repo, range(len(repo)), x) cs = _successors(repo, s) return [r for r in subset if r in cs] @@ -286,7 +260,9 @@ return cs def revsetallsuccessors(repo, subset, x): - """obsolete parents""" + """``allsuccessors(set)`` + Transitive successors of changesets in set. + """ s = revset.getset(repo, range(len(repo)), x) cs = _allsuccessors(repo, s) return [r for r in subset if r in cs] @@ -424,62 +400,9 @@ except KeyError: pass # rebase not found -# Pushkey mechanism for mutable -######################################### - -def listmarkers(repo): - """List markers over pushkey""" - if not repo.obsstore: - return {} - data = repo.obsstore._writemarkers() - encdata = base85.b85encode(data) - return {'dump0': encdata, - 'dump': encdata} # legacy compat - -def pushmarker(repo, key, old, new): - """Push markers over pushkey""" - if not key.startswith('dump'): - repo.ui.warn(_('unknown key: %r') % key) - return 0 - if old: - repo.ui.warn(_('unexpected old value') % key) - return 0 - data = base85.b85decode(new) - lock = repo.lock() - try: - try: - repo.obsstore.mergemarkers(data) - return 1 - except util.Abort: - return 0 - finally: - lock.release() - -pushkey.register('obsolete', pushmarker, listmarkers) - ### Discovery wrapping ############################# -class blist(list, object): - """silly class to have non False but empty list""" - - def __nonzero__(self): - return bool(len(self.orig)) - -def wrapfindcommonoutgoing(orig, repo, *args, **kwargs): - """wrap mercurial.discovery.findcommonoutgoing to remove extinct changeset - - Such excluded changeset are removed from excluded and will *not* appear - are excluded secret changeset. - """ - outgoing = orig(repo, *args, **kwargs) - orig = outgoing.excluded - outgoing.excluded = blist(n for n in orig if not repo[n].extinct()) - # when no revision is specified (push everything) a shortcut is taken when - # nothign was exclude. taking this code path when extinct changeset have - # been excluded leads to repository corruption. - outgoing.excluded.orig = orig - return outgoing def wrapcheckheads(orig, repo, remote, outgoing, *args, **kwargs): """wrap mercurial.discovery.checkheads @@ -489,74 +412,16 @@ """ # do not push instability for h in outgoing.missingheads: - # checking heads only is enought because any thing base on obsolete - # changeset is either obsolete or unstable. - ctx = repo[h] - if ctx.unstable(): - raise util.Abort(_("push includes an unstable changeset: %s!") - % ctx) - if ctx.obsolete(): - raise util.Abort(_("push includes an obsolete changeset: %s!") - % ctx) + # Checking heads is enough, obsolete descendants are either + # obsolete or unstable. + ctx = repo[h] if ctx.latecomer(): - raise util.Abort(_("push includes an latecomer changeset: %s!") + raise util.Abort(_("push includes a latecomer changeset: %s!") % ctx) if ctx.conflicting(): - raise util.Abort(_("push includes conflicting changeset: %s!") + raise util.Abort(_("push includes a conflicting changeset: %s!") % ctx) - ### patch remote branch map - # do not read it this burn eyes - try: - if 'oldbranchmap' not in vars(remote): - remote.oldbranchmap = remote.branchmap - def branchmap(): - newbm = {} - oldbm = None - if (util.safehasattr(phases, 'visiblebranchmap') - and not util.safehasattr(remote, 'ignorevisiblebranchmap') - ): - remote.ignorevisiblebranchmap = False - remote.branchmap = remote.oldbranchmap - oldbm = phases.visiblebranchmap(remote) - remote.branchmap = remote.newbranchmap - remote.ignorevisiblebranchmap = True - if oldbm is None: - oldbm = remote.oldbranchmap() - for branch, nodes in oldbm.iteritems(): - nodes = list(nodes) - new = set() - while nodes: - n = nodes.pop() - if n in repo.obsstore.precursors: - markers = repo.obsstore.precursors[n] - for mark in markers: - for newernode in mark[1]: - if newernode is not None: - nodes.append(newernode) - else: - new.add(n) - if new: - newbm[branch] = list(new) - return newbm - remote.ignorevisiblebranchmap = True - remote.branchmap = branchmap - remote.newbranchmap = branchmap - return orig(repo, remote, outgoing, *args, **kwargs) - finally: - remote.__dict__.pop('branchmap', None) # restore class one - remote.__dict__.pop('oldbranchmap', None) - remote.__dict__.pop('newbranchmap', None) - remote.__dict__.pop('ignorevisiblebranchmap', None) - -# eye are still burning -def wrapvisiblebranchmap(orig, repo): - ignore = getattr(repo, 'ignorevisiblebranchmap', None) - if ignore is None: - return orig(repo) - elif ignore: - return repo.branchmap() - else: - return None # break recursion + return orig(repo, remote, outgoing, *args, **kwargs) def wrapclearcache(orig, repo, *args, **kwargs): try: @@ -571,20 +436,6 @@ cmdtable = {} command = cmdutil.command(cmdtable) -@command('debugobsolete', [], _('SUBJECT OBJECT')) -def cmddebugobsolete(ui, repo, subject, object): - """add an obsolete relation between two nodes - - The subject is expected to be a newer version of the object. - """ - lock = repo.lock() - try: - sub = repo[subject] - obj = repo[object] - repo.addobsolete(sub.node(), obj.node()) - finally: - lock.release() - return 0 @command('debugconvertobsolete', [], '') def cmddebugconvertobsolete(ui, repo): @@ -594,69 +445,77 @@ l = repo.lock() some = False try: - repo._importoldobsolete = True - store = repo.obsstore - ### very first format + unlink = [] + tr = repo.transaction('convert-obsolete') try: - f = repo.opener('obsolete-relations') + repo._importoldobsolete = True + store = repo.obsstore + ### very first format try: + f = repo.opener('obsolete-relations') + try: + some = True + for line in f: + subhex, objhex = line.split() + suc = bin(subhex) + prec = bin(objhex) + sucs = (suc==nullid) and [] or [suc] + meta = { + 'date': '%i %i' % util.makedate(), + 'user': ui.username(), + } + try: + store.create(tr, prec, sucs, 0, meta) + cnt += 1 + except ValueError: + repo.ui.write_err("invalid old marker line: %s" + % (line)) + err += 1 + finally: + f.close() + unlink.append(repo.join('obsolete-relations')) + except IOError: + pass + ### second (json) format + data = repo.sopener.tryread('obsoletemarkers') + if data: some = True - for line in f: - subhex, objhex = line.split() - suc = bin(subhex) - prec = bin(objhex) - sucs = (suc==nullid) and [] or [suc] - meta = { - 'date': '%i %i' % util.makedate(), - 'user': ui.username(), - } + for oldmark in json.loads(data): + del oldmark['id'] # dropped for now + del oldmark['reason'] # unused until then + oldobject = str(oldmark.pop('object')) + oldsubjects = [str(s) for s in oldmark.pop('subjects', [])] + LOOKUP_ERRORS = (error.RepoLookupError, error.LookupError) + if len(oldobject) != 40: + try: + oldobject = repo[oldobject].node() + except LOOKUP_ERRORS: + pass + if any(len(s) != 40 for s in oldsubjects): + try: + oldsubjects = [repo[s].node() for s in oldsubjects] + except LOOKUP_ERRORS: + pass + + oldmark['date'] = '%i %i' % tuple(oldmark['date']) + meta = dict((k.encode('utf-8'), v.encode('utf-8')) + for k, v in oldmark.iteritems()) try: - store.create(prec, sucs, 0, meta) + succs = [bin(n) for n in oldsubjects] + succs = [n for n in succs if n != nullid] + store.create(tr, bin(oldobject), succs, + 0, meta) cnt += 1 except ValueError: - repo.ui.write_err("invalid old marker line: %s" - % (line)) + repo.ui.write_err("invalid marker %s -> %s\n" + % (oldobject, oldsubjects)) err += 1 - finally: - f.close() - util.unlink(repo.join('obsolete-relations')) - except IOError: - pass - ### second (json) format - data = repo.sopener.tryread('obsoletemarkers') - if data: - some = True - for oldmark in json.loads(data): - del oldmark['id'] # dropped for now - del oldmark['reason'] # unused until then - oldobject = str(oldmark.pop('object')) - oldsubjects = [str(s) for s in oldmark.pop('subjects', [])] - LOOKUP_ERRORS = (error.RepoLookupError, error.LookupError) - if len(oldobject) != 40: - try: - oldobject = repo[oldobject].node() - except LOOKUP_ERRORS: - pass - if any(len(s) != 40 for s in oldsubjects): - try: - oldsubjects = [repo[s].node() for s in oldsubjects] - except LOOKUP_ERRORS: - pass - - oldmark['date'] = '%i %i' % tuple(oldmark['date']) - meta = dict((k.encode('utf-8'), v.encode('utf-8')) - for k, v in oldmark.iteritems()) - try: - succs = [bin(n) for n in oldsubjects] - succs = [n for n in succs if n != nullid] - store.create(bin(oldobject), succs, - 0, meta) - cnt += 1 - except ValueError: - repo.ui.write_err("invalid marker %s -> %s\n" - % (oldobject, oldsubjects)) - err += 1 - util.unlink(repo.sjoin('obsoletemarkers')) + unlink.append(repo.sjoin('obsoletemarkers')) + tr.close() + for path in unlink: + util.unlink(path) + finally: + tr.release() finally: del repo._importoldobsolete l.release() @@ -717,26 +576,23 @@ if newconflictings > 0: ui.warn(_('%i new conflictings changesets\n') % newconflictings) -def noextinctsvisibleheads(orig, repo): - repo._turn_extinct_secret() - return orig(repo) - def wrapcmdutilamend(orig, ui, repo, commitfunc, old, *args, **kwargs): oldnode = old.node() new = orig(ui, repo, commitfunc, old, *args, **kwargs) if new != oldnode: lock = repo.lock() try: - meta = { - 'subjects': [new], - 'object': oldnode, - 'date': util.makedate(), - 'user': ui.username(), - 'reason': 'commit --amend', - } - repo.obsstore.create(oldnode, [new], 0, meta) - repo._clearobsoletecache() - repo._turn_extinct_secret() + tr = repo.transaction('post-amend-obst') + try: + meta = { + 'date': '%i %i' % util.makedate(), + 'user': ui.username(), + } + repo.obsstore.create(tr, oldnode, [new], 0, meta) + tr.close() + repo._clearobsoletecache() + finally: + tr.release() finally: lock.release() return new @@ -746,12 +602,8 @@ extensions.wrapcommand(commands.table, "pull", wrapmayobsoletewc) if util.safehasattr(cmdutil, 'amend'): extensions.wrapfunction(cmdutil, 'amend', wrapcmdutilamend) - extensions.wrapfunction(discovery, 'findcommonoutgoing', wrapfindcommonoutgoing) extensions.wrapfunction(discovery, 'checkheads', wrapcheckheads) - extensions.wrapfunction(phases, 'visibleheads', noextinctsvisibleheads) extensions.wrapfunction(phases, 'advanceboundary', wrapclearcache) - if util.safehasattr(phases, 'visiblebranchmap'): - extensions.wrapfunction(phases, 'visiblebranchmap', wrapvisiblebranchmap) ### serialisation ############################# @@ -812,183 +664,6 @@ newer.add(()) return sorted(newer) -### obsolete relation storage -############################# -def add2set(d, key, mark): - """add to a `set` in []""" - d.setdefault(key, []).append(mark) - -def markerid(marker): - KEYS = ['subjects', "object", "date", "user", "reason"] - for key in KEYS: - assert key in marker - keys = sorted(marker.keys()) - a = util.sha1() - for key in keys: - if key == 'subjects': - for sub in sorted(marker[key]): - a.update(sub) - elif key == 'id': - pass - else: - a.update(str(marker[key])) - a.update('\0') - return a.digest() - -# mercurial backport - -def encodemeta(meta): - """Return encoded metadata string to string mapping. - - Assume no ':' in key and no '\0' in both key and value.""" - for key, value in meta.iteritems(): - if ':' in key or '\0' in key: - raise ValueError("':' and '\0' are forbidden in metadata key'") - if '\0' in value: - raise ValueError("':' are forbidden in metadata value'") - return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)]) - -def decodemeta(data): - """Return string to string dictionary from encoded version.""" - d = {} - for l in data.split('\0'): - if l: - key, value = l.split(':') - d[key] = value - return d - -# data used for parsing and writing -_fmversion = 0 -_fmfixed = '>BIB20s' -_fmnode = '20s' -_fmfsize = struct.calcsize(_fmfixed) -_fnodesize = struct.calcsize(_fmnode) - -def _readmarkers(data): - """Read and enumerate markers from raw data""" - off = 0 - diskversion = _unpack('>B', data[off:off + 1])[0] - off += 1 - if diskversion != _fmversion: - raise util.Abort(_('parsing obsolete marker: unknown version %r') - % diskversion) - - # Loop on markers - l = len(data) - while off + _fmfsize <= l: - # read fixed part - cur = data[off:off + _fmfsize] - off += _fmfsize - nbsuc, mdsize, flags, pre = _unpack(_fmfixed, cur) - # read replacement - sucs = () - if nbsuc: - s = (_fnodesize * nbsuc) - cur = data[off:off + s] - sucs = _unpack(_fmnode * nbsuc, cur) - off += s - # read metadata - # (metadata will be decoded on demand) - metadata = data[off:off + mdsize] - if len(metadata) != mdsize: - raise util.Abort(_('parsing obsolete marker: metadata is too ' - 'short, %d bytes expected, got %d') - % (len(metadata), mdsize)) - off += mdsize - yield (pre, sucs, flags, metadata) - -class obsstore(object): - """Store obsolete markers - - Markers can be accessed with two mappings: - - precursors: old -> set(new) - - successors: new -> set(old) - """ - - def __init__(self): - self._all = [] - # new markers to serialize - self._new = [] - self.precursors = {} - self.successors = {} - - def __iter__(self): - return iter(self._all) - - def __nonzero__(self): - return bool(self._all) - - def create(self, prec, succs=(), flag=0, metadata=None): - """obsolete: add a new obsolete marker - - * ensuring it is hashable - * check mandatory metadata - * encode metadata - """ - if metadata is None: - metadata = {} - if len(prec) != 20: - raise ValueError(repr(prec)) - for succ in succs: - if len(succ) != 20: - raise ValueError((succs)) - marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata)) - self.add(marker) - - def add(self, marker): - """Add a new marker to the store - - This marker still needs to be written to disk""" - self._new.append(marker) - self._load(marker) - - def loadmarkers(self, data): - """Load all markers in data, mark them as known.""" - for marker in _readmarkers(data): - self._load(marker) - - def mergemarkers(self, data): - other = set(_readmarkers(data)) - local = set(self._all) - new = other - local - for marker in new: - self.add(marker) - - def flushmarkers(self, stream): - """Write all markers to a stream - - After this operation, "new" markers are considered "known".""" - self._writemarkers(stream) - self._new[:] = [] - - def _load(self, marker): - self._all.append(marker) - pre, sucs = marker[:2] - self.precursors.setdefault(pre, set()).add(marker) - for suc in sucs: - self.successors.setdefault(suc, set()).add(marker) - - def _writemarkers(self, stream=None): - # Kept separate from flushmarkers(), it will be reused for - # markers exchange. - if stream is None: - final = [] - w = final.append - else: - w = stream.write - w(_pack('>B', _fmversion)) - for marker in self._all: - pre, sucs, flags, metadata = marker - nbsuc = len(sucs) - format = _fmfixed + (_fmnode * nbsuc) - data = [nbsuc, len(metadata), flags, pre] - data.extend(sucs) - w(_pack(format, *data)) - w(metadata) - if stream is None: - return ''.join(final) - - ### repo subclassing ############################# @@ -998,10 +673,7 @@ if not util.safehasattr(repo.opener, 'tryread'): raise util.Abort('Obsolete extension requires Mercurial 2.2 (or later)') - opull = repo.pull opush = repo.push - olock = repo.lock - o_rollback = repo._rollback o_updatebranchcache = repo.updatebranchcache # /!\ api change in Hg 2.2 (97efd26eb9576f39590812ea9) /!\ @@ -1032,31 +704,13 @@ """return the set of node that make obsolete (sub)""" return set(marker[0] for marker in self.obsstore.successors.get(node, [])) - @storecache('obsstore') - def obsstore(self): - if not getattr(self, '_importoldobsolete', False): - data = repo.opener.tryread('obsolete-relations') - if not data: - data = repo.sopener.tryread('obsoletemarkers') - if data: - raise util.Abort('old format of obsolete marker detected!\n' - 'run `hg debugconvertobsolete` once.') - store = obsstore() - data = self.sopener.tryread('obsstore') - if data: - store.loadmarkers(data) - return store - @util.propertycache def _obsoleteset(self): """the set of obsolete revision""" obs = set() nm = self.changelog.nodemap - for obj in self.obsstore.precursors: - try: # /!\api change in Hg 2.2 (e8d37b78acfb22ae2c1fb126c2)/!\ - rev = nm.get(obj) - except TypeError: #XXX to remove while breaking Hg 2.1 support - rev = nm.get(obj, None) + for prec in self.obsstore.precursors: + rev = nm.get(prec) if rev is not None: obs.add(rev) return obs @@ -1137,16 +791,19 @@ % {'sub': short(sub), 'obj': short(obj)}) lock = self.lock() try: - meta = { - 'date': util.makedate(), - 'user': ui.username(), - 'reason': 'unknown', - } - subs = (sub == nullid) and [] or [sub] - mid = self.obsstore.create(obj, subs, 0, meta) - self._clearobsoletecache() - self._turn_extinct_secret() - return mid + tr = self.transaction('add-obsolete') + try: + meta = { + 'date': '%i %i' % util.makedate(), + 'user': ui.username(), + } + subs = (sub == nullid) and [] or [sub] + mid = self.obsstore.create(tr, obj, subs, 0, meta) + tr.close() + self._clearobsoletecache() + return mid + finally: + tr.release() finally: lock.release() @@ -1155,155 +812,35 @@ # Assume oldnodes are all descendants of a single rev rootrevs = self.revs('roots(%ln)', oldnodes) assert len(rootrevs) == 1, rootrevs - rootnode = self[rootrevs[0]].node() + #rootnode = self[rootrevs[0]].node() for n in oldnodes: self.addobsolete(newnode, n) - def _turn_extinct_secret(self): - """ensure all extinct changeset are secret""" - self._clearobsoletecache() - # this is mainly for safety purpose - # both pull and push - query = '(obsolete() - obsolete()::(unstable() - secret())) - secret()' - expobs = [c.node() for c in repo.set(query)] - phases.retractboundary(repo, 2, expobs) - - ### Disk IO - - def lock(self, *args, **kwargs): - l = olock(*args, **kwargs) - if not getattr(l.releasefn, 'obspatched', False): - oreleasefn = l.releasefn - def releasefn(*args, **kwargs): - if 'obsstore' in vars(self) and self.obsstore._new: - f = self.sopener('obsstore', 'wb', atomictemp=True) - try: - self.obsstore.flushmarkers(f) - f.close() - except: # re-raises - f.discard() - raise - oreleasefn(*args, **kwargs) - releasefn.obspatched = True - l.releasefn = releasefn - return l - - ### pull // push support - def pull(self, remote, *args, **kwargs): - """wrapper around push that push obsolete relation""" - l = repo.lock() - try: - result = opull(remote, *args, **kwargs) - remoteobs = remote.listkeys('obsolete') - if 'dump' in remoteobs: - remoteobs['dump0'] = remoteobs.pop('dump') - if 'dump0' in remoteobs: - for key, values in remoteobs.iteritems(): - if key.startswith('dump'): - data = base85.b85decode(remoteobs['dump0']) - self.obsstore.mergemarkers(data) - self._clearobsoletecache() - self._turn_extinct_secret() - return result - finally: - l.release() - def push(self, remote, *args, **opts): """wrapper around pull that pull obsolete relation""" - self._turn_extinct_secret() try: result = opush(remote, *args, **opts) except util.Abort, ex: - hint = _("use 'hg stabilize' to get a stable history (or --force to proceed)") + hint = _("use 'hg stabilize' to get a stable history " + "or --force to ignore warnings") if (len(ex.args) >= 1 and ex.args[0].startswith('push includes ') and ex.hint is None): ex.hint = hint raise - if 'obsolete' in remote.listkeys('namespaces') and self.obsstore: - data = self.obsstore._writemarkers() - r = remote.pushkey('obsolete', 'dump0', '', - base85.b85encode(data)) - if not r: - self.ui.warn(_('failed to push obsolete markers!\n')) - self._turn_extinct_secret() - return result - ### rollback support - - # /!\ api change in Hg 2.2 (97efd26eb9576f39590812ea9) /!\ - if util.safehasattr(repo, '_journalfiles'): # Hg 2.2 - def _journalfiles(self): - return o_journalfiles() + (self.sjoin('journal.obsstore'),) - - def _writejournal(self, desc): - """wrapped version of _writejournal that save obsolete data""" - o_writejournal(desc) - filename = 'obsstore' - filepath = self.sjoin(filename) - if os.path.exists(filepath): - journalname = 'journal.' + filename - journalpath = self.sjoin(journalname) - util.copyfile(filepath, journalpath) - - else: # XXX removing this bloc will break Hg 2.1 support - def _writejournal(self, desc): - """wrapped version of _writejournal that save obsolete data""" - entries = list(o_writejournal(desc)) - filename = 'obsstore' - filepath = self.sjoin(filename) - if os.path.exists(filepath): - journalname = 'journal.' + filename - journalpath = self.sjoin(journalname) - util.copyfile(filepath, journalpath) - entries.append(journalpath) - return tuple(entries) - - def _rollback(self, dryrun, force): - """wrapped version of _rollback that restore obsolete data""" - ret = o_rollback(dryrun, force) - if not (ret or dryrun): #rollback did not failed - src = self.sjoin('undo.obsstore') - dst = self.sjoin('obsstore') - if os.path.exists(src): - util.rename(src, dst) - elif os.path.exists(dst): - # If no state was saved because the file did not existed before. - os.unlink(dst) - # invalidate cache - self.__dict__.pop('obsstore', None) - return ret - - @storecache('00changelog.i') - def changelog(self): - # << copy pasted from mercurial source - c = changelog.changelog(self.sopener) - if 'HG_PENDING' in os.environ: - p = os.environ['HG_PENDING'] - if p.startswith(self.root): - c.readpending('00changelog.i.a') - # >> end of the copy paste - old = c.__dict__.pop('hiddenrevs', ()) - if old: - ui.warn("old wasn't empty ? %r" % old) - def _sethidden(c, value): - assert not value - - - class hchangelog(c.__class__): - @util.propertycache - def hiddenrevs(c): - shown = ['not obsolete()', '.', 'bookmark()', 'tagged()', - 'public()'] - basicquery = 'obsolete() - (::(%s))' % (' or '.join(shown)) - # !!! self is repo not changelog - result = set(scmutil.revrange(self, [basicquery])) - return result - c.__class__ = hchangelog - return c - repo.__class__ = obsoletingrepo + for arg in sys.argv: + if 'debugc' in arg: + break + else: + data = repo.opener.tryread('obsolete-relations') + if not data: + data = repo.sopener.tryread('obsoletemarkers') + if data: + raise util.Abort('old format of obsolete marker detected!\n' + 'run `hg debugconvertobsolete` once.') diff -r 37cba4324ccf -r b86e062f2335 tests/test-amend.t --- a/tests/test-amend.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-amend.t Mon Aug 06 19:34:24 2012 +0200 @@ -93,7 +93,7 @@ 7384bbcba36f 000000000000 bd19cbe78fbf a34b93d251e4 $ glog - @ 6@foo(secret) amends a34b93d251e49c93d5685ebacad785c73a7e8605 + @ 6@foo(draft) amends a34b93d251e49c93d5685ebacad785c73a7e8605 | o 5@default(draft) resetbranch | diff -r 37cba4324ccf -r b86e062f2335 tests/test-evolve.t --- a/tests/test-evolve.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-evolve.t Mon Aug 06 19:34:24 2012 +0200 @@ -240,15 +240,15 @@ $ glog --hidden o 6:23409eba69a0@default(draft) a nifty feature | - | o 5:e416e48b2742@default(secret) french looks better + | x 5:e416e48b2742@default(draft) french looks better | | | | o 4:f8111a076f09@default(draft) another feature | |/ - | | o 3:524e478d4811@default(secret) fix spelling of Zwei + | | x 3:524e478d4811@default(draft) fix spelling of Zwei | | | - | | o 2:7b36850622b2@default(secret) another feature + | | x 2:7b36850622b2@default(draft) another feature | |/ - | o 1:568a468b60fc@default(draft) a nifty feature + | x 1:568a468b60fc@default(draft) a nifty feature |/ @ 0:e55e0562ee93@default(draft) base @@ -390,9 +390,9 @@ |/ o 0:8685c6d34325@default(draft) add 0 - $ hg graft 3 -O + $ hg graft -r3 -O grafting revision 3 - $ hg graft 1 -o 2 + $ hg graft -r1 -o 2 grafting revision 1 $ glog --hidden @ 6:acb28cd497b7@default(draft) add 1 @@ -401,9 +401,9 @@ | o 4:ce341209337f@default(draft) add 4 | - | o 3:0e84df4912da@default(secret) add 3 + | x 3:0e84df4912da@default(draft) add 3 | | - | o 2:db038628b9e5@default(secret) add 2 + | x 2:db038628b9e5@default(draft) add 2 | | | o 1:73d38bb17fd7@default(draft) add 1 |/ @@ -437,7 +437,7 @@ $ glog --hidden @ 8:920e58bb443b@default(draft) conflict | - | o 7:a5bfd90a2f29@default(secret) conflict + | x 7:a5bfd90a2f29@default(draft) conflict | | o | 6:acb28cd497b7@default(draft) add 1 | | @@ -445,9 +445,9 @@ | | o | 4:ce341209337f@default(draft) add 4 |/ - | o 3:0e84df4912da@default(secret) add 3 + | x 3:0e84df4912da@default(draft) add 3 | | - | o 2:db038628b9e5@default(secret) add 2 + | x 2:db038628b9e5@default(draft) add 2 | | | o 1:73d38bb17fd7@default(draft) add 1 |/ diff -r 37cba4324ccf -r b86e062f2335 tests/test-obsolete-push.t --- a/tests/test-obsolete-push.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-obsolete-push.t Mon Aug 06 19:34:24 2012 +0200 @@ -32,9 +32,9 @@ $ glog --hidden @ 2:244232c2222a@default(unstable/secret) C | - | o 1:6c81ed0049f8@default(extinct/secret) B + | x 1:6c81ed0049f8@default(extinct/draft) B |/ - o 0:1994f17a630e@default(suspended/secret) A + x 0:1994f17a630e@default(suspended/draft) A $ hg init ../clone $ cat > ../clone/.hg/hgrc < hg add "$1" > hg ci -m "add $1" > } + $ getid() { + > hg id --debug -ir "$1" + > } $ alias qlog="hg log --template='{rev}\n- {node|short}\n'" $ hg init local @@ -27,9 +30,21 @@ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ mkcommit obsol_c # 3 created new head - $ hg debugobsolete 3 2 + $ getid 2 + 4538525df7e2b9f09423636c61ef63a4cb872a2d + $ getid 3 + 0d3f46688ccc6e756c7e96cf64c391c411309597 + $ hg debugobsolete 4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 + $ hg debugobsolete + 4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 {'date': '', 'user': 'test'} +Test hidden() revset + + $ qlog -r 'hidden()' --hidden + 2 + - 4538525df7e2 + Test that obsolete changeset are hidden $ qlog @@ -82,7 +97,7 @@ $ hg up 1 -q $ mkcommit "obsol_c'" # 4 (on 1) created new head - $ hg debugobsolete 4 3 + $ hg debugobsolete `getid 3` `getid 4` $ qlog 4 - 725c380fe99b @@ -127,13 +142,13 @@ $ hg glog --template '{rev}:{node|short}@{branch}({obsolete}/{phase}) {desc|firstline}\n' \ > --hidden - @ 5:a7a6f2b5d8a5@default(unstable/secret) add d + @ 5:a7a6f2b5d8a5@default(unstable/draft) add d | | o 4:725c380fe99b@default(stable/draft) add obsol_c' | | - o | 3:0d3f46688ccc@default(suspended/secret) add obsol_c + x | 3:0d3f46688ccc@default(suspended/draft) add obsol_c |/ - | o 2:4538525df7e2@default(extinct/secret) add c + | x 2:4538525df7e2@default(extinct/draft) add c |/ o 1:7c3bad9141dc@default(stable/draft) add b | @@ -144,11 +159,13 @@ $ hg init ../other-new $ hg phase --draft 'secret() - extinct()' # until we fix exclusion + abort: empty revision set + [255] $ hg push ../other-new pushing to ../other-new searching for changes abort: push includes an unstable changeset: a7a6f2b5d8a5! - (use 'hg stabilize' to get a stable history (or --force to proceed)) + (use 'hg stabilize' to get a stable history or --force to ignore warnings) [255] $ hg push -f ../other-new pushing to ../other-new @@ -182,7 +199,7 @@ $ mkcommit obsol_d # 6 created new head 1 new unstables changesets - $ hg debugobsolete 6 5 + $ hg debugobsolete `getid 5` `getid 6` $ qlog 6 - 95de7fc6918d @@ -201,7 +218,7 @@ pushing to ../other-new searching for changes abort: push includes an unstable changeset: 95de7fc6918d! - (use 'hg stabilize' to get a stable history (or --force to proceed)) + (use 'hg stabilize' to get a stable history or --force to ignore warnings) [255] $ hg push ../other-new -f # use f because there is unstability pushing to ../other-new @@ -230,7 +247,7 @@ $ hg push ../other-new pushing to ../other-new searching for changes - no changes found (ignored 0 secret changesets) + no changes found [1] $ hg up -q .^ # 3 @@ -238,7 +255,7 @@ $ mkcommit "obsol_d'" # 7 created new head 1 new unstables changesets - $ hg debugobsolete 7 6 + $ hg debugobsolete `getid 6` `getid 7` $ hg pull -R ../other-new . pulling from . searching for changes @@ -261,55 +278,58 @@ pushing to stuff that doesn't support obsolete - $ hg init ../other-old - > # XXX I don't like this but changeset get published otherwise - > # remove it when we will get a --keep-state flag for push - $ echo '[extensions]' > ../other-old/.hg/hgrc - $ echo "obsolete=!$(echo $(dirname $TESTDIR))/obsolete.py" >> ../other-old/.hg/hgrc - $ hg push ../other-old - pushing to ../other-old - searching for changes - abort: push includes an unstable changeset: 909a0fb57e5d! - (use 'hg stabilize' to get a stable history (or --force to proceed)) - [255] - $ hg push -f ../other-old - pushing to ../other-old - searching for changes - adding changesets - adding manifests - adding file changes - added 5 changesets with 5 changes to 5 files (+1 heads) - $ qlog -R ../other-old - 4 - - 909a0fb57e5d - 3 - - 725c380fe99b - 2 - - 0d3f46688ccc - 1 - - 7c3bad9141dc - 0 - - 1f0dee641bb7 +DISABLED. the _enable switch it global :-/ + +.. $ hg init ../other-old +.. > # XXX I don't like this but changeset get published otherwise +.. > # remove it when we will get a --keep-state flag for push +.. $ echo '[extensions]' > ../other-old/.hg/hgrc +.. $ echo "obsolete=!$(echo $(dirname $TESTDIR))/obsolete.py" >> ../other-old/.hg/hgrc +.. $ hg push ../other-old +.. pushing to ../other-old +.. searching for changes +.. abort: push includes an unstable changeset: 909a0fb57e5d! +.. (use 'hg stabilize' to get a stable history or --force to ignore warnings) +.. [255] +.. $ hg push -f ../other-old +.. pushing to ../other-old +.. searching for changes +.. adding changesets +.. adding manifests +.. adding file changes +.. added 5 changesets with 5 changes to 5 files (+1 heads) +.. $ qlog -R ../other-ol +.. 4 +.. - 909a0fb57e5d +.. 3 +.. - 725c380fe99b +.. 2 +.. - 0d3f46688ccc +.. 1 +.. - 7c3bad9141dc +.. 0 +.. - 1f0dee641bb7 clone support $ hg clone . ../cloned > # The warning should go away once we have default value to set ready before we pull - requesting all changes - adding changesets - adding manifests - adding file changes - added 5 changesets with 5 changes to 5 files (+1 heads) updating to branch default 4 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ qlog -R ../cloned + $ qlog -R ../cloned --hidden + 7 + - 909a0fb57e5d + 6 + - 95de7fc6918d + 5 + - a7a6f2b5d8a5 4 - - 909a0fb57e5d + - 725c380fe99b 3 - - 725c380fe99b + - 0d3f46688ccc 2 - - 0d3f46688ccc + - 4538525df7e2 1 - 7c3bad9141dc 0 @@ -322,7 +342,7 @@ $ mkcommit "obsol_d''" created new head 1 new unstables changesets - $ hg debugobsolete 8 7 + $ hg debugobsolete `getid 7` `getid 8` $ cd ../other-new $ hg up -q 3 $ hg pull ../local/ @@ -379,8 +399,10 @@ created new head $ hg id -n 9 - $ hg debugobsolete 9 0 - 83b5778897ad try to obsolete immutable changeset 1f0dee641bb7 + $ hg debugobsolete `getid 0` `getid 9` +83b5778897ad try to obsolete immutable changeset 1f0dee641bb7 +# at core level the warning is not issued +# this is now a big issue now that we have latecomer warning $ qlog -r 'obsolete()' 3 - 0d3f46688ccc @@ -400,7 +422,7 @@ 0 - 1f0dee641bb7 - $ hg debugobsolete null 9 #kill + $ hg debugobsolete `getid 9` #kill $ hg up null -q # to be not based on 9 anymore $ qlog 8 @@ -421,29 +443,29 @@ | | o 4 - 725c380fe99b | | - o | 3 - 0d3f46688ccc + x | 3 - 0d3f46688ccc |/ o 1 - 7c3bad9141dc | o 0 - 1f0dee641bb7 - $ hg glog --template='{rev} - {node|short}\n' `(hg --version | grep -q 'version 2.1') || echo '--hidden'` - o 9 - 83b5778897ad + $ hg glog --template='{rev} - {node|short}\n' --hidden + x 9 - 83b5778897ad o 8 - 159dfc9fa5d3 | - | o 7 - 909a0fb57e5d + | x 7 - 909a0fb57e5d |/ - | o 6 - 95de7fc6918d + | x 6 - 95de7fc6918d |/ - | o 5 - a7a6f2b5d8a5 + | x 5 - a7a6f2b5d8a5 |/ | o 4 - 725c380fe99b | | - o | 3 - 0d3f46688ccc + x | 3 - 0d3f46688ccc |/ - | o 2 - 4538525df7e2 + | x 2 - 4538525df7e2 |/ o 1 - 7c3bad9141dc | @@ -477,7 +499,7 @@ $ hg up -q 10 $ mkcommit "obsol_d'''" created new head - $ hg debugobsolete 12 11 + $ hg debugobsolete `getid 11` `getid 12` $ hg push ../other-new --traceback pushing to ../other-new searching for changes @@ -517,8 +539,8 @@ $ hg push ../other-new/ pushing to ../other-new/ searching for changes - abort: push includes an latecomer changeset: 6db5e282cb91! - (use 'hg stabilize' to get a stable history (or --force to proceed)) + abort: push includes a latecomer changeset: 6db5e282cb91! + (use 'hg stabilize' to get a stable history or --force to ignore warnings) [255] Check hg commit --amend compat @@ -578,7 +600,7 @@ 159dfc9fa5d3 9468a5f5d8b2 1f0dee641bb7 83b5778897ad 4538525df7e2 0d3f46688ccc - 83b5778897ad 000000000000 + 83b5778897ad 909a0fb57e5d 159dfc9fa5d3 9468a5f5d8b2 6db5e282cb91 95de7fc6918d 909a0fb57e5d @@ -595,7 +617,7 @@ branch: default commit: (clean) update: 9 new changesets, 9 branch heads (merge) - $ hg debugobsolete 50f11e5e3a63 a7a6f2b5d8a5 + $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63` $ hg log -r 'conflicting()' changeset: 14:50f11e5e3a63 tag: tip diff -r 37cba4324ccf -r b86e062f2335 tests/test-qsync.t --- a/tests/test-qsync.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-qsync.t Mon Aug 06 19:34:24 2012 +0200 @@ -182,7 +182,6 @@ pulling from ../local2 searching for changes no changes found - (run 'hg update' to get a working copy) $ hg pull --mq ../local2/.hg/patches pulling from ../local2/.hg/patches searching for changes diff -r 37cba4324ccf -r b86e062f2335 tests/test-stabilize-order.t --- a/tests/test-stabilize-order.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-stabilize-order.t Mon Aug 06 19:34:24 2012 +0200 @@ -54,9 +54,9 @@ | | | | o 3:7a7552255fb5@default(draft) addc | | | - | | o 2:ef23d6ef94d6@default(draft) addb + | | x 2:ef23d6ef94d6@default(draft) addb | |/ - | o 1:93418d2c0979@default(draft) adda + | x 1:93418d2c0979@default(draft) adda |/ o 0:c471ef929e6a@default(draft) addroot @@ -77,9 +77,9 @@ | | o 3:7a7552255fb5@default(draft) addc | | - | o 2:ef23d6ef94d6@default(draft) addb + | x 2:ef23d6ef94d6@default(draft) addb | | - | o 1:93418d2c0979@default(draft) adda + | x 1:93418d2c0979@default(draft) adda |/ o 0:c471ef929e6a@default(draft) addroot @@ -135,7 +135,7 @@ | | o 9:5e819fbb0d27@default(draft) addc | | - | o 8:6bf44048e43f@default(draft) addb + | x 8:6bf44048e43f@default(draft) addb |/ o 7:f5ff10856e5a@default(draft) adda | diff -r 37cba4324ccf -r b86e062f2335 tests/test-stabilize-result.t --- a/tests/test-stabilize-result.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-stabilize-result.t Mon Aug 06 19:34:24 2012 +0200 @@ -37,11 +37,11 @@ $ glog --hidden @ 4:1447e1c4828d@default(draft) bk:[changea] changea | - | o 3:41ad4fe8c795@default(secret) bk:[] amends 102a90ea7b4a3361e4082ed620918c261189a36a + | x 3:41ad4fe8c795@default(draft) bk:[] amends 102a90ea7b4a3361e4082ed620918c261189a36a | | - | | o 2:cce2c55b8965@default(secret) bk:[] changea + | | x 2:cce2c55b8965@default(draft) bk:[] changea | |/ - | o 1:102a90ea7b4a@default(secret) bk:[] addb + | x 1:102a90ea7b4a@default(draft) bk:[] addb |/ o 0:07f494440405@default(draft) bk:[] adda diff -r 37cba4324ccf -r b86e062f2335 tests/test-uncommit.t --- a/tests/test-uncommit.t Mon Aug 06 19:31:52 2012 +0200 +++ b/tests/test-uncommit.t Mon Aug 06 19:34:24 2012 +0200 @@ -220,7 +220,7 @@ $ glog --hidden @ 4:e8db4aa611f6@bar(stable/draft) touncommit | - | o 3:5eb72dbe0cb4@bar(extinct/secret) touncommit + | x 3:5eb72dbe0cb4@bar(extinct/draft) touncommit |/ o 2:f63b90038565@default(stable/draft) merge |\ @@ -263,11 +263,11 @@ R m R n $ glog --hidden - @ 5:c706fe2c12f8@bar(stable/secret) touncommit + @ 5:c706fe2c12f8@bar(stable/draft) touncommit | | o 4:e8db4aa611f6@bar(stable/draft) touncommit |/ - | o 3:5eb72dbe0cb4@bar(extinct/secret) touncommit + | x 3:5eb72dbe0cb4@bar(extinct/draft) touncommit |/ o 2:f63b90038565@default(stable/draft) merge |\