gbp-pq: add --time-mache=N option
authorGuido Günther <agx@sigxcpu.org>
Sat, 30 Jul 2011 08:46:22 +0000 (10:46 +0200)
committerGuido Günther <agx@sigxcpu.org>
Sat, 30 Jul 2011 12:40:44 +0000 (14:40 +0200)
to find the last commit the patch-queue applies to.

gbp-pq
gbp/config.py

diff --git a/gbp-pq b/gbp-pq
index 253b610..3622433 100755 (executable)
--- a/gbp-pq
+++ b/gbp-pq
@@ -167,9 +167,17 @@ def get_maintainer_from_control():
         return None, None
 
 
-def import_quilt_patches(repo, branch, series):
-    """apply a series of quilt patches in the series file 'series' to branch
-       the patch-queue branch for 'branch'"""
+def import_quilt_patches(repo, branch, series, tries):
+    """
+    apply a series of quilt patches in the series file 'series' to branch
+    the patch-queue branch for 'branch'
+
+    @param repo: git repository to work on
+    @param branch: branch to base pqtch queue on
+    @param series; series file to read patches from
+    @param tries: try that many times to apply the patches going back one
+                  commit in the branches history after each failure.
+    """
     if is_pq_branch(branch):
         gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch)
         raise GbpError
@@ -177,18 +185,31 @@ def import_quilt_patches(repo, branch, series):
         pq_branch = pq_branch_name(branch)
 
     if repo.has_branch(pq_branch):
-        raise GbpError, ("Patch queue branch '%s'. already exists. Try 'rebase' instead."
-
-    try:
-        repo.create_branch(pq_branch)
-    except CommandExecFailed:
-        raise GbpError, ("Cannot create patch-queue branch '%s'." % pq_branch)
-    repo.set_branch(pq_branch)
+        raise GbpError, ("Patch queue branch '%s'. already exists. Try 'rebase' instead.")
 
-    queue = PatchQueue.read_series_file(series)
-    for patch in queue:
-        gbp.log.debug("Applying %s" % patch.path)
-        apply_and_commit_patch(repo, patch.path, patch.topic)
+    commits = repo.commits(options=['-%d' % tries], first_parent=True)
+    for commit in commits:
+        try:
+            gbp.log.info("Trying to apply patches at '%s'" % commit)
+            repo.create_branch(pq_branch, commit)
+        except CommandExecFailed:
+            raise GbpError, ("Cannot create patch-queue branch '%s'." % pq_branch)
+
+        repo.set_branch(pq_branch)
+        queue = PatchQueue.read_series_file(series)
+        for patch in queue:
+            gbp.log.debug("Applying %s" % patch.path)
+            try:
+                apply_and_commit_patch(repo, patch.path, patch.topic)
+            except (GbpError, GitRepositoryError, CommandExecFailed):
+                repo.set_branch(branch)
+                repo.delete_branch(pq_branch)
+                break
+        else:
+            # All patches applied successfully
+            break
+    else:
+        raise GbpError, "Couldn't apply patches"
 
 
 def get_mailinfo(patch):
@@ -304,6 +325,7 @@ def main(argv):
     parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
                       help="verbose command execution")
     parser.add_option("--topic", dest="topic", help="in case of 'apply' topic (subdir) to put patch into")
+    parser.add_config_file_option(option_name="time-machine", dest="time_machine", type="int")
     parser.add_config_file_option(option_name="color", dest="color", type='tristate')
 
     (options, args) = parser.parse_args(argv)
@@ -339,7 +361,8 @@ def main(argv):
             export_patches(repo, current, options)
         elif action == "import":
             series = SERIES_FILE
-            import_quilt_patches(repo, current, series)
+            tries = options.time_machine if (options.time_machine > 0) else 1
+            import_quilt_patches(repo, current, series, tries)
             current = repo.get_branch()
             gbp.log.info("Patches listed in '%s' imported on '%s'" %
                           (series, current))
index e416f93..00c7fd6 100644 (file)
@@ -122,6 +122,7 @@ class GbpOptionParser(OptionParser):
                  'author-date-is-committer-date': 'False',
                  'create-missing-branches': 'False',
                  'submodules'      : 'False',
+                 'time-machine'    : 1,
              }
     help = {
              'debian-branch':
@@ -196,6 +197,8 @@ class GbpOptionParser(OptionParser):
                   "Transparently handle submodules in the upstream tree, default is '%(submodules)s'",
              'postimport':
                   "hook run after a successful import, default is '%(postimport)s'",
+             'time-machine':
+                  "don't try head commit only to apply the patch queue but look TIME_MACHINE commits back",
            }
     config_files = [ '/etc/git-buildpackage/gbp.conf',
                      os.path.expanduser('~/.gbp.conf'),