pass
# Utility functions
-class RevParseException(StgException):
- """Revision spec parse error."""
- pass
-
def parse_rev(rev):
- """Parse a revision specification into its
- patchname@branchname//patch_id parts. If no branch name has a slash
- in it, also accept / instead of //."""
- if '/' in ''.join(git.get_heads()):
- # We have branch names with / in them.
- branch_chars = r'[^@]'
- patch_id_mark = r'//'
- else:
- # No / in branch names.
- branch_chars = r'[^@/]'
- patch_id_mark = r'(/|//)'
- patch_re = r'(?P<patch>[^@/]+)'
- branch_re = r'@(?P<branch>%s+)' % branch_chars
- patch_id_re = r'%s(?P<patch_id>[a-z.]*)' % patch_id_mark
-
- # Try //patch_id.
- m = re.match(r'^%s$' % patch_id_re, rev)
- if m:
- return None, None, m.group('patch_id')
-
- # Try path[@branch]//patch_id.
- m = re.match(r'^%s(%s)?%s$' % (patch_re, branch_re, patch_id_re), rev)
- if m:
- return m.group('patch'), m.group('branch'), m.group('patch_id')
-
- # Try patch[@branch].
- m = re.match(r'^%s(%s)?$' % (patch_re, branch_re), rev)
- if m:
- return m.group('patch'), m.group('branch'), None
-
- # No, we can't parse that.
- raise RevParseException
-
-def git_id(crt_series, rev):
- """Return the GIT id
+ """Parse a revision specification into its branch:patch parts.
"""
- if not rev:
- return None
-
- # try a GIT revision first
try:
- return git.rev_parse(rev + '^{commit}')
- except git.GitException:
- pass
+ branch, patch = rev.split(':', 1)
+ except ValueError:
+ branch = None
+ patch = rev
- # try an StGIT patch name
- try:
- patch, branch, patch_id = parse_rev(rev)
- if branch == None:
- series = crt_series
- else:
- series = stack.Series(branch)
- if patch == None:
- patch = series.get_current()
- if not patch:
- raise CmdException, 'No patches applied'
- if patch in series.get_applied() or patch in series.get_unapplied() or \
- patch in series.get_hidden():
- if patch_id in ['top', '', None]:
- return series.get_patch(patch).get_top()
- elif patch_id == 'bottom':
- return series.get_patch(patch).get_bottom()
- elif patch_id == 'top.old':
- return series.get_patch(patch).get_old_top()
- elif patch_id == 'bottom.old':
- return series.get_patch(patch).get_old_bottom()
- elif patch_id == 'log':
- return series.get_patch(patch).get_log()
- if patch == 'base' and patch_id == None:
- return series.get_base()
- except RevParseException:
- pass
- except stack.StackException:
- pass
+ return (branch, patch)
- raise CmdException, 'Unknown patch or revision: %s' % rev
+def git_id(crt_series, rev):
+ """Return the GIT id
+ """
+ # TODO: remove this function once all the occurrences were converted
+ # to git_commit()
+ repository = libstack.Repository.default()
+ return git_commit(rev, repository, crt_series.get_name()).sha1
-def git_commit(name, repository, branch = None):
+def git_commit(name, repository, branch_name = None):
"""Return the a Commit object if 'name' is a patch name or Git commit.
The patch names allowed are in the form '<branch>:<patch>' and can
be followed by standard symbols used by git-rev-parse. If <patch>
is '{base}', it represents the bottom of the stack.
"""
# Try a [branch:]patch name first
- try:
- branch, patch = name.split(':', 1)
- except ValueError:
- patch = name
+ branch, patch = parse_rev(name)
if not branch:
- branch = repository.current_branch_name
+ branch = branch_name or repository.current_branch_name
# The stack base
if patch.startswith('{base}'):
usage = """%prog [options] [<files or dirs>]
Show the diff (default) or diffstat between the current working copy
-or a tree-ish object and another tree-ish object. File names can also
-be given to restrict the diff output. The tree-ish object can be a
-standard git commit, tag or tree. In addition to these, the command
-also supports 'base', representing the bottom of the current stack,
-and '[patch][//[bottom | top]]' for the patch boundaries (defaulting to
-the current one):
+or a tree-ish object and another tree-ish object (defaulting to HEAD).
+File names can also be given to restrict the diff output. The
+tree-ish object can be an StGIT patch, a standard git commit, tag or
+tree. In addition to these, the command also supports '{base}',
+representing the bottom of the current stack.
-rev = '([patch][//[bottom | top]]) | <tree-ish> | base'
-
-If neither bottom nor top are given but a '//' is present, the command
-shows the specified patch (defaulting to the current one)."""
+rev = '[branch:](<patch>|{base}) | <tree-ish>'
+"""
directory = DirectoryHasRepository()
options = [make_option('-r', '--range',
rev_list = options.revs.split('..')
rev_list_len = len(rev_list)
if rev_list_len == 1:
- rev = rev_list[0]
- if rev.endswith('/'):
- # the whole patch
- rev = strip_suffix('/', rev)
- if rev.endswith('/'):
- rev = strip_suffix('/', rev)
- rev1 = rev + '//bottom'
- rev2 = rev + '//top'
- else:
- rev1 = rev_list[0]
- rev2 = None
+ rev1 = rev_list[0]
+ rev2 = None
elif rev_list_len == 2:
rev1 = rev_list[0]
rev2 = rev_list[1]
rev2 = None
diff_str = git.diff(args, git_id(crt_series, rev1),
- git_id(crt_series, rev2),
+ rev2 and git_id(crt_series, rev2),
diff_flags = options.diff_flags)
if options.stat:
out.stdout_raw(git.diffstat(diff_str) + '\n')
help = 'show the files modified by a patch (or the current patch)'
-usage = """%prog [options] [<patch>]
+usage = """%prog [options] [[<branch>:]<patch>]
List the files modified by the given patch (defaulting to the current
one). Passing the '--stat' option shows the diff statistics for the
options = [make_option('-s', '--stat',
help = 'show the diff stat',
action = 'store_true'),
- make_option('-b', '--branch',
- help = 'use BRANCH instead of the default one'),
make_option('--bare',
help = 'bare file names (useful for scripting)',
action = 'store_true')
"""Show the files modified by a patch (or the current patch)
"""
if len(args) == 0:
- patch = ''
+ patch = 'HEAD'
elif len(args) == 1:
patch = args[0]
else:
parser.error('incorrect number of arguments')
- rev1 = git_id(crt_series, '%s//bottom' % patch)
- rev2 = git_id(crt_series, '%s//top' % patch)
+ rev1 = git_id(crt_series, '%s^' % patch)
+ rev2 = git_id(crt_series, '%s' % patch)
if options.stat:
out.stdout_raw(git.diffstat(git.diff(rev1 = rev1, rev2 = rev2)) + '\n')
'shortlog': stack.shortlog(crt_series.get_patch(p)
for p in patches),
'diffstat': git.diffstat(git.diff(
- rev1 = git_id(crt_series, '%s//bottom' % patches[0]),
- rev2 = git_id(crt_series, '%s//top' % patches[-1])))}
+ rev1 = git_id(crt_series, '%s^' % patches[0]),
+ rev2 = git_id(crt_series, '%s' % patches[-1])))}
try:
msg_string = tmpl % tmpl_dict
else:
number_str = ''
- diff = git.diff(rev1 = git_id(crt_series, '%s//bottom' % patch),
- rev2 = git_id(crt_series, '%s//top' % patch),
+ diff = git.diff(rev1 = git_id(crt_series, '%s^' % patch),
+ rev2 = git_id(crt_series, '%s' % patch),
diff_flags = options.diff_flags)
tmpl_dict = {'patch': patch,
'sender': sender,
out.done()
elif options.update:
- rev1 = git_id(crt_series, '//bottom')
- rev2 = git_id(crt_series, '//top')
+ rev1 = git_id(crt_series, 'HEAD^')
+ rev2 = git_id(crt_series, 'HEAD')
files = git.barefiles(rev1, rev2).split('\n')
out.start('Updating with commit %s' % commit_id)
patchname = newpatch.get_name()
# find a patchlog to fork from
- (refpatchname, refbranchname, refpatchid) = parse_rev(patchname)
- if refpatchname and not refpatchid and \
- (not refpatchid or refpatchid == 'top'):
- # FIXME: should also support picking //top.old
+ refbranchname, refpatchname = parse_rev(patchname)
+ if refpatchname:
if refbranchname:
# assume the refseries is OK, since we already resolved
# commit_str to a git_id
between = applied[:applied.index(patch):-1]
pop_patches(crt_series, between, keep = True)
elif options.update:
- rev1 = git_id(crt_series, '//bottom')
- rev2 = git_id(crt_series, '//top')
+ rev1 = git_id(crt_series, 'HEAD^')
+ rev2 = git_id(crt_series, 'HEAD')
patch_files = git.barefiles(rev1, rev2).split('\n')
files = [f for f in files if f in patch_files]
if not files:
elif options.empty and stack.patches.get(patch).is_empty():
prefix = empty_prefix
- patch_str = patch + branch_str
+ patch_str = branch_str + patch
if options.description or options.author:
patch_str = patch_str.ljust(length)
return
if options.showbranch:
- branch_str = '@' + stack.name
+ branch_str = stack.name + ':'
else:
branch_str = ''
test_expect_success \
'Create a branch with empty patches' \
'
- stg branch -c foo base &&
+ stg branch -c foo {base} &&
stg new p1 -m p1 &&
stg new p2 -m p2 &&
stg new p3 -m p3 &&