changeset 6740:d959abd665fd stable

topic: teach debug-default-topic-namespace how to clean commit extras
author Anton Shestakov <av6@dwimlabs.net>
date Mon, 11 Mar 2024 16:16:52 -0300
parents c94690f59bea
children cd22d260d8cc
files hgext3rd/topic/__init__.py tests/test-namespaces.t
diffstat 2 files changed, 59 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/topic/__init__.py	Thu Mar 07 14:56:50 2024 -0300
+++ b/hgext3rd/topic/__init__.py	Mon Mar 11 16:16:52 2024 -0300
@@ -1907,6 +1907,7 @@
 @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"""
@@ -1919,9 +1920,52 @@
     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	Thu Mar 07 14:56:50 2024 -0300
+++ b/tests/test-namespaces.t	Mon Mar 11 16:16:52 2024 -0300
@@ -323,6 +323,21 @@
   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 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'