[PATCH 4 of 8] commands: add --abandoned flag to push, pull, outgoing, and incoming

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Thu Jun 2 03:38:34 CDT 2011


On Wed, Jun 1, 2011 at 6:42 PM, Martin Geisler <mg at lazybytes.net> wrote:
> # HG changeset patch
> # User Martin Geisler <mg at lazybytes.net>
> # Date 1306919172 -7200
> # Node ID c64031c2591a669eb251e96e9cc0b91776413187
> # Parent  459996b74ce052c8b055bef1192badf464abae28
> commands: add --abandoned flag to push, pull, outgoing, and incoming
>
> The flag makes the commands include abandoned changesets, the default
> is to not transfer abandoned changesets.
>
> Discovery works like normal and the client determines the set of
> common nodes and the remote heads. The client would normally retrieve
> all remote heads is learns about here, but we want to avoid sending
> abandoned changesets when possible.
>
> The client uses localrepo.nonabandoned to have the server prune the
> list of remote heads to only contain the relevant remote heads.
>
> The arguments to nonabandoned is the common nodes that are heads on
> the client and all the remote heads. Based on that, the server can
> determine what heads the client need: an abandoned head is only needed
> if the client already has a head which is abandoned on the server.
>
> Imagine the server has:
>
>          [a]   * --- * ...
>         /     /
>  --- [r] --- * --- * --- * ...
>
> where [r] is the root of the abandoned set and [a] is the node that
> was added to define the abandoned set. All nodes following [r] is
> abandoned here.
>
> If the client has a head in the common set that is a descendent of
> [r], then the client needs [a].
>
> diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
> --- a/mercurial/bundlerepo.py
> +++ b/mercurial/bundlerepo.py
> @@ -293,7 +293,7 @@
>     return bundlerepository(ui, repopath, bundlename)
>
>  def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
> -                     force=False):
> +                     force=False, abandoned=False):
>     '''obtains a bundle of changes incoming from other
>
>     "onlyheads" restricts the returned changes to those reachable from the
> @@ -311,7 +311,8 @@
>     "cleanupfn" must be called without arguments when you're done processing the
>       changes; it closes both the original "other" and the one returned here.
>     '''
> -    tmp = discovery.findcommonincoming(repo, other, heads=onlyheads, force=force)
> +    tmp = discovery.findcommonincoming(repo, other, heads=onlyheads, force=force,
> +                                       abandoned=abandoned)
>     common, incoming, rheads = tmp
>     if not incoming:
>         try:
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -3171,6 +3171,7 @@
>  @command('incoming|in',
>     [('f', 'force', None,
>      _('run even if remote repository is unrelated')),
> +    ('', 'abandoned', False, _('include abandoned changesets')),
>     ('n', 'newest-first', None, _('show newest record first')),
>     ('', 'bundle', '',
>      _('file to store the bundles into'), _('FILE')),
> @@ -3542,6 +3543,7 @@
>
>  @command('outgoing|out',
>     [('f', 'force', None, _('run even when the destination is unrelated')),
> +    ('', 'abandoned', False, _('include abandoned changesets')),
>     ('r', 'rev', [],
>      _('a changeset intended to be included in the destination'), _('REV')),
>     ('n', 'newest-first', None, _('show newest record first')),
> @@ -3690,6 +3692,7 @@
>     [('u', 'update', None,
>      _('update to new branch head if changesets were pulled')),
>     ('f', 'force', None, _('run even when remote repository is unrelated')),
> +    ('', 'abandoned', False, _('include abandoned changesets')),
>     ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
>     ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
>     ('b', 'branch', [], _('a specific branch you would like to pull'),
> @@ -3738,7 +3741,8 @@
>                     "so a rev cannot be specified.")
>             raise util.Abort(err)
>
> -    modheads = repo.pull(other, heads=revs, force=opts.get('force'))
> +    modheads = repo.pull(other, heads=revs, force=opts.get('force'),
> +                         abandoned=opts.get('abandoned'))
>     bookmarks.updatefromremote(ui, repo, other)
>     if checkout:
>         checkout = str(repo.changelog.rev(other.lookup(checkout)))
> @@ -3761,6 +3765,7 @@
>
>  @command('^push',
>     [('f', 'force', None, _('force push')),
> +    ('', 'abandoned', False, _('include abandoned changesets')),
>     ('r', 'rev', [],
>      _('a changeset intended to be included in the destination'),
>      _('REV')),
> @@ -3829,7 +3834,8 @@
>     finally:
>         del repo._subtoppath
>     result = repo.push(other, opts.get('force'), revs=revs,
> -                       newbranch=opts.get('new_branch'))
> +                       newbranch=opts.get('new_branch'),
> +                       abandoned=opts.get('abandoned'))
>
>     result = (result == 0)
>
> diff --git a/mercurial/discovery.py b/mercurial/discovery.py
> --- a/mercurial/discovery.py
> +++ b/mercurial/discovery.py
> @@ -9,7 +9,34 @@
>  from i18n import _
>  import util, setdiscovery, treediscovery
>
> -def findcommonincoming(repo, remote, heads=None, force=False):
> +def findcommonincoming(repo, remote, heads=None, force=False, abandoned=False):
> +    import os
> +    if 'DEBUG' in os.environ:
> +        print 'discovery.findcommonincoming(abandoned=%s)' % abandoned
> +
> +    common, anyinc, rheads = _findcommonincoming(repo, remote, heads, force)
> +
> +    if 'DEBUG' in os.environ:
> +        print '  common:', map(short, common)
> +        print '  anyinc:', anyinc
> +        print '  rheads:', map(short, rheads)
> +
> +    commonheads = [c for c in common if c in repo.heads()]
> +
> +    if not abandoned:
> +        rheads = remote.nonabandoned(rheads, commonheads)

We might want to have something pluggable here so that different
filters can all reduce rheads in a single roundtrip. IIRC Pierre-Yves'
work requires something similar (albeit without additional info like
commonheads).
-parren

> +        if util.all(rh in repo for rh in rheads):
> +             anyinc = False
> +
> +        if 'DEBUG' in os.environ:
> +            print 'discovery.findcommonincoming(abandoned=%s)' % abandoned
> +            print '  anyinc:', anyinc, '(after pruning abandoned)'
> +            print '  rheads:', map(short, rheads), '(after pruning abandoned)'
> +
> +    return common, anyinc, rheads
> +
> +
> +def _findcommonincoming(repo, remote, heads=None, force=False):
>     """Return a tuple (common, anyincoming, heads) used to identify the common
>     subset of nodes between repo and remote.
>
> @@ -27,6 +54,10 @@
>     Please use findcommonoutgoing to compute the set of outgoing nodes to give
>     extensions a good hook into outgoing.
>     """
> +    import os
> +    if 'DEBUG' in os.environ:
> +        print 'discovery._findcommonincoming(heads=%s)' % (heads and
> +                                                           map(short, heads))
>
>     if not remote.capable('getbundle'):
>         return treediscovery.findcommonincoming(repo, remote, heads, force)
> @@ -46,7 +77,8 @@
>     common, anyinc, srvheads = res
>     return (list(common), anyinc, heads or list(srvheads))
>
> -def findcommonoutgoing(repo, other, onlyheads=None, force=False, commoninc=None):
> +def findcommonoutgoing(repo, other, onlyheads=None, force=False, commoninc=None,
> +                       abandoned=False):
>     '''Return a tuple (common, anyoutgoing, heads) used to identify the set
>     of nodes present in repo but not in other.
>
> @@ -58,10 +90,25 @@
>     findcommonincoming(repo, other, force) to avoid recomputing it here.
>
>     The returned tuple is meant to be passed to changelog.findmissing.'''
> -    common, _any, _hds = commoninc or findcommonincoming(repo, other, force=force)
> -    return (common, onlyheads or repo.heads())
> +    import os
> +    if 'DEBUG' in os.environ:
> +        print 'discovery.findcommonoutgoing(onlyheads=%s)' % (onlyheads and
> +                                                              map(short, onlyheads))
>
> -def prepush(repo, remote, force, revs, newbranch):
> +    common, _any, rheads = commoninc or findcommonincoming(repo, other, force=force,
> +                                                           abandoned=True)
> +    if 'DEBUG' in os.environ:
> +        print '  common:', map(short, common)
> +        print '  _any:', _any
> +        print '  rheads:', map(short, rheads)
> +
> +    heads = onlyheads or repo.heads()
> +    if not abandoned:
> +        heads = repo.nonabandoned(heads, rheads)
> +
> +    return (common, heads)
> +
> +def prepush(repo, remote, force, revs, newbranch, abandoned):
>     '''Analyze the local and remote repositories and determine which
>     changesets need to be pushed to the remote. Return value depends
>     on circumstances:
> @@ -75,9 +122,10 @@
>     changegroup is a readable file-like object whose read() returns
>     successive changegroup chunks ready to be sent over the wire and
>     remoteheads is the list of remote heads.'''
> -    commoninc = findcommonincoming(repo, remote, force=force)
> +    commoninc = findcommonincoming(repo, remote, force=force, abandoned=abandoned)
>     common, revs = findcommonoutgoing(repo, remote, onlyheads=revs,
> -                                      commoninc=commoninc, force=force)
> +                                      commoninc=commoninc, force=force,
> +                                      abandoned=abandoned)
>     _common, inc, remoteheads = commoninc
>
>     cl = repo.changelog
> diff --git a/mercurial/hg.py b/mercurial/hg.py
> --- a/mercurial/hg.py
> +++ b/mercurial/hg.py
> @@ -430,7 +430,8 @@
>     if revs:
>         revs = [other.lookup(rev) for rev in revs]
>     other, chlist, cleanupfn = bundlerepo.getremotechanges(ui, repo, other,
> -                                revs, opts["bundle"], opts["force"])
> +                                revs, opts["bundle"], opts["force"],
> +                                opts.get('abandoned'))
>     try:
>         if not chlist:
>             ui.status(_("no changes found\n"))
> @@ -483,7 +484,8 @@
>
>     other = repository(remoteui(repo, opts), dest)
>     common, outheads = discovery.findcommonoutgoing(repo, other, revs,
> -                                                    force=opts.get('force'))
> +                                                    force=opts.get('force'),
> +                                                    abandoned=opts.get('abandoned'))
>     o = repo.changelog.findmissing(common, outheads)
>     if not o:
>         ui.status(_("no changes found\n"))
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -520,6 +520,96 @@
>     def abandoned(self, rev):
>         return self.changelog.abandoned(self[rev].node())
>
> +    def nonabandoned(self, candidates, clientheads):
> +        """remove unnecessary abandoned heads from candidates
> +
> +        - candidates is a list of heads in our repo that that client
> +          is interested in.
> +
> +        - clientheads is a list of heads already present on the client
> +          side.
> +        """
> +        import os
> +        def debug(*msgs):
> +            if 'DEBUG' in os.environ:
> +                for msg in msgs:
> +                    print msg,
> +                print
> +
> +        debug('localrepo.nonabandoned')
> +        debug('  clientheads:', map(short, clientheads))
> +        debug('  candidates:', map(short, candidates))
> +
> +        ancestor = self.changelog.ancestor
> +        newheads = [] # TODO: could we use a set?
> +
> +        def addhead(h):
> +            i = 0
> +            while i < len(newheads):
> +                nh = newheads[i]
> +                an = ancestor(nh, h)
> +                if an == nh:
> +                    del newheads[i]
> +                elif an == h:
> +                    return
> +                else:
> +                    i += 1
> +            newheads.append(h)
> +
> +
> +        for h in candidates:
> +            abandoner = self[h].abandoned()
> +
> +            debug('   our head', short(h), 'is abandoned:', bool(abandoner))
> +            if not abandoner:
> +                debug('    ', short(h), 'is not abandoned => in result')
> +                addhead(h)
> +                continue
> +
> +            if not 'abandon' in self[h].extra():
> +                debug('    ', short(h), 'does not abandon anything')
> +                # We never transfer an abandoned head, unless it
> +                # abandons other candidates.
> +                if h in clientheads:
> +                    # Keep a head if it is already a remote head.
> +                    debug('     ', short(h), 'is already a remote head => in result')
> +                    addhead(h)
> +                continue
> +
> +            debug('    ', short(h), 'is abandoned by', short(abandoner))
> +            if abandoner != h:
> +                addhead(abandoner)
> +
> +            # The root of the abandoned sets of nodes
> +            root = self.changelog.parents(h)[0]
> +
> +            debug('    abandoned set root is', short(root))
> +            for rh in clientheads:
> +                debug('     testing remote head', short(rh), 'for', short(h))
> +                an = ancestor(root, rh)
> +
> +                if an == root:
> +                    # rh is a descendant of root
> +                    debug('     ', short(rh), 'is a descendant of root', short(root))
> +                    addhead(rh)
> +                    if self[rh].abandoned():
> +                        addhead(self[rh].abandoned())
> +                    continue
> +
> +                if an == rh:
> +                    # rh is an ancestor of root
> +                    debug('     ', short(rh), 'is an ancestor of root', short(root))
> +                    for p in self.changelog.parents(root):
> +                        debug('      adding root parent', short(p))
> +                        addhead(p)
> +                    continue
> +                debug('     ', short(rh), 'is unrelated for', short(h))
> +
> +        if 'DEBUG' in os.environ:
> +            debug('  newheads:', map(short, newheads))
> +
> +        return newheads
> +
>     def lookup(self, key):
>         if isinstance(key, int):
>             return self.changelog.node(key)
> @@ -1339,11 +1429,11 @@
>
>         return r
>
> -    def pull(self, remote, heads=None, force=False):
> +    def pull(self, remote, heads=None, force=False, abandoned=False):
>         lock = self.lock()
>         try:
>             tmp = discovery.findcommonincoming(self, remote, heads=heads,
> -                                               force=force)
> +                                               force=force, abandoned=abandoned)
>             common, fetch, rheads = tmp
>             if not fetch:
>                 self.ui.status(_("no changes found\n"))
> @@ -1380,7 +1470,8 @@
>         """
>         pass
>
> -    def push(self, remote, force=False, revs=None, newbranch=False):
> +    def push(self, remote, force=False, revs=None, newbranch=False,
> +             abandoned=False):
>         '''Push outgoing changesets (limited by revs) from the current
>         repository to remote. Return an integer:
>           - 0 means HTTP error *or* nothing to push
> @@ -1403,7 +1494,7 @@
>             lock = remote.lock()
>         try:
>             cg, remote_heads = discovery.prepush(self, remote, force, revs,
> -                                                 newbranch)
> +                                                 newbranch, abandoned)
>             ret = remote_heads
>             if cg is not None:
>                 if unbundle:
> diff --git a/mercurial/revlog.py b/mercurial/revlog.py
> --- a/mercurial/revlog.py
> +++ b/mercurial/revlog.py
> @@ -421,6 +421,12 @@
>         if heads is None:
>             heads = self.heads()
>
> +        # TODO:
> +        #if not abandoned:
> +        #    heads = filter(lambda x: not self.abandoned(x), heads)
> +        #    if 'DEBUG' in os.environ:
> +        #        print '  heads:', map(short, heads), '(after filtering)'
> +
>         common = [self.rev(n) for n in common]
>         heads = [self.rev(n) for n in heads]
>
> diff --git a/tests/test-abandon-abandoned.t b/tests/test-abandon-abandoned.t
> new file mode 100644
> --- /dev/null
> +++ b/tests/test-abandon-abandoned.t
> @@ -0,0 +1,30 @@
> +Test abandoning an abandoning changeset
> +
> +  $ hg init
> +  $ touch a b
> +  $ hg add a
> +  $ hg commit -m a
> +  $ hg add b
> +  $ hg commit -m b
> +
> +  $ hg abandon 1
> +  $ hg log
> +  changeset:   0:3903775176ed
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  summary:     a
> +
> +Abandon the abandoning changeset and 1 is visible again:
> +
> +  $ hg abandon 2
> +  $ hg log
> +  changeset:   1:0e067c57feba
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  summary:     b
> +
> +  changeset:   0:3903775176ed
> +  user:        test
> +  date:        Thu Jan 01 00:00:00 1970 +0000
> +  summary:     a
> +
> diff --git a/tests/test-abandoned.t b/tests/test-abandoned.t
> --- a/tests/test-abandoned.t
> +++ b/tests/test-abandoned.t
> @@ -54,3 +54,576 @@
>   $ hg log --abandoned -r 'abandoned()'
>   1 0b00c28422ee x
>   2 339976ff5010 abandoned
> +
> +hg outgoing
> +===========
> +
> +testing outgoing with no shared abandoned changesets
> +
> +  $ hg out ../empty
> +  comparing with ../empty
> +  searching for changes
> +  0 54dbcd775ef0 init
> +
> +  $ hg out ../base-i
> +  comparing with ../base-i
> +  searching for changes
> +  no changes found
> +  [1]
> +
> +testing outgoing --abandoned with no shared abandoned changesets
> +
> +  $ hg out --abandoned ../empty
> +  comparing with ../empty
> +  searching for changes
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +
> +  $ hg out --abandoned ../base-i
> +  comparing with ../base-i
> +  searching for changes
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +
> +testing outgoing with a shared abandoned changeset
> +
> +  $ hg out ../base-x
> +  comparing with ../base-x
> +  searching for changes
> +  2 339976ff5010 abandoned
> +
> +  $ hg out --abandoned ../base-x
> +  comparing with ../base-x
> +  searching for changes
> +  2 339976ff5010 abandoned
> +
> +hg push
> +=======
> +
> +testing push with no shared abandoned changesets
> +
> +  $ hg push ../empty
> +  pushing to ../empty
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 1 changes to 1 files
> +  $ hg -R ../empty log --abandoned
> +  0 54dbcd775ef0 init
> +  $ hg -R ../empty rollback -q
> +
> +  $ hg push ../base-i
> +  pushing to ../base-i
> +  searching for changes
> +  no changes found
> +
> +testing push --abandoned with no shared abandoned changesets
> +
> +  $ hg push --abandoned ../empty
> +  pushing to ../empty
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 2 changes to 2 files
> +  $ hg -R ../empty log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../empty rollback -q
> +
> +  $ hg push --abandoned ../base-i
> +  pushing to ../base-i
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 1 changes to 1 files
> +  $ hg -R ../base-i log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-i rollback -q
> +
> +testing push with a shared abandoned changeset
> +
> +  $ hg push ../base-x
> +  pushing to ../base-x
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 0 changes to 0 files
> +  $ hg -R ../base-x log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-x rollback -q
> +
> +  $ hg push --abandoned ../base-x
> +  pushing to ../base-x
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 0 changes to 0 files
> +  $ hg -R ../base-x log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-x rollback -q
> +
> +hg incoming
> +===========
> +
> +testing incoming with no shared abandoned changesets
> +
> +  $ cd ../empty
> +  $ hg in ../repo
> +  comparing with ../repo
> +  0 54dbcd775ef0 init
> +
> +  $ cd ../base-i
> +  $ hg in ../repo
> +  comparing with ../repo
> +  searching for changes
> +  no changes found
> +  [1]
> +
> +testing incoming --abandoned with no shared abandoned changesets
> +
> +  $ cd ../empty
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +
> +  $ cd ../base-i
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  searching for changes
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +
> +testing incoming with a shared abandoned changeset
> +
> +  $ cd ../base-x
> +  $ hg in ../repo
> +  comparing with ../repo
> +  searching for changes
> +  2 339976ff5010 abandoned
> +
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  searching for changes
> +  2 339976ff5010 abandoned
> +
> +hg pull
> +=======
> +
> +testing pull with no shared abandoned changesets
> +
> +  $ cd ../empty
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  requesting all 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 log --abandoned
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ cd ../base-i
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  searching for changes
> +  no changes found
> +
> +testing pull --abandoned with no shared abandoned changesets
> +
> +  $ cd ../empty
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  requesting all changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 2 changes to 2 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ cd ../base-i
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 1 changes to 1 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +testing pull with a shared abandoned changeset
> +
> +  $ cd ../base-x
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 0 changes to 0 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 0 changes to 0 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +################################################################
> +Create non-abandoned child changeset y on top of the abandoned
> +changeset x. This makes changeset 2 irrelevant for x.
> +
> +  $ cd ../repo
> +  $ touch y
> +  $ hg commit -A -m y y
> +  created new head
> +  $ hg glog
> +  @  3 4936e3be10e0 y
> +  |
> +  | o  2 339976ff5010 abandoned
> +  |/
> +  o  1 0b00c28422ee x
> +  |
> +  o  0 54dbcd775ef0 init
> +
> +
> +hg outgoing
> +===========
> +
> +testing outgoing
> +
> +  $ hg out ../empty
> +  comparing with ../empty
> +  searching for changes
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  3 4936e3be10e0 y
> +
> +  $ hg out ../base-i
> +  comparing with ../base-i
> +  searching for changes
> +  1 0b00c28422ee x
> +  3 4936e3be10e0 y
> +
> +testing outgoing --abandoned
> +
> +  $ hg out --abandoned ../empty
> +  comparing with ../empty
> +  searching for changes
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +  $ hg out --abandoned ../base-i
> +  comparing with ../base-i
> +  searching for changes
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +testing outgoing with a shared previously-abandoned changeset
> +
> +  $ hg out ../base-x
> +  comparing with ../base-x
> +  searching for changes
> +  3 4936e3be10e0 y
> +
> +  $ hg out --abandoned ../base-x
> +  comparing with ../base-x
> +  searching for changes
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +hg push
> +=======
> +
> +testing push
> +
> +  $ hg push ../empty
> +  pushing to ../empty
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 3 changes to 3 files
> +  $ hg -R ../empty log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../empty rollback -q
> +
> +  $ hg push ../base-i
> +  pushing to ../base-i
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 2 changes to 2 files
> +  $ hg -R ../base-i log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-i rollback -q
> +
> +testing push --abandoned
> +
> +  $ hg push --abandoned ../empty
> +  pushing to ../empty
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 4 changesets with 3 changes to 3 files (+1 heads)
> +  $ hg -R ../empty log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../empty rollback -q
> +
> +  $ hg push --abandoned ../base-i
> +  pushing to ../base-i
> +  searching for changes
> +  abort: push creates new remote heads on branch 'default'!
> +  (did you forget to merge? use push -f to force)
> +  [255]
> +  $ hg push --abandoned --force ../base-i
> +  pushing to ../base-i
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 2 changes to 2 files (+1 heads)
> +  $ hg -R ../base-i log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-i rollback -q
> +
> +testing push with a shared previously-abandoned changeset
> +
> +  $ hg push ../base-x
> +  pushing to ../base-x
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 1 changesets with 1 changes to 1 files
> +  $ hg -R ../base-x log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-x rollback -q
> +
> +  $ hg push --abandoned ../base-x
> +  pushing to ../base-x
> +  searching for changes
> +  abort: push creates new remote heads on branch 'default'!
> +  (did you forget to merge? use push -f to force)
> +  [255]
> +  $ hg push --abandoned --force ../base-x
> +  pushing to ../base-x
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 1 changes to 1 files (+1 heads)
> +  $ hg -R ../base-x log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg -R ../base-x rollback -q
> +
> +hg incoming
> +===========
> +
> +testing incoming
> +
> +  $ cd ../empty
> +  $ hg in ../repo
> +  comparing with ../repo
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  3 4936e3be10e0 y
> +
> +  $ cd ../base-i
> +  $ hg in ../repo
> +  comparing with ../repo
> +  searching for changes
> +  1 0b00c28422ee x
> +  3 4936e3be10e0 y
> +
> +testing incoming --abandoned
> +
> +  $ cd ../empty
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  0 54dbcd775ef0 init
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +  $ cd ../base-i
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  searching for changes
> +  1 0b00c28422ee x
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +testing incoming with a shared previously-abandoned changeset
> +
> +  $ cd ../base-x
> +  $ hg in ../repo
> +  comparing with ../repo
> +  searching for changes
> +  3 4936e3be10e0 y
> +
> +  $ hg in --abandoned ../repo
> +  comparing with ../repo
> +  searching for changes
> +  2 339976ff5010 abandoned
> +  3 4936e3be10e0 y
> +
> +hg pull
> +=======
> +
> +testing pull
> +
> +  $ cd ../empty
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  requesting all changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 3 changes to 3 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ cd ../base-i
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 2 changes to 2 files
> +  (run 'hg update' to get a working copy)
> +  $ hg log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +testing pull --abandoned
> +
> +  $ cd ../empty
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  requesting all changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 4 changesets with 3 changes to 3 files (+1 heads)
> +  (run 'hg heads' to see heads, 'hg merge' to merge)
> +  $ hg log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ cd ../base-i
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 3 changesets with 2 changes to 2 files (+1 heads)
> +  (run 'hg heads' to see heads, 'hg merge' to merge)
> +  $ hg log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +testing pull with a shared previously-abandoned changeset
> +
> +  $ cd ../base-x
> +  $ hg pull ../repo
> +  pulling from ../repo
> +  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 log --abandoned
> +  2 4936e3be10e0 y
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> +
> +  $ hg pull --abandoned ../repo
> +  pulling from ../repo
> +  searching for changes
> +  adding changesets
> +  adding manifests
> +  adding file changes
> +  added 2 changesets with 1 changes to 1 files (+1 heads)
> +  (run 'hg heads' to see heads, 'hg merge' to merge)
> +  $ hg log --abandoned
> +  3 4936e3be10e0 y
> +  2 339976ff5010 abandoned
> +  1 0b00c28422ee x
> +  0 54dbcd775ef0 init
> +  $ hg rollback -q
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>


More information about the Mercurial-devel mailing list