X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Fpatman%2Fgitutil.py;h=31fb3b28299749fea46367f710216a042db798d7;hb=5a1a8a63be8f7262a300eddafb18020926b12fb6;hp=72fc95d5580d497b13c6d72eaaaa32a7086058c8;hpb=b5d54d26ea1354fede1121671a7ca3b9b44b5b5c;p=platform%2Fkernel%2Fu-boot.git diff --git a/tools/patman/gitutil.py b/tools/patman/gitutil.py index 72fc95d..31fb3b2 100644 --- a/tools/patman/gitutil.py +++ b/tools/patman/gitutil.py @@ -7,9 +7,7 @@ import os import subprocess import sys -from patman import checkpatch from patman import command -from patman import series from patman import settings from patman import terminal from patman import tools @@ -51,19 +49,30 @@ def LogCmd(commit_range, git_dir=None, oneline=False, reverse=False, 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']] - stdout = command.RunPipe(pipe, capture=True, oneline=True).stdout - patch_count = int(stdout) + if branch: + us, msg = GetUpstream('.git', branch) + rev_range = '%s..%s' % (us, branch) + else: + rev_range = '@{upstream}..' + pipe = [LogCmd(rev_range, oneline=True)] + result = command.RunPipe(pipe, capture=True, capture_stderr=True, + oneline=True, raise_on_error=False) + if result.return_code: + raise ValueError('Failed to determine upstream: %s' % + result.stderr.strip()) + patch_count = len(result.stdout.splitlines()) return patch_count def NameRevision(commit_hash): @@ -254,17 +263,62 @@ def Fetch(git_dir=None, work_tree=None): if result.return_code != 0: raise OSError('git fetch: %s' % result.stderr) -def CreatePatches(start, count, ignore_binary, series): +def CheckWorktreeIsAvailable(git_dir): + """Check if git-worktree functionality is available + + Args: + git_dir: The repository to test in + + Returns: + True if git-worktree commands will work, False otherwise. + """ + pipe = ['git', '--git-dir', git_dir, 'worktree', 'list'] + result = command.RunPipe([pipe], capture=True, capture_stderr=True, + raise_on_error=False) + return result.return_code == 0 + +def AddWorktree(git_dir, output_dir, commit_hash=None): + """Create and checkout a new git worktree for this build + + Args: + git_dir: The repository to checkout the worktree from + output_dir: Path for the new worktree + commit_hash: Commit hash to checkout + """ + # We need to pass --detach to avoid creating a new branch + pipe = ['git', '--git-dir', git_dir, 'worktree', 'add', '.', '--detach'] + if commit_hash: + pipe.append(commit_hash) + result = command.RunPipe([pipe], capture=True, cwd=output_dir, + capture_stderr=True) + if result.return_code != 0: + raise OSError('git worktree add: %s' % result.stderr) + +def PruneWorktrees(git_dir): + """Remove administrative files for deleted worktrees + + Args: + git_dir: The repository whose deleted worktrees should be pruned + """ + pipe = ['git', '--git-dir', git_dir, 'worktree', 'prune'] + result = command.RunPipe([pipe], capture=True, capture_stderr=True) + if result.return_code != 0: + raise OSError('git worktree prune: %s' % result.stderr) + +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 + series: Series object for this series (set of patches) Return: - Filename of cover letter + Filename of cover letter (None if none) List of filenames of patch files """ if series.get('version'): @@ -277,7 +331,8 @@ def CreatePatches(start, count, ignore_binary, series): 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() @@ -335,6 +390,31 @@ def BuildEmailList(in_list, tag=None, alias=None, raise_on_error=True): return ['%s %s%s%s' % (tag, quote, email, quote) for email in result] return result +def CheckSuppressCCConfig(): + """Check if sendemail.suppresscc is configured correctly. + + Returns: + True if the option is configured correctly, False otherwise. + """ + suppresscc = command.OutputOneLine('git', 'config', 'sendemail.suppresscc', + raise_on_error=False) + + # Other settings should be fine. + if suppresscc == 'all' or suppresscc == 'cccmd': + col = terminal.Color() + + print((col.Color(col.RED, "error") + + ": git config sendemail.suppresscc set to %s\n" % (suppresscc)) + + " patman needs --cc-cmd to be run to set the cc list.\n" + + " Please run:\n" + + " git config --unset sendemail.suppresscc\n" + + " Or read the man page:\n" + + " git send-email --help\n" + + " and set an option that runs --cc-cmd\n") + return False + + return True + def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname, self_only=False, alias=None, in_reply_to=None, thread=False, smtp_server=None): @@ -369,27 +449,27 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname, >>> alias['boys'] = ['fred', ' john'] >>> alias['all'] = ['fred ', 'john', ' mary '] >>> alias[os.getenv('USER')] = ['this-is-me@me.com'] - >>> series = series.Series() - >>> series.to = ['fred'] - >>> series.cc = ['mary'] + >>> series = {} + >>> series['to'] = ['fred'] + >>> series['cc'] = ['mary'] >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ False, alias) 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" cover p1 p2' +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2' >>> EmailPatches(series, None, ['p1'], True, True, 'cc-fname', False, \ alias) 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" p1' - >>> series.cc = ['all'] +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" p1' + >>> series['cc'] = ['all'] >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ True, alias) 'git send-email --annotate --to "this-is-me@me.com" --cc-cmd "./patman \ ---cc-cmd cc-fname" cover p1 p2' +send --cc-cmd cc-fname" cover p1 p2' >>> EmailPatches(series, 'cover', ['p1', 'p2'], True, True, 'cc-fname', \ False, alias) 'git send-email --annotate --to "f.bloggs@napier.co.nz" --cc \ "f.bloggs@napier.co.nz" --cc "j.bloggs@napier.co.nz" --cc \ -"m.poppins@cloud.net" --cc-cmd "./patman --cc-cmd cc-fname" cover p1 p2' +"m.poppins@cloud.net" --cc-cmd "./patman send --cc-cmd cc-fname" cover p1 p2' # Restore argv[0] since we clobbered it. >>> sys.argv[0] = _old_argv0 @@ -420,7 +500,7 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname, cmd += to cmd += cc - cmd += ['--cc-cmd', '"%s --cc-cmd %s"' % (sys.argv[0], cc_fname)] + cmd += ['--cc-cmd', '"%s send --cc-cmd %s"' % (sys.argv[0], cc_fname)] if cover_fname: cmd.append(cover_fname) cmd += args