Message ID | 1424979780-11697-1-git-send-email-luis.henriques@canonical.com |
---|---|
State | New |
Headers | show |
This looks good to me, Luis. Thanks for the new feature! -Kamal On Thu, 2015-02-26 at 19:43 +0000, Luis Henriques wrote: > 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@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:
Cheers, -- Luís
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:
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@canonical.com> --- stable/apply-stable-patches | 95 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 6 deletions(-)