Mercurial > hg
changeset 17090:e64d416b6b94
merge with crew
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 01 Jul 2012 21:19:57 -0500 |
parents | 75f4180509a4 (diff) 0c1d10351869 (current diff) |
children | f7a2849ef8cd |
files | tests/test-histedit-commute tests/test-histedit-commute.out tests/test-histedit-drop tests/test-histedit-drop.out tests/test-histedit-edit tests/test-histedit-edit.out tests/test-histedit-fold tests/test-histedit-fold-non-commute tests/test-histedit-fold-non-commute.out tests/test-histedit-fold.out tests/test-histedit-no-change tests/test-histedit-no-change.out tests/test-histedit-non-commute tests/test-histedit-non-commute-abort tests/test-histedit-non-commute-abort.out tests/test-histedit-non-commute.out tests/test-histedit-outgoing tests/test-histedit-outgoing.out |
diffstat | 12 files changed, 501 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py Mon Jul 02 01:48:12 2012 +0200 +++ b/mercurial/commands.py Sun Jul 01 21:19:57 2012 -0500 @@ -17,7 +17,7 @@ import minirst, revset, fileset import dagparser, context, simplemerge import random, setdiscovery, treediscovery, dagutil, pvec -import phases +import phases, obsolete table = {} @@ -2049,6 +2049,31 @@ flags = repo.known([bin(s) for s in ids]) ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags]))) +@command('debugobsolete', [] + commitopts2, + _('[OBSOLETED [REPLACEMENT] [REPL... ]')) +def debugobsolete(ui, repo, precursor=None, *successors, **opts): + """create arbitrary obsolete marker""" + if precursor is not None: + metadata = {} + if 'date' in opts: + metadata['date'] = opts['date'] + metadata['user'] = opts['user'] or ui.username() + succs = tuple(bin(succ) for succ in successors) + l = repo.lock() + try: + repo.obsstore.create(bin(precursor), succs, 0, metadata) + finally: + l.release() + else: + for mctx in obsolete.allmarkers(repo): + ui.write(hex(mctx.precnode())) + for repl in mctx.succnodes(): + ui.write(' ') + ui.write(hex(repl)) + ui.write(' %X ' % mctx._data[2]) + ui.write(mctx.metadata()) + ui.write('\n') + @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]')) def debugpushkey(ui, repopath, namespace, *keyinfo, **opts): '''access the pushkey key/value protocol
--- a/mercurial/context.py Mon Jul 02 01:48:12 2012 +0200 +++ b/mercurial/context.py Sun Jul 01 21:19:57 2012 -0500 @@ -230,6 +230,10 @@ for d in self._repo.changelog.descendants([self._rev]): yield changectx(self._repo, d) + def obsolete(self): + """True if the changeset is obsolete""" + return self.node() in self._repo.obsstore.obsoleted + def _fileinfo(self, path): if '_manifest' in self.__dict__: try:
--- a/mercurial/localrepo.py Mon Jul 02 01:48:12 2012 +0200 +++ b/mercurial/localrepo.py Sun Jul 01 21:19:57 2012 -0500 @@ -4,12 +4,11 @@ # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. - from node import bin, hex, nullid, nullrev, short from i18n import _ -import repo, changegroup, subrepo, discovery, pushkey +import repo, changegroup, subrepo, discovery, pushkey, obsolete import changelog, dirstate, filelog, manifest, context, bookmarks, phases -import lock, transaction, store, encoding +import lock, transaction, store, encoding, base85 import scmutil, util, extensions, hook, error, revset import match as matchmod import merge as mergemod @@ -192,6 +191,14 @@ def _phasecache(self): return phases.phasecache(self, self._phasedefaults) + @storecache('obsstore') + def obsstore(self): + store = obsolete.obsstore() + data = self.sopener.tryread('obsstore') + if data: + store.loadmarkers(data) + return store + @storecache('00changelog.i') def changelog(self): c = changelog.changelog(self.sopener) @@ -983,6 +990,16 @@ self.store.write() if '_phasecache' in vars(self): self._phasecache.write() + if 'obsstore' in vars(self) and self.obsstore._new: + # XXX: transaction logic should be used here. But for + # now rewriting the whole file is good enough. + f = self.sopener('obsstore', 'wb', atomictemp=True) + try: + self.obsstore.flushmarkers(f) + f.close() + except: # re-raises + f.discard() + raise for k, ce in self._filecache.items(): if k == 'dirstate': continue @@ -1656,6 +1673,11 @@ # Remote is old or publishing all common changesets # should be seen as public phases.advanceboundary(self, phases.public, subset) + + remoteobs = remote.listkeys('obsolete') + if 'dump' in remoteobs: + data = base85.b85decode(remoteobs['dump']) + self.obsstore.mergemarkers(data) finally: lock.release() @@ -1796,6 +1818,12 @@ if not r: self.ui.warn(_('updating %s to public failed!\n') % newremotehead) + if 'obsolete' in self.listkeys('namespaces') and self.obsstore: + data = self.obsstore._writemarkers() + r = remote.pushkey('obsolete', 'dump', '', + base85.b85encode(data)) + if not r: + self.ui.warn(_('failed to push obsolete markers!\n')) finally: if lock is not None: lock.release()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/obsolete.py Sun Jul 01 21:19:57 2012 -0500 @@ -0,0 +1,279 @@ +# obsolete.py - obsolete markers handling +# +# Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org> +# Logilab SA <contact@logilab.fr> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +"""Obsolete markers handling + +An obsolete marker maps an old changeset to a list of new +changesets. If the list of new changesets is empty, the old changeset +is said to be "killed". Otherwise, the old changeset is being +"replaced" by the new changesets. + +Obsolete markers can be used to record and distribute changeset graph +transformations performed by history rewriting operations, and help +building new tools to reconciliate conflicting rewriting actions. To +facilitate conflicts resolution, markers include various annotations +besides old and news changeset identifiers, such as creation date or +author name. + + +Format +------ + +Markers are stored in an append-only file stored in +'.hg/store/obsstore'. + +The file starts with a version header: + +- 1 unsigned byte: version number, starting at zero. + + +The header is followed by the markers. Each marker is made of: + +- 1 unsigned byte: number of new changesets "R", could be zero. + +- 1 unsigned 32-bits integer: metadata size "M" in bytes. + +- 1 byte: a bit field. It is reserved for flags used in obsolete + markers common operations, to avoid repeated decoding of metadata + entries. + +- 20 bytes: obsoleted changeset identifier. + +- N*20 bytes: new changesets identifiers. + +- M bytes: metadata as a sequence of nul-terminated strings. Each + string contains a key and a value, separated by a color ':', without + additional encoding. Keys cannot contain '\0' or ':' and values + cannot contain '\0'. +""" +import struct +from mercurial import util, base85 +from i18n import _ + +_pack = struct.pack +_unpack = struct.unpack + + + +# 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) + +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 + +class marker(object): + """Wrap obsolete marker raw data""" + + def __init__(self, repo, data): + # the repo argument will be used to create changectx in later version + self._repo = repo + self._data = data + self._decodedmeta = None + + def precnode(self): + """Precursor changeset node identifier""" + return self._data[0] + + def succnodes(self): + """List of successor changesets node identifiers""" + return self._data[1] + + def metadata(self): + """Decoded metadata dictionary""" + if self._decodedmeta is None: + self._decodedmeta = decodemeta(self._data[3]) + return self._decodedmeta + + def date(self): + """Creation date as (unixtime, offset)""" + parts = self.metadata()['date'].split(' ') + return (float(parts[0]), int(parts[1])) + +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(prec) + for succ in succs: + if len(succ) != 20: + raise ValueError(prec) + 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) + +def listmarkers(repo): + """List markers over pushkey""" + if not repo.obsstore: + return {} + data = repo.obsstore._writemarkers() + return {'dump': base85.b85encode(data)} + +def pushmarker(repo, key, old, new): + """Push markers over pushkey""" + if key != '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: + repo.obsstore.mergemarkers(data) + return 1 + finally: + lock.release() + +def allmarkers(repo): + """all obsolete markers known in a repository""" + for markerdata in repo.obsstore: + yield marker(repo, markerdata) + +def precursormarkers(ctx): + """obsolete marker making this changeset obsolete""" + for data in ctx._repo.obsstore.precursors.get(ctx.node(), ()): + yield marker(ctx._repo, data) + +def successormarkers(ctx): + """obsolete marker marking this changeset as a successors""" + for data in ctx._repo.obsstore.successors.get(ctx.node(), ()): + yield marker(ctx._repo, data) +
--- a/mercurial/pushkey.py Mon Jul 02 01:48:12 2012 +0200 +++ b/mercurial/pushkey.py Sun Jul 01 21:19:57 2012 -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. -import bookmarks, phases +import bookmarks, phases, obsolete def _nslist(repo): n = {} @@ -16,6 +16,7 @@ _namespaces = {"namespaces": (lambda *x: False, _nslist), "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), "phases": (phases.pushphase, phases.listphases), + "obsolete": (obsolete.pushmarker, obsolete.listmarkers), } def register(namespace, pushkey, listkeys):
--- a/tests/test-bookmarks-pushpull.t Mon Jul 02 01:48:12 2012 +0200 +++ b/tests/test-bookmarks-pushpull.t Sun Jul 01 21:19:57 2012 -0500 @@ -40,6 +40,7 @@ bookmarks phases namespaces + obsolete $ hg debugpushkey ../a bookmarks Y 4e3505fd95835d721066b76e75dbb8cc554d7f77 X 4e3505fd95835d721066b76e75dbb8cc554d7f77 @@ -214,6 +215,7 @@ bookmarks phases namespaces + obsolete $ hg debugpushkey http://localhost:$HGPORT/ bookmarks Y 4efff6d98829d9c824c621afd6e3f01865f5439f foobar 9b140be1080824d768c5a4691a564088eede71f9
--- a/tests/test-debugcomplete.t Mon Jul 02 01:48:12 2012 +0200 +++ b/tests/test-debugcomplete.t Sun Jul 01 21:19:57 2012 -0500 @@ -86,6 +86,7 @@ debugindexdot debuginstall debugknown + debugobsolete debugpushkey debugpvec debugrebuildstate @@ -236,6 +237,7 @@ debugindexdot: debuginstall: debugknown: + debugobsolete: date, user debugpushkey: debugpvec: debugrebuildstate: rev
--- a/tests/test-hook.t Mon Jul 02 01:48:12 2012 +0200 +++ b/tests/test-hook.t Sun Jul 01 21:19:57 2012 -0500 @@ -198,6 +198,7 @@ listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} no changes found listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'} + listkeys hook: HG_NAMESPACE=obsolete HG_VALUES={} listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} adding remote bookmark bar importing bookmark bar
--- a/tests/test-http-proxy.t Mon Jul 02 01:48:12 2012 +0200 +++ b/tests/test-http-proxy.t Sun Jul 01 21:19:57 2012 -0500 @@ -105,20 +105,24 @@ * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob) + * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob) + * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob) + * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob) + * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
--- a/tests/test-https.t Mon Jul 02 01:48:12 2012 +0200 +++ b/tests/test-https.t Sun Jul 01 21:19:57 2012 -0500 @@ -125,6 +125,7 @@ adding file changes added 1 changesets with 4 changes to 4 files warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) + warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) updating to branch default 4 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg verify -R copy-pull @@ -154,6 +155,7 @@ added 1 changesets with 1 changes to 1 files warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=https://localhost:$HGPORT/ + warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) (run 'hg update' to get a working copy) $ cd .. @@ -182,6 +184,7 @@ pulling from https://localhost:$HGPORT/ searching for changes no changes found + warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) cacert mismatch @@ -194,6 +197,7 @@ pulling from https://127.0.0.1:$HGPORT/ searching for changes no changes found + warning: 127.0.0.1 certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) $ hg -R copy-pull pull --config web.cacerts=pub-other.pem abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob) [255] @@ -202,6 +206,7 @@ pulling from https://localhost:$HGPORT/ searching for changes no changes found + warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) Test server cert which isn't valid yet @@ -259,6 +264,7 @@ pulling from https://localhost:$HGPORT/ searching for changes no changes found + warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting) Test https with cacert and fingerprint through proxy
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-obsolete.t Sun Jul 01 21:19:57 2012 -0500 @@ -0,0 +1,143 @@ + + $ mkcommit() { + > echo "$1" > "$1" + > hg add "$1" + > hg ci -m "add $1" + > } + $ getid() { + > hg id --debug -ir "desc('$1')" + > } + + + $ hg init tmpa + $ cd tmpa + +Killing a single changeset without replacement + + $ mkcommit kill_me + $ hg debugobsolete -d '0 0' `getid kill_me` -u babar + $ hg debugobsolete + 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'} + $ cd .. + +Killing a single changeset with replacement + + $ hg init tmpb + $ cd tmpb + $ mkcommit a + $ mkcommit b + $ mkcommit original_c + $ hg up "desc('b')" + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit new_c + created new head + $ hg debugobsolete `getid original_c` `getid new_c` -d '56 12' + $ hg debugobsolete + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + +do it again (it read the obsstore before adding new changeset) + + $ hg up '.^' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit new_2_c + created new head + $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c` + $ hg debugobsolete + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + +Register two markers with a missing node + + $ hg up '.^' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit new_3_c + created new head + $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337 + $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c` + $ hg debugobsolete + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'} + 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'} + + $ cd .. + +Exchange Test +============================ + +Destination repo does not have any data +--------------------------------------- + +Try to pull markers + + $ hg init tmpc + $ cd tmpc + $ hg pull ../tmpb + pulling from ../tmpb + requesting all changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 6 changes to 6 files (+3 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg debugobsolete + ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'} + + $ cd .. + +Try to pull markers + + $ hg init tmpd + $ hg -R tmpb push tmpd + pushing to tmpd + searching for changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 6 changes to 6 files (+3 heads) + $ hg -R tmpd debugobsolete + ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'} + + +Destination repo have existing data +--------------------------------------- + +On pull + + $ hg init tmpe + $ cd tmpe + $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 + $ hg pull ../tmpb + pulling from ../tmpb + requesting all changes + adding changesets + adding manifests + adding file changes + added 6 changesets with 6 changes to 6 files (+3 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg debugobsolete + 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'} + ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'} + +On push + + $ hg push ../tmpc + pushing to ../tmpc + searching for changes + no changes found + [1] + $ hg -R ../tmpc debugobsolete + ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'} + cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'} + 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'} + 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'} + 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}