[RFC][kteam-tools][PATCH] apply-stable-patches: add option to check commits tagged with 'Fixes:'

Luis Henriques luis.henriques at canonical.com
Thu Feb 26 19:43:00 UTC 2015


This commit adds a new option to also check for commits that have not been
tagged for stable but that contain a 'Fixes:' tag, for a SHA1 that is on
the current branch (both directly or with a 'commit <SHA1> upstream').

Note that this new option does NOT actually apply any patch!  It simply
stores them in a new directory ('Possible-Fixes').  These patches require
extra attention as are likely not suitable for stable trees.

Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
---
 stable/apply-stable-patches | 95 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 89 insertions(+), 6 deletions(-)

diff --git a/stable/apply-stable-patches b/stable/apply-stable-patches
index 12f8376c34a0..ed3e27c3a4ad 100755
--- a/stable/apply-stable-patches
+++ b/stable/apply-stable-patches
@@ -76,6 +76,12 @@ class Cmdline:
 
         --sob            Add 'Signed-off-by:' line to the patches
 
+        --check-fixes    Also check for commits that have not been tagged for stable
+                         but that contain a 'Fixes: <SHA1>' line for a SHA1 that is
+                         on the current branch.  A new directory ('Possible-Fixes')
+                         will be created with these patches, but they will NOT be
+                         applied.
+
         --check-already  Check for already committed ('commit {sha} upstream.')
                          patches
 
@@ -118,8 +124,8 @@ class Cmdline:
         try:
             optsShort = ''
             optsLong  = ['help', 'range=', 'sob', 'verbose', 'config=',
-                         'check-already', 'stop-on-fail', 'debug=',
-                         'name=', 'email=']
+                         'check-already', 'stop-on-fail', 'check-fixes',
+                          'debug=', 'name=', 'email=']
             opts, args = getopt(argv[1:], optsShort, optsLong)
 
             for opt, val in opts:
@@ -135,6 +141,9 @@ class Cmdline:
                 elif (opt == '--check-already'):
                     self.cfg['check_already'] = True
 
+                elif (opt == '--check-fixes'):
+                    self.cfg['check_fixes'] = True
+
                 elif (opt == '--stop-on-fail'):
                     self.cfg['stop_on_fail'] = True
 
@@ -295,6 +304,35 @@ class ApplyStablePatches(StdApp):
                 temp = dst.name
         rename(temp, patch)
 
+    # Check if we have SHA1 in the current branch
+    def check_fix(self, sha1, branch, merge_base):
+        # First, look for stable updates commits since the merge base:
+        # Look for commits with "commit <SHA1> upstream." ...
+        status, res = run_command("git log -1 --grep='^commit %s.* upstream.$' %s..HEAD" % (sha1, merge_base))
+        if status != 0:
+            stdo("\nError processing fix for '%s'.  Ignoring...\n" % (sha1))
+            return False
+        if res[0]:
+            return True
+
+        # ...or "[ Upstream commit <SHA1> ]"
+        status, res = run_command("git log --grep='^\[ Upstream commit %s.* \]$' %s..HEAD" % (sha1, merge_base))
+        if status != 0:
+            stdo("\nError processing fix for '%s'.  Ignoring...\n" % (sha1))
+            return False
+        if res[0]:
+            return True
+
+        # Finally, see if it finds it in the git history (slower operation)
+        status, res = run_command("git branch --contains %s %s" % (sha1, branch))
+        if status != 0:
+            stdo("\nError processing fix for '%s'.  Ignoring...\n" % (sha1))
+            return False
+        if branch == res[0].strip(" *"):
+            return True
+
+        return False
+
     # main
     #
     def main(self):
@@ -315,6 +353,12 @@ class ApplyStablePatches(StdApp):
             if 'sob' not in self.cfg:
                 raise CmdlineError('No "Signed-off-by:" given, you must specify --sob=<sob> option')
 
+            # get current branch name
+            status, result = run_command("git rev-parse --abbrev-ref HEAD")
+            if status != 0:
+                raise GitError("\n".join(result))
+            cur_branch = result[0].strip()
+
             # Fetch latest upstream changes
             stdo("Fetching upstream commits from linux master repository...")
             status, result = run_command("git fetch -q %s master" %
@@ -323,6 +367,11 @@ class ApplyStablePatches(StdApp):
             if status != 0:
                 raise GitError("\n".join(result))
 
+            if 'check_already' in self.cfg or 'check_fixes' in self.cfg:
+		status, result = run_command('git show-branch --merge-base HEAD master')
+		if status == 0:
+		    merge_base=result[0].strip()
+
             # Find commits marked for stable in the provided range, and
             # save hints added for which versions the commit should be
             # backported or cherry-picked
@@ -335,7 +384,9 @@ class ApplyStablePatches(StdApp):
             cc = 1
             ccstable = compile(r'^\s*Cc:.*\b(stable)\b.*', IGNORECASE | MULTILINE)
             cchint = compile(r'((?P<for>\b(for)\b)|(?P<gr>\s*>\s*)|(?P<ge>\s*>=\s*)|(\s*))(?P<v>[v]*)(?P<kver>[0-9]\.[0-9][^\s+,\]]*)(?P<plus>[+]*)[,\]]*((?P<only>[\s]+only)|(?P<later>[\s]+and later)|(\s*))')
+            fixes = compile(r'^\s*Fixes:\s*([a-f0-9]+).*', IGNORECASE | MULTILINE)
             forstable = []
+            fixeslist = []
             for c in result:
                 stdo("\rLooking for stable commits inside provided range (%d/%d)..."
                      % (cc, len(result)))
@@ -358,6 +409,13 @@ class ApplyStablePatches(StdApp):
                     if 'verbose' in self.cfg and forvers:
                         print("")
                     forstable.append([c, forvers])
+                elif 'check_fixes' in self.cfg:
+                    # search for 'Fixes: <SHA1>' lines
+                    s = fixes.search(body)
+                    if s:
+                        sha1 = s.group(1)
+                        if self.check_fix(sha1, cur_branch, merge_base):
+                            fixeslist.append([c, sha1])
                 cc += 1
 
             #stdo("\n")
@@ -428,10 +486,6 @@ class ApplyStablePatches(StdApp):
             if not path.exists(discarded_dir):
                 mkdir(discarded_dir)
             kernel = KernelVersion(Kernel().version())
-	    if 'check_already' in self.cfg:
-		status, result = run_command('git show-branch --merge-base HEAD master')
-		if status == 0:
-		    merge_base=result[0].strip()
             for change in forstable:
                 status, title = run_command('git log -n 1 --format=%%s %s' % (change[0]))
                 if status != 0:
@@ -507,6 +561,35 @@ class ApplyStablePatches(StdApp):
                     move(filename, applied_dir)
                 print("success")
 
+            if 'check_fixes' in self.cfg:
+                stdo("\n\rPossible fixes found:\n")
+                fixes_dir = 'Possible-Fixes'
+                if not path.exists(fixes_dir):
+                    mkdir(fixes_dir)
+
+                for change in fixeslist:
+                    status, title = run_command('git log -n 1 --format=%%s %s' % (change[0]))
+                    if status != 0:
+                        eout(result)
+                        continue
+                    print('Commit "%s" fixes %s' % (title[0], change[1]))
+                    status, result = run_command('git format-patch -k %s^..%s' % (change[0], change[0]))
+                    if status != 0:
+                        eout(result)
+                        continue
+                    filename = result[0]
+                    short_sha_pfx = '%s-' % change[0][:8]
+                    newfilename = filename.replace('0001-', short_sha_pfx, 1)
+                    rename(filename, newfilename)
+                    filename = newfilename
+
+                    fixes_file = '%s/%s' % (fixes_dir, filename)
+                    if path.exists(fixes_file):
+                        remove(filename)
+                        continue
+                    self.modify_patch(filename, change[0], self.cfg['sob'], ccstable)
+                    move(filename, fixes_file)
+
         # Handle the user presses <ctrl-C>.
         #
         except KeyboardInterrupt:
-- 
2.1.4




More information about the kernel-team mailing list