changeset 6744:3076dba01b86

branching: merge with stable
author Anton Shestakov <av6@dwimlabs.net>
date Thu, 14 Mar 2024 15:12:18 -0300
parents 50c0f1e2dfb6 (current diff) cd22d260d8cc (diff)
children 71c4b6c2bcdc
files hgext3rd/topic/__init__.py tests/test-namespaces.t
diffstat 2 files changed, 130 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/topic/__init__.py	Sun Mar 03 15:38:03 2024 -0300
+++ b/hgext3rd/topic/__init__.py	Thu Mar 14 15:12:18 2024 -0300
@@ -179,6 +179,7 @@
     hg,
     localrepo,
     lock as lockmod,
+    logcmdutil,
     merge,
     namespaces,
     node,
@@ -700,31 +701,23 @@
             self._topic_namespaces = namespaces
             return namespaces
 
-        @property
-        def currenttns(self):
-            tns = self.vfs.tryread(b'topic-namespace')
+        def wlock(self, wait=True):
+            wlock = super(topicrepo, self).wlock(wait=wait)
             # we should definitely drop this at some point, but it depends on
             # our own release schedule, not core's, so here's hg 1.0
             # hg <= 1.0 (cfa08c88a5c4)
-            if tns == b'none':
+            if wlock is not None and wlock.held:
                 try:
-                    with self.wlock(wait=False):
-                        try:
-                            # we make sure the file contains what we expect
-                            if self.vfs.read(b'topic-namespace') == b'none':
-                                repo.vfs.unlinkpath(b'topic-namespace')
-                        except IOError as err:
-                            if err.errno != errno.ENOENT:
-                                raise
-                except error.LockError:
-                    # if we cannot acquire wdir lock, then we shouldn't do
-                    # anything at all, since it'd be unsafe to modify wdir
-                    pass
-            elif tns == b'':
-                # technically, if user creates an empty file, it should be
-                # handled differently than non-existing file, but the
-                # distinction is probably not that important
-                tns = b'none'
+                    if self.vfs.read(b'topic-namespace') == b'none':
+                        repo.vfs.unlinkpath(b'topic-namespace')
+                except IOError as err:
+                    if err.errno != errno.ENOENT:
+                        raise
+            return wlock
+
+        @property
+        def currenttns(self):
+            tns = self.vfs.tryread(b'topic-namespace') or b'none'
             return encoding.tolocal(tns)
 
         @util.propertycache
@@ -1843,6 +1836,68 @@
     for tns in repo.topic_namespaces:
         ui.write(b'%s\n' % (tns,))
 
+@command(b'debug-default-topic-namespace', [
+        (b'', b'none', True, b'find changesets with topic-namespace=none'),
+        (b'', b'default', False, b'find changesets with topic-namespace=default'),
+        (b'', b'clear', False, b'remove topic namespace from commit extras'),
+    ] + commands.formatteropts)
+def debugdefaulttns(ui, repo, **opts):
+    """list changesets with the default topic namespace in commit extras"""
+    opts = pycompat.byteskwargs(opts)
+    condition = []
+    if opts[b'none']:
+        condition += [b'extra("topic-namespace", "none")']
+    if opts[b'default']:
+        condition += [b'extra("topic-namespace", "default")']
+    if not condition:
+        condition = [b'none()']
+    revs = repo.revs(b'not public() and not obsolete() and (%lr)', condition)
+    if opts[b'clear']:
+        with repo.wlock(), repo.lock(), repo.transaction(b'debug-default-topic-namespace'):
+            for rev in revs:
+                _clear_tns_extras(ui, repo, rev)
+        return
+    displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
+    logcmdutil.displayrevs(ui, repo, revs, displayer, None)
+
+def _clear_tns_extras(ui, repo, rev):
+    ctx = repo[rev]
+
+    if len(ctx.parents()) > 1:
+        # ctx.files() isn't reliable for merges, so fall back to the
+        # slower repo.status() method
+        st = ctx.p1().status(ctx)
+        files = set(st.modified) | set(st.added) | set(st.removed)
+    else:
+        files = set(ctx.files())
+
+    def filectxfn(repo, unused, path):
+        try:
+            return ctx[path]
+        except error.ManifestLookupError:
+            return None
+
+    extra = ctx.extra().copy()
+    del extra[b'topic-namespace']
+
+    p1 = ctx.p1().node()
+    p2 = ctx.p2().node()
+    mc = context.memctx(repo,
+                        (p1, p2),
+                        ctx.description(),
+                        files,
+                        filectxfn,
+                        user=ctx.user(),
+                        date=ctx.date(),
+                        extra=extra)
+
+    overrides = {(b'phases', b'new-commit'): ctx.phase()}
+    with repo.ui.configoverride(overrides, b'debug-default-topic-namespace'):
+        newnode = repo.commitctx(mc)
+
+    replacements = {(ctx.node(),): (newnode,)}
+    scmutil.cleanupnodes(repo, replacements, b'debug-default-topic-namespace')
+
 @command(b'debug-parse-fqbn', commands.formatteropts, _(b'FQBN'), optionalrepo=True)
 def debugparsefqbn(ui, repo, fqbn, **opts):
     """parse branch//namespace/topic string into its components"""
--- a/tests/test-namespaces.t	Sun Mar 03 15:38:03 2024 -0300
+++ b/tests/test-namespaces.t	Thu Mar 14 15:12:18 2024 -0300
@@ -286,6 +286,60 @@
   abort: topic namespace 'nonsense' does not exist
   [10]
 
+Debug command related to the default/empty topic namespace
+
+  $ hg debug-topic-namespace --clear
+
+  $ echo none > none
+  $ hg ci -qAm 'tns=none' \
+  >    --config extensions.topic=! \
+  >    --config extensions.commitextras= \
+  >    --extra topic-namespace=none
+
+
+  $ echo default > default
+  $ hg ci -qAm 'tns=default' \
+  >   --config extensions.topic=! \
+  >   --config extensions.commitextras= \
+  >   --extra topic-namespace=default
+
+  $ hg debug-default-topic-namespace \
+  >   --debug \
+  >   | grep extra
+  extra:       branch=stable
+  extra:       topic-namespace=none
+
+  $ hg debug-default-topic-namespace \
+  >   --no-none \
+  >   --default \
+  >   --debug \
+  >   | grep extra
+  extra:       branch=stable
+  extra:       topic-namespace=default
+
+  $ hg debug-default-topic-namespace \
+  >   --default \
+  >   -T '{rev}:{node|short} {join(extras, " ")}\n'
+  4:29a2d0acd473 branch=stable topic-namespace=none
+  5:16d6061fce0c branch=stable topic-namespace=default
+
+  $ hg debug-default-topic-namespace --none --default --clear
+  1 new orphan changesets
+
+  $ hg debug-default-topic-namespace --none --default
+
+  $ hg evolve --config extensions.evolve= --any
+  update:[7] tns=default
+  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  working directory is now at 68ef84f4b0a2
+  move:[7] tns=default
+  atop:[6] tns=none
+  working directory is now at ddeaa72064d4
+
+  $ hg debug-default-topic-namespace --none --default
+
+  $ hg verify --quiet
+
 Parsing
 
   $ hg debugparsefqbn foo/bar//user26/feature -T '[{branch}] <{topic_namespace}> ({topic})\n'