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 <sjg@chromium.org>
This commit is contained in:
@@ -23,11 +23,12 @@ import command
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import series
|
import series
|
||||||
import settings
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import terminal
|
import terminal
|
||||||
|
|
||||||
|
import settings
|
||||||
|
|
||||||
|
|
||||||
def CountCommitsToBranch():
|
def CountCommitsToBranch():
|
||||||
"""Returns number of commits between HEAD and the tracking branch.
|
"""Returns number of commits between HEAD and the tracking branch.
|
||||||
@@ -44,6 +45,119 @@ def CountCommitsToBranch():
|
|||||||
patch_count = int(stdout)
|
patch_count = int(stdout)
|
||||||
return patch_count
|
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):
|
def CreatePatches(start, count, series):
|
||||||
"""Create a series of patches from the top of the current branch.
|
"""Create a series of patches from the top of the current branch.
|
||||||
|
|
||||||
@@ -390,6 +504,14 @@ def Setup():
|
|||||||
if alias_fname:
|
if alias_fname:
|
||||||
settings.ReadGitAliases(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__":
|
if __name__ == "__main__":
|
||||||
import doctest
|
import doctest
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user