# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737470557 -3600
#      Tue Jan 21 15:42:37 2025 +0100
# Branch heptapod-17-6
# Node ID d0467b93a30d4e2952fa96217c08dc1cad5d1605
# Parent  adb5d49653d610f2d40aa1e675bcc36b6216adc2
StateMaintainer: new `native` property

This is obviously to reduce duplication. It is worthwile to note
that in Heptapod 17.7, it will be equivalent to which subclass is in use
(we still use `HeptapodGitHandler` for native projects with mirrors to Git
in Heptapod 17.6).
That is why we preferred using a property, as it can simply be replaced by
a class attribute later on.

diff --git a/hgext3rd/heptapod/state_maintainer.py b/hgext3rd/heptapod/state_maintainer.py
--- a/hgext3rd/heptapod/state_maintainer.py
+++ b/hgext3rd/heptapod/state_maintainer.py
@@ -119,6 +119,10 @@
     # Methods relying on the expected implemented methods
     #
 
+    @property
+    def native(self):
+        return self.repo.ui.configbool(b'heptapod', b'native')
+
     def is_wiki(self):
         """Tell whether self.repo is the storage for a GitLab wiki"""
         return (self.repo.ui.environ.get(b'GL_REPOSITORY', b'')
@@ -815,7 +819,7 @@
         prune_default_branch = to_prune.pop(default_git_branch, None)
         if (
                 prune_default_branch
-                and ui.configbool(b'heptapod', b'native')
+                and self.native
                 and default_git_branch.startswith(b'branch/')
         ):
             msg = (b"These changes close or prune the Heptapod default "
@@ -936,7 +940,7 @@
             return
 
         ui = self.repo.ui
-        native = ui.configbool(b'heptapod', b'native')
+        native = self.native
         ui.note(b"heptapod_notify_gitlab heptapod.native=%r" % native)
 
         if native and prune_reasons:
# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737470695 -3600
#      Tue Jan 21 15:44:55 2025 +0100
# Branch heptapod-17-6
# Node ID 85ac760749abcf3d64504ae5ba2fac5f24cdcc87
# Parent  d0467b93a30d4e2952fa96217c08dc1cad5d1605
Wikis: forcing the default branch if native

and also stop setting it to `master`.

This is the root resolution for heptapod#1987

diff --git a/heptapod/gitlab/change.py b/heptapod/gitlab/change.py
--- a/heptapod/gitlab/change.py
+++ b/heptapod/gitlab/change.py
@@ -39,6 +39,9 @@
     def is_creation(self):
         return self.before == ZERO_SHA and self.after != ZERO_SHA
 
+    def is_deletion(self):
+        return self.after == ZERO_SHA and self.before != ZERO_SHA
+
     def export_for_hook(self, handler, native=False):
         """Prepare for actual hook sending.
 
diff --git a/hgext3rd/heptapod/state_maintainer.py b/hgext3rd/heptapod/state_maintainer.py
--- a/hgext3rd/heptapod/state_maintainer.py
+++ b/hgext3rd/heptapod/state_maintainer.py
@@ -860,7 +860,7 @@
                                                    before=before_sha,
                                                    after=after_sha)
 
-        if self.is_wiki():
+        if self.is_wiki() and not self.native:
             # GitLab wikis are much hardwired onto 'master' in a Git repo
             on_default = changes.get(gitlab_branch_ref(b'branch/default'))
             if on_default is not None:
@@ -1158,6 +1158,21 @@
         if default_exists and not ref_is_topic(default_ref):
             return
 
+        # The default GitLab branch might not have been set on Wikis
+        # when they went native, see heptapod#1987. For Wikis, the choice
+        # is always 'branch/default'.
+        branch_default_ref = gitlab_branch_ref(b'branch/default')
+        if default_ref is None and self.is_wiki() and self.native:
+            change = changes.get(branch_default_ref)
+            exists = branch_default_ref in self.gitlab_refs
+            if change is not None:
+                # mutating boolean clearer than very long condition in `if`
+                exists &= not change.is_deletion()
+                exists |= change.is_creation()
+            if exists:
+                self.set_default_gitlab_ref(branch_default_ref)
+                return
+
         new_named_branch_refs = set()
         fallback_new_refs = set()
         for ref, change in pycompat.iteritems(changes):
@@ -1187,7 +1202,6 @@
                 )
             return
 
-        branch_default_ref = gitlab_branch_ref(b'branch/default')
         if branch_default_ref in candidate_refs:
             new_default_ref = branch_default_ref
         else:
diff --git a/hgext3rd/heptapod/tests/no_git/test_integration.py b/hgext3rd/heptapod/tests/no_git/test_integration.py
--- a/hgext3rd/heptapod/tests/no_git/test_integration.py
+++ b/hgext3rd/heptapod/tests/no_git/test_integration.py
@@ -211,9 +211,7 @@
 
     sha = fixture.ctx1.hex()
     # for wikis, we duplicate `branch/default` as `master`
-    changes = {}, {b'refs/heads/branch/default': (ZERO_SHA, sha),
-                   b'refs/heads/master': (ZERO_SHA, sha),
-                   }
+    changes = {}, {b'refs/heads/branch/default': (ZERO_SHA, sha)}
     assert notifs == [
         ('pre-receive', changes),
         ('post-receive', changes),
# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737487068 -3600
#      Tue Jan 21 20:17:48 2025 +0100
# Branch heptapod-17-6
# Node ID f34492e3beb2feade9df44809ad051e67e97957a
# Parent  85ac760749abcf3d64504ae5ba2fac5f24cdcc87
Setting version for release

diff --git a/heptapod/VERSION b/heptapod/VERSION
--- a/heptapod/VERSION
+++ b/heptapod/VERSION
@@ -1,1 +1,1 @@
-4.8.1dev0
+4.8.1
# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737487072 -3600
#      Tue Jan 21 20:17:52 2025 +0100
# Branch heptapod-17-6
# Node ID fd7ab05348af792c7756aa2bffa172eafd6f037f
# Parent  f34492e3beb2feade9df44809ad051e67e97957a
Added tag 4.8.1 for changeset f34492e3beb2

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -100,3 +100,4 @@
 051d5d1a5b298a55eaea2f140812353527c1eb2b 4.7.6
 eedd1bdaad2fd98cf68a5c4c05db952096e20bd8 4.7.7
 0592551395b445cf8f1823024a793a65c427c66b 4.8.0
+f34492e3beb2feade9df44809ad051e67e97957a 4.8.1
# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737487089 -3600
#      Tue Jan 21 20:18:09 2025 +0100
# Branch heptapod-17-6
# Node ID 103a3526a0e950b890f086927c9d68e8ee140b47
# Parent  fd7ab05348af792c7756aa2bffa172eafd6f037f
New stable dev cycle

diff --git a/heptapod/VERSION b/heptapod/VERSION
--- a/heptapod/VERSION
+++ b/heptapod/VERSION
@@ -1,1 +1,1 @@
-4.8.1
+4.8.2dev0
# HG changeset patch
# User Georges Racinet <georges.racinet@cloudcrane.io>
# Date 1737488251 -3600
#      Tue Jan 21 20:37:31 2025 +0100
# Node ID 7daa150349b45ec4bcc4694a9db790452e6485ab
# Parent  619676e43dc4f241bfcd4d6a55d0f376fd7f3255
# Parent  103a3526a0e950b890f086927c9d68e8ee140b47
Merged fixes of 4.8.1

These were made for Heptapod 17.6.2

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -100,5 +100,6 @@
 051d5d1a5b298a55eaea2f140812353527c1eb2b 4.7.6
 eedd1bdaad2fd98cf68a5c4c05db952096e20bd8 4.7.7
 0592551395b445cf8f1823024a793a65c427c66b 4.8.0
+f34492e3beb2feade9df44809ad051e67e97957a 4.8.1
 66c09471519c8b80e7ab5d93f2c2435000f3b01e 5.0.0
 0dc18d6bd6efb951678b511510bd7d905ebe18bb 5.0.1
diff --git a/heptapod/gitlab/change.py b/heptapod/gitlab/change.py
--- a/heptapod/gitlab/change.py
+++ b/heptapod/gitlab/change.py
@@ -39,6 +39,9 @@
     def is_creation(self):
         return self.before == ZERO_SHA and self.after != ZERO_SHA
 
+    def is_deletion(self):
+        return self.after == ZERO_SHA and self.before != ZERO_SHA
+
     def export_for_hook(self, handler, native=False):
         """Prepare for actual hook sending.
 
diff --git a/hgext3rd/heptapod/state_maintainer.py b/hgext3rd/heptapod/state_maintainer.py
--- a/hgext3rd/heptapod/state_maintainer.py
+++ b/hgext3rd/heptapod/state_maintainer.py
@@ -119,6 +119,10 @@
     # Methods relying on the expected implemented methods
     #
 
+    @property
+    def native(self):
+        return self.repo.ui.configbool(b'heptapod', b'native')
+
     def is_wiki(self):
         """Tell whether self.repo is the storage for a GitLab wiki"""
         return (self.repo.ui.environ.get(b'GL_REPOSITORY', b'')
@@ -855,7 +859,7 @@
                                                    before=before_sha,
                                                    after=after_sha)
 
-        if self.is_wiki():
+        if self.is_wiki() and not self.native:
             # GitLab wikis are much hardwired onto 'master' in a Git repo
             on_default = changes.get(gitlab_branch_ref(b'branch/default'))
             if on_default is not None:
@@ -935,7 +939,7 @@
             return
 
         ui = self.repo.ui
-        native = ui.configbool(b'heptapod', b'native')
+        native = self.native
         ui.note(b"heptapod_notify_gitlab heptapod.native=%r" % native)
 
         if native and prune_reasons:
@@ -1153,6 +1157,21 @@
         if default_exists and not ref_is_topic(default_ref):
             return
 
+        # The default GitLab branch might not have been set on Wikis
+        # when they went native, see heptapod#1987. For Wikis, the choice
+        # is always 'branch/default'.
+        branch_default_ref = gitlab_branch_ref(b'branch/default')
+        if default_ref is None and self.is_wiki() and self.native:
+            change = changes.get(branch_default_ref)
+            exists = branch_default_ref in self.gitlab_refs
+            if change is not None:
+                # mutating boolean clearer than very long condition in `if`
+                exists &= not change.is_deletion()
+                exists |= change.is_creation()
+            if exists:
+                self.set_default_gitlab_ref(branch_default_ref)
+                return
+
         new_named_branch_refs = set()
         fallback_new_refs = set()
         for ref, change in pycompat.iteritems(changes):
@@ -1182,7 +1201,6 @@
                 )
             return
 
-        branch_default_ref = gitlab_branch_ref(b'branch/default')
         if branch_default_ref in candidate_refs:
             new_default_ref = branch_default_ref
         else:
diff --git a/hgext3rd/heptapod/tests/no_git/test_integration.py b/hgext3rd/heptapod/tests/no_git/test_integration.py
--- a/hgext3rd/heptapod/tests/no_git/test_integration.py
+++ b/hgext3rd/heptapod/tests/no_git/test_integration.py
@@ -210,9 +210,7 @@
 
     sha = fixture.ctx1.hex()
     # for wikis, we duplicate `branch/default` as `master`
-    changes = {}, {b'refs/heads/branch/default': (ZERO_SHA, sha),
-                   b'refs/heads/master': (ZERO_SHA, sha),
-                   }
+    changes = {}, {b'refs/heads/branch/default': (ZERO_SHA, sha)}
     assert notifs == [
         ('pre-receive', changes),
         ('post-receive', changes),