mercurial/hg.py
changeset 52096 19ae7730636a
parent 51859 f4733654f144
parent 52082 fb15ba66c702
child 52555 85c095c1f8bc
--- a/mercurial/hg.py	Thu Oct 24 15:23:52 2024 +0200
+++ b/mercurial/hg.py	Sat Oct 26 00:58:01 2024 +0200
@@ -1427,60 +1427,6 @@
     )
 
 
-def _outgoing(ui, repo, dests, opts, subpath=None):
-    out = set()
-    others = []
-    for path in urlutil.get_push_paths(repo, ui, dests):
-        dest = path.loc
-        if subpath is not None:
-            subpath = urlutil.url(subpath)
-            if subpath.isabs():
-                dest = bytes(subpath)
-            else:
-                p = urlutil.url(dest)
-                if p.islocal():
-                    normpath = os.path.normpath
-                else:
-                    normpath = posixpath.normpath
-                p.path = normpath(b'%s/%s' % (p.path, subpath))
-                dest = bytes(p)
-        branches = path.branch, opts.get(b'branch') or []
-
-        ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(dest))
-        revs, checkout = addbranchrevs(repo, repo, branches, opts.get(b'rev'))
-        if revs:
-            revs = [repo[rev].node() for rev in logcmdutil.revrange(repo, revs)]
-
-        other = peer(repo, opts, dest)
-        try:
-            outgoing = discovery.findcommonoutgoing(
-                repo, other, revs, force=opts.get(b'force')
-            )
-            o = outgoing.missing
-            out.update(o)
-            if not o:
-                scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
-            others.append(other)
-        except:  # re-raises
-            other.close()
-            raise
-    # make sure this is ordered by revision number
-    outgoing_revs = list(out)
-    cl = repo.changelog
-    outgoing_revs.sort(key=cl.rev)
-    return outgoing_revs, others
-
-
-def _outgoing_recurse(ui, repo, dests, opts):
-    ret = 1
-    if opts.get(b'subrepos'):
-        ctx = repo[None]
-        for subpath in sorted(ctx.substate):
-            sub = ctx.sub(subpath)
-            ret = min(ret, sub.outgoing(ui, dests, opts))
-    return ret
-
-
 def _outgoing_filter(repo, revs, opts):
     """apply revision filtering/ordering option for outgoing"""
     limit = logcmdutil.getlimit(opts)
@@ -1504,37 +1450,94 @@
         yield n
 
 
+def _outgoing_recurse(ui, repo, dests, opts):
+    ret = 1
+    if opts.get(b'subrepos'):
+        ctx = repo[None]
+        for subpath in sorted(ctx.substate):
+            sub = ctx.sub(subpath)
+            ret = min(ret, sub.outgoing(ui, dests, opts))
+    return ret
+
+
+def display_outgoing_revs(ui, repo, o, opts):
+    # make sure this is ordered by revision number
+    cl = repo.changelog
+    o.sort(key=cl.rev)
+    if opts.get(b'graph'):
+        revdag = logcmdutil.graphrevs(repo, o, opts)
+        ui.pager(b'outgoing')
+        displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
+        logcmdutil.displaygraph(
+            ui, repo, revdag, displayer, graphmod.asciiedges
+        )
+    else:
+        ui.pager(b'outgoing')
+        displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
+        for n in _outgoing_filter(repo, o, opts):
+            displayer.show(repo[n])
+            displayer.close()
+
+
+_no_subtoppath = object()
+
+
 def outgoing(ui, repo, dests, opts, subpath=None):
     if opts.get(b'graph'):
         logcmdutil.checkunsupportedgraphflags([], opts)
-    o, others = _outgoing(ui, repo, dests, opts, subpath=subpath)
     ret = 1
-    try:
-        if o:
-            ret = 0
+    for path in urlutil.get_push_paths(repo, ui, dests):
+        dest = path.loc
+        prev_subtopath = getattr(repo, "_subtoppath", _no_subtoppath)
+        try:
+            repo._subtoppath = dest
+            if subpath is not None:
+                subpath = urlutil.url(subpath)
+                if subpath.isabs():
+                    dest = bytes(subpath)
+                else:
+                    p = urlutil.url(dest)
+                    if p.islocal():
+                        normpath = os.path.normpath
+                    else:
+                        normpath = posixpath.normpath
+                    p.path = normpath(b'%s/%s' % (p.path, subpath))
+                    dest = bytes(p)
+            branches = path.branch, opts.get(b'branch') or []
 
-            if opts.get(b'graph'):
-                revdag = logcmdutil.graphrevs(repo, o, opts)
-                ui.pager(b'outgoing')
-                displayer = logcmdutil.changesetdisplayer(
-                    ui, repo, opts, buffered=True
+            ui.status(_(b'comparing with %s\n') % urlutil.hidepassword(dest))
+            revs, checkout = addbranchrevs(
+                repo, repo, branches, opts.get(b'rev')
+            )
+            if revs:
+                revs = [
+                    repo[rev].node() for rev in logcmdutil.revrange(repo, revs)
+                ]
+
+            other = peer(repo, opts, dest)
+            try:
+                outgoing = discovery.findcommonoutgoing(
+                    repo, other, revs, force=opts.get(b'force')
                 )
-                logcmdutil.displaygraph(
-                    ui, repo, revdag, displayer, graphmod.asciiedges
-                )
+                o = outgoing.missing
+                if not o:
+                    scmutil.nochangesfound(repo.ui, repo, outgoing.excluded)
+                else:
+                    ret = 0
+                    display_outgoing_revs(ui, repo, o, opts)
+
+                cmdutil.outgoinghooks(ui, repo, other, opts, o)
+                ret = min(ret, _outgoing_recurse(ui, repo, dests, opts))
+            except:  # re-raises
+                raise
+            finally:
+                other.close()
+        finally:
+            if prev_subtopath is _no_subtoppath:
+                del repo._subtoppath
             else:
-                ui.pager(b'outgoing')
-                displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
-                for n in _outgoing_filter(repo, o, opts):
-                    displayer.show(repo[n])
-                displayer.close()
-        for oth in others:
-            cmdutil.outgoinghooks(ui, repo, oth, opts, o)
-            ret = min(ret, _outgoing_recurse(ui, repo, dests, opts))
-        return ret  # exit code is zero since we found outgoing changes
-    finally:
-        for oth in others:
-            oth.close()
+                repo._subtoppath = prev_subtopath
+    return ret
 
 
 def verify(repo, level=None):