From a10fd93cbc2ddf1da1f8b6d915f4bc3276ff7731 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Dec 2012 10:42:04 +0000 Subject: patman: Make command methods return a CommandResult Rather than returning a list of things, return an object. That makes it easier to access the returned items, and easier to extend the return value later. Signed-off-by: Simon Glass --- tools/patman/gitutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/patman/gitutil.py') diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index ca3ba4a03e4..77907c15c82 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -40,7 +40,7 @@ def CountCommitsToBranch(): """ pipe = [['git', 'log', '--no-color', '--oneline', '@{upstream}..'], ['wc', '-l']] - stdout = command.RunPipe(pipe, capture=True, oneline=True) + stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout patch_count = int(stdout) return patch_count -- cgit v1.2.3 From dc191505b903220a8581303efef0a1ead0e06532 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Dec 2012 10:42:05 +0000 Subject: patman: Allow commands to raise on error, or not Make raise_on_error a parameter so that we can control which commands raise and which do not. If we get an error reading the alias file, just continue. Signed-off-by: Simon Glass --- tools/patman/gitutil.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools/patman/gitutil.py') diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 77907c15c82..33743dd8780 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -359,7 +359,8 @@ def GetAliasFile(): Returns: Filename of git alias file, or None if none """ - fname = command.OutputOneLine('git', 'config', 'sendemail.aliasesfile') + fname = command.OutputOneLine('git', 'config', 'sendemail.aliasesfile', + raise_on_error=False) if fname: fname = os.path.join(GetTopLevel(), fname.strip()) return fname -- cgit v1.2.3 From 5f6a1c420070221e2fdbe81d9a8af8bcd3c05fbb Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Dec 2012 10:42:07 +0000 Subject: patman: Add additional git utilties Add methods to find out the commits in a branch, clone a repo and fetch from a repo. Signed-off-by: Simon Glass --- tools/patman/gitutil.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 1 deletion(-) (limited to 'tools/patman/gitutil.py') diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 33743dd8780..99fac795c20 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -23,11 +23,12 @@ import command import re import os import series -import settings import subprocess import sys import terminal +import settings + def CountCommitsToBranch(): """Returns number of commits between HEAD and the tracking branch. @@ -44,6 +45,119 @@ def CountCommitsToBranch(): patch_count = int(stdout) return patch_count +def GetUpstream(git_dir, branch): + """Returns the name of the upstream for a branch + + Args: + git_dir: Git directory containing repo + branch: Name of branch + + Returns: + Name of upstream branch (e.g. 'upstream/master') or None if none + """ + remote = command.OutputOneLine('git', '--git-dir', git_dir, 'config', + 'branch.%s.remote' % branch) + merge = command.OutputOneLine('git', '--git-dir', git_dir, 'config', + 'branch.%s.merge' % branch) + if remote == '.': + return merge + elif remote and merge: + leaf = merge.split('/')[-1] + return '%s/%s' % (remote, leaf) + else: + raise ValueError, ("Cannot determine upstream branch for branch " + "'%s' remote='%s', merge='%s'" % (branch, remote, merge)) + + +def GetRangeInBranch(git_dir, branch, include_upstream=False): + """Returns an expression for the commits in the given branch. + + Args: + git_dir: Directory containing git repo + branch: Name of branch + Return: + Expression in the form 'upstream..branch' which can be used to + access the commits. + """ + upstream = GetUpstream(git_dir, branch) + return '%s%s..%s' % (upstream, '~' if include_upstream else '', branch) + +def CountCommitsInBranch(git_dir, branch, include_upstream=False): + """Returns the number of commits in the given branch. + + Args: + git_dir: Directory containing git repo + branch: Name of branch + Return: + Number of patches that exist on top of the branch + """ + range_expr = GetRangeInBranch(git_dir, branch, include_upstream) + pipe = [['git', '--git-dir', git_dir, 'log', '--oneline', range_expr], + ['wc', '-l']] + result = command.RunPipe(pipe, capture=True, oneline=True) + patch_count = int(result.stdout) + return patch_count + +def CountCommits(commit_range): + """Returns the number of commits in the given range. + + Args: + commit_range: Range of commits to count (e.g. 'HEAD..base') + Return: + Number of patches that exist on top of the branch + """ + pipe = [['git', 'log', '--oneline', commit_range], + ['wc', '-l']] + stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout + patch_count = int(stdout) + return patch_count + +def Checkout(commit_hash, git_dir=None, work_tree=None, force=False): + """Checkout the selected commit for this build + + Args: + commit_hash: Commit hash to check out + """ + pipe = ['git'] + if git_dir: + pipe.extend(['--git-dir', git_dir]) + if work_tree: + pipe.extend(['--work-tree', work_tree]) + pipe.append('checkout') + if force: + pipe.append('-f') + pipe.append(commit_hash) + result = command.RunPipe([pipe], capture=True, raise_on_error=False) + if result.return_code != 0: + raise OSError, 'git checkout (%s): %s' % (pipe, result.stderr) + +def Clone(git_dir, output_dir): + """Checkout the selected commit for this build + + Args: + commit_hash: Commit hash to check out + """ + pipe = ['git', 'clone', git_dir, '.'] + result = command.RunPipe([pipe], capture=True, cwd=output_dir) + if result.return_code != 0: + raise OSError, 'git clone: %s' % result.stderr + +def Fetch(git_dir=None, work_tree=None): + """Fetch from the origin repo + + Args: + commit_hash: Commit hash to check out + """ + pipe = ['git'] + if git_dir: + pipe.extend(['--git-dir', git_dir]) + if work_tree: + pipe.extend(['--work-tree', work_tree]) + pipe.append('fetch') + result = command.RunPipe([pipe], capture=True) + if result.return_code != 0: + raise OSError, 'git fetch: %s' % result.stderr + def CreatePatches(start, count, series): """Create a series of patches from the top of the current branch. @@ -390,6 +504,14 @@ def Setup(): if alias_fname: settings.ReadGitAliases(alias_fname) +def GetHead(): + """Get the hash of the current HEAD + + Returns: + Hash of HEAD + """ + return command.OutputOneLine('git', 'show', '-s', '--pretty=format:%H') + if __name__ == "__main__": import doctest -- cgit v1.2.3 From 6d819925d0781b1fa8e5526f73cd277449dc08e1 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Sun, 17 Mar 2013 10:31:04 +0000 Subject: patman: Allow specifying the message ID your series is in reply to Some versions of git don't seem to prompt you for the message ID that your series is in reply to. Allow specifying this from the command line. Signed-off-by: Doug Anderson Acked-by: Simon Glass --- tools/patman/gitutil.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/patman/gitutil.py') diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 99fac795c20..4e21d4c2a77 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -317,7 +317,7 @@ def BuildEmailList(in_list, tag=None, alias=None): return result def EmailPatches(series, cover_fname, args, dry_run, cc_fname, - self_only=False, alias=None): + self_only=False, alias=None, in_reply_to=None): """Email a patch series. Args: @@ -327,6 +327,8 @@ def EmailPatches(series, cover_fname, args, dry_run, cc_fname, dry_run: Just return the command that would be run cc_fname: Filename of Cc file for per-commit Cc self_only: True to just email to yourself as a test + in_reply_to: If set we'll pass this to git as --in-reply-to. + Should be a message ID that this is in reply to. Returns: Git command that was/would be run @@ -376,6 +378,9 @@ def EmailPatches(series, cover_fname, args, dry_run, cc_fname, to = BuildEmailList([os.getenv('USER')], '--to', alias) cc = [] cmd = ['git', 'send-email', '--annotate'] + if in_reply_to: + cmd.append('--in-reply-to="%s"' % in_reply_to) + cmd += to cmd += cc cmd += ['--cc-cmd', '"%s --cc-cmd %s"' % (sys.argv[0], cc_fname)] -- cgit v1.2.3