pull: support '--packaging-branch' option and support two modes for '--force' option.
authorwanchao-xu <wanchao.xu@samsung.com>
Fri, 26 Apr 2024 09:09:44 +0000 (17:09 +0800)
committerwanchao-xu <wanchao.xu@samsung.com>
Fri, 26 Apr 2024 09:09:44 +0000 (17:09 +0800)
The 'force' option now has two possible values:
'merge': upstream branch is merged, even if fast-forward is not possible.
'clean': check out a clean copy from the upstream if fast-forward is not possible (i.e. no merge). Local changes are lost in this case.

Change-Id: Id2485c5a15141af39ed24c8922bdb2639e921948
Signed-off-by: wanchao-xu <wanchao.xu@samsung.com>
docs/manpages/gbp-pull.xml
gbp/scripts/pull.py

index 1662383d4c674e1872b25c7c4590e809a13150c5..a3e410d0bb7b59f07e19d4a1b684f6a117d48da7 100644 (file)
       &gbp-pull;
 
       &man.common.options.synopsis;
-      <arg><option>--force</option></arg>
+      <arg><option>--force=</option><replaceable>[merge|clean]</replaceable></arg>
       <arg><option>--all</option></arg>
       <arg><option>--redo-pq</option></arg>
       <arg><option>--[no-]pristine-tar</option></arg>
       <arg><option>--ignore-branch</option></arg>
-      <arg><option>--debian-branch=</option><replaceable>branch_name</replaceable></arg>
+      <group>
+        <arg><option>--debian-branch=</option><replaceable>branch_name</replaceable></arg>
+        <arg><option>--packaging-branch=</option><replaceable>branch_name</replaceable></arg>
+      </group>
       <arg><option>--upstream-branch=</option><replaceable>branch_name</replaceable></arg>
       <arg><option>--track-missing</option></arg>
       <arg><option>--depth=</option><replaceable>depth</replaceable></arg>
       &man.common.options.description;
 
       <varlistentry>
-        <term><option>--force</option></term>
+        <term><option>--force=</option><replaceable>[merge|clean]</replaceable></term>
         <listitem>
          <para>Force a branch update even if this results in a non fast
-         forward update. <warning><para>Forcing a branch update
+         forward update.
+    <emphasis>merge</emphasis> does a git-merge.
+    <emphasis>clean</emphasis> checks out a clean copy from upstream.
+    <warning><para>using <emphasis>clean</emphasis>
          makes you lose your modifications.</para></warning></para>
         </listitem>
       </varlistentry>
          developed on, default is <replaceable>master</replaceable>.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><option>--packaging-branch</option>=<replaceable>branch_name</replaceable>
+        </term>
+        <listitem>
+          <para>The branch the packaging is being maintained on.
+          Alternative to the <emphasis>--debian-branch</emphasis> option.</para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><option>--upstream-branch</option>=<replaceable>branch_name</replaceable>
         </term>
index d8ece7017e636fa82eebecdc6be5b1eac21060dd..61adce3d240ab3687dccbece9576e15dd763d219 100755 (executable)
@@ -38,7 +38,7 @@ def fast_forward_branch(rem_repo, branch, repo, options):
     @return: branch updated or already up to date
     @rtype: boolean
     """
-    update = False
+    update = None
 
     if rem_repo:
         remote = 'refs/remotes/%s/%s' % (rem_repo, branch)
@@ -57,11 +57,14 @@ def fast_forward_branch(rem_repo, branch, repo, options):
         return True
 
     if can_fast_forward:
-        update = True
+        update = 'merge'
     else:
-        if options.force:
-            gbp.log.info("Non-fast forwarding '%s' due to --force" % branch)
-            update = True
+        if options.force == 'merge':
+            gbp.log.info("Non-fast forwarding '%s' due to --force=merge" % branch)
+            update = 'merge'
+        elif options.force == 'clean':
+            gbp.log.info("Checking out clean copy of '%s' due to --force=clean" % branch)
+            update = 'clean'
         else:
             gbp.log.warn("Skipping non-fast forward of '%s' - use --force or "
                          "update manually" % branch)
@@ -71,12 +74,32 @@ def fast_forward_branch(rem_repo, branch, repo, options):
                                                 repo.rev_parse(branch, short=12),
                                                 repo.rev_parse(remote, short=12)))
         if repo.branch == branch:
-            repo.merge(remote)
+            if update == 'merge':
+                repo.merge(remote)
+            elif update == 'clean':
+                # Have to drop our current branch
+                tmpbranch = "_gbptmp-" + branch
+                gbp.log.debug("Checking out '%s' to '%s'" % (remote, tmpbranch))
+                repo.create_branch(tmpbranch, remote)
+                gbp.log.debug("Switching current branch to '%s'" % (tmpbranch))
+                repo.set_branch(tmpbranch)
+                gbp.log.debug("Dropping branch '%s'" % branch)
+                repo.delete_branch(branch)
+                gbp.log.info("Renaming branch '%s' to '%s'" % (tmpbranch, branch))
+                repo.rename_branch(tmpbranch, branch)
         else:
-            sha1 = repo.rev_parse(remote)
-            repo.update_ref("refs/heads/%s" % branch, sha1,
-                            msg="gbp: forward %s to %s" % (branch, remote))
-    return update
+            if can_fast_forward or (update == 'clean'):
+                sha1 = repo.rev_parse(remote)
+                repo.update_ref("refs/heads/%s" % branch, sha1,
+                                msg="gbp: forward %s to %s" % (branch, remote))
+            elif update == 'merge':
+                # Merge other branch, if it cannot be fast-forwarded
+                current_branch = repo.branch
+                repo.set_branch(branch)
+                repo.merge(remote)
+                repo.set_branch(current_branch)
+
+    return True if update is not None else False
 
 
 def build_parser(name):
@@ -90,15 +113,18 @@ def build_parser(name):
     branch_group = GbpOptionGroup(parser, "branch options", "branch update and layout options")
     parser.add_option_group(branch_group)
     branch_group.add_boolean_config_file_option(option_name="ignore-branch", dest="ignore_branch")
-    branch_group.add_option("--force", action="store_true", dest="force", default=False,
-                            help="force a branch update even if it can't be fast forwarded")
+    branch_group.add_option("--force", action="store", dest="force", default=None,
+                            help="force a branch update even if it can't be fast forwarded "
+                            "(valid ACTIONs are 'merge', 'clean')",
+                            metavar='ACTION')
     branch_group.add_option("--all", action="store_true", default=False,
                             help="update all remote-tracking branches that "
                                  "have identical name in the remote")
     branch_group.add_option("--redo-pq", action="store_true", dest="redo_pq", default=False,
                             help="redo the patch queue branch after a pull. Warning: this drops the old patch-queue branch")
     branch_group.add_config_file_option(option_name="upstream-branch", dest="upstream_branch")
-    branch_group.add_config_file_option(option_name="debian-branch", dest="debian_branch")
+    branch_group.add_config_file_option(option_name="debian-branch", dest="packaging_branch")
+    branch_group.add_config_file_option(option_name="packaging-branch", dest="packaging_branch")
     branch_group.add_boolean_config_file_option(option_name="pristine-tar", dest="pristine_tar")
     branch_group.add_boolean_config_file_option(option_name="track-missing", dest="track_missing")
     branch_group.add_option("--depth", action="store", dest="depth", default=0,
@@ -187,7 +213,7 @@ def main(argv):
         repo.fetch(rem_repo, depth=options.depth, tags=True)
 
         fetch_remote = get_remote(repo, current)
-        for branch in [options.debian_branch, options.upstream_branch]:
+        for branch in [options.packaging_branch, options.upstream_branch]:
             if not branch:
                 continue
             if options.track_missing:
@@ -217,7 +243,7 @@ def main(argv):
                 retval = 2
 
         if options.redo_pq:
-            repo.set_branch(options.debian_branch)
+            repo.set_branch(options.packaging_branch)
             Command("gbp")(["pq", "drop"])
             Command("gbp")(["pq", "import"])