patman: Allow creating patches for another branch
Add a -b option to allow patches to be created from a branch other than
the current one.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/patman/control.py b/tools/patman/control.py
index a896c92..b48eac4 100644
--- a/tools/patman/control.py
+++ b/tools/patman/control.py
@@ -20,7 +20,7 @@
"""Do required setup before doing anything"""
gitutil.Setup()
-def prepare_patches(col, count, start, ignore_binary):
+def prepare_patches(col, branch, count, start, ignore_binary):
"""Figure out what patches to generate, then generate them
The patch files are written to the current directory, e.g. 0001_xxx.patch
@@ -28,6 +28,7 @@
Args:
col (terminal.Color): Colour output object
+ branch (str): Branch to create patches from (None = current)
count (int): Number of patches to produce, or -1 to produce patches for
the current branch back to the upstream commit
start (int): Start partch to use (0=first / top of branch)
@@ -42,7 +43,7 @@
"""
if count == -1:
# Work out how many patches to send if we can
- count = (gitutil.CountCommitsToBranch() - start)
+ count = (gitutil.CountCommitsToBranch(branch) - start)
if not count:
sys.exit(col.Color(col.RED,
@@ -50,9 +51,9 @@
# Read the metadata from the commits
to_do = count
- series = patchstream.GetMetaData(start, to_do)
+ series = patchstream.GetMetaData(branch, start, to_do)
cover_fname, patch_files = gitutil.CreatePatches(
- start, to_do, ignore_binary, series)
+ branch, start, to_do, ignore_binary, series)
# Fix up the patch files to our liking, and insert the cover letter
patchstream.FixPatches(series, patch_files)
@@ -158,9 +159,11 @@
setup()
col = terminal.Color()
series, cover_fname, patch_files = prepare_patches(
- col, options.count, options.start, options.ignore_binary)
+ col, options.branch, options.count, options.start,
+ options.ignore_binary)
ok = check_patches(series, patch_files, options.check_patch,
options.verbose)
+
its_a_go = ok or options.ignore_errors
if its_a_go:
email_patches(
diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py
index 2119521..588be73e 100644
--- a/tools/patman/func_test.py
+++ b/tools/patman/func_test.py
@@ -426,12 +426,21 @@
os.chdir(self.gitdir)
# Check that it can detect the current branch
- self.assertEqual(2, gitutil.CountCommitsToBranch())
+ self.assertEqual(2, gitutil.CountCommitsToBranch(None))
col = terminal.Color()
with capture_sys_output() as _:
_, cover_fname, patch_files = control.prepare_patches(
- col, count=-1, start=0, ignore_binary=False)
+ col, branch=None, count=-1, start=0, ignore_binary=False)
self.assertIsNone(cover_fname)
self.assertEqual(2, len(patch_files))
+
+ # Check that it can detect a different branch
+ self.assertEqual(3, gitutil.CountCommitsToBranch('second'))
+ with capture_sys_output() as _:
+ _, cover_fname, patch_files = control.prepare_patches(
+ col, branch='second', count=-1, start=0,
+ ignore_binary=False)
+ self.assertIsNotNone(cover_fname)
+ self.assertEqual(3, len(patch_files))
finally:
os.chdir(orig_dir)
diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py
index 29444bf..b683481 100644
--- a/tools/patman/gitutil.py
+++ b/tools/patman/gitutil.py
@@ -49,17 +49,24 @@
cmd.append('--')
return cmd
-def CountCommitsToBranch():
+def CountCommitsToBranch(branch):
"""Returns number of commits between HEAD and the tracking branch.
This looks back to the tracking branch and works out the number of commits
since then.
+ Args:
+ branch: Branch to count from (None for current branch)
+
Return:
Number of patches that exist on top of the branch
"""
- pipe = [LogCmd('@{upstream}..', oneline=True),
- ['wc', '-l']]
+ if branch:
+ us, msg = GetUpstream('.git', branch)
+ rev_range = '%s..%s' % (us, branch)
+ else:
+ rev_range = '@{upstream}..'
+ pipe = [LogCmd(rev_range, oneline=True), ['wc', '-l']]
stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout
patch_count = int(stdout)
return patch_count
@@ -252,13 +259,14 @@
if result.return_code != 0:
raise OSError('git fetch: %s' % result.stderr)
-def CreatePatches(start, count, ignore_binary, series):
+def CreatePatches(branch, start, count, ignore_binary, series):
"""Create a series of patches from the top of the current branch.
The patch files are written to the current directory using
git format-patch.
Args:
+ branch: Branch to create patches from (None for current branch)
start: Commit to start from: 0=HEAD, 1=next one, etc.
count: number of commits to include
ignore_binary: Don't generate patches for binary files
@@ -277,7 +285,8 @@
prefix = series.GetPatchPrefix()
if prefix:
cmd += ['--subject-prefix=%s' % prefix]
- cmd += ['HEAD~%d..HEAD~%d' % (start + count, start)]
+ brname = branch or 'HEAD'
+ cmd += ['%s~%d..%s~%d' % (brname, start + count, brname, start)]
stdout = command.RunList(cmd)
files = stdout.splitlines()
diff --git a/tools/patman/main.py b/tools/patman/main.py
index 2432d31..0667541 100755
--- a/tools/patman/main.py
+++ b/tools/patman/main.py
@@ -31,6 +31,8 @@
parser = OptionParser()
parser.add_option('-H', '--full-help', action='store_true', dest='full_help',
default=False, help='Display the README file')
+parser.add_option('-b', '--branch', type='str',
+ help="Branch to process (by default, the current branch)")
parser.add_option('-c', '--count', dest='count', type='int',
default=-1, help='Automatically create patches from top n commits')
parser.add_option('-i', '--ignore-errors', action='store_true',
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index 4fe465e..2ea8ebc 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -512,17 +512,19 @@
ps.Finalize()
return series
-def GetMetaData(start, count):
+def GetMetaData(branch, start, count):
"""Reads out patch series metadata from the commits
This does a 'git log' on the relevant commits and pulls out the tags we
are interested in.
Args:
- start: Commit to start from: 0=HEAD, 1=next one, etc.
+ branch: Branch to use (None for current branch)
+ start: Commit to start from: 0=branch HEAD, 1=next one, etc.
count: Number of commits to list
"""
- return GetMetaDataForList('HEAD~%d' % start, None, count)
+ return GetMetaDataForList('%s~%d' % (branch if branch else 'HEAD', start),
+ None, count)
def GetMetaDataForTest(text):
"""Process metadata from a file containing a git log. Used for tests