-include doc.dep
clean:
- rm -f *.xml *.html *.pdf *.1 doc.dep $(COMMANDS_TXT)
+ rm -f *.xml *.html *.pdf *.1 doc.dep $(COMMANDS_TXT) stg-cmd-list.txt
-$(COMMANDS_TXT): $(shell find .. -name '*.py')
+ALL_PY = $(shell find ../stgit -name '*.py')
+
+$(COMMANDS_TXT): $(ALL_PY)
../stg-build --asciidoc $(basename $(subst stg-,,$@)) > $@
+stg-cmd-list.txt: $(ALL_PY)
+ ../stg-build --cmd-list > $@
+
%.html : %.txt
$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf $(ASCIIDOC_EXTRA) $<
[stglink-inlinemacro]
<a href="stg-{target}.html">stg {target}</a>
endif::backend-xhtml11[]
+
+## stgsublink: macro
+#
+# Usage: stgsublink:command[]
+#
+# Show StGit link as: <command> in man pages, stg <command> in
+# html.
+
+ifdef::backend-docbook[]
+[stgsublink-inlinemacro]
+{target}
+endif::backend-docbook[]
+
+ifdef::backend-xhtml11[]
+[stgsublink-inlinemacro]
+<a href="stg-{target}.html">{target}</a>
+endif::backend-xhtml11[]
manpages are named 'stg-<command>(1)'.
endif::backend-docbook[]
-Generic commands
-~~~~~~~~~~~~~~~~
-
-User-support commands not touching the repository.
-
-stg help::
- stgdesc:help[]
-stg version::
- stgdesc:version[]
-stg copyright::
- stgdesc:copyright[]
-
-Repository commands
-~~~~~~~~~~~~~~~~~~~
-
-stglink:clone[]::
- stgdesc:clone[]
-stglink:id[]::
- stgdesc:id[]
-
-Stack commands
-~~~~~~~~~~~~~~
-
-Stack management
-^^^^^^^^^^^^^^^^
-
-stglink:branch[]::
- stgdesc:branch[]
-stglink:init[]::
- stgdesc:init[]
-stglink:clean[]::
- stgdesc:clean[]
-stglink:pull[]::
- stgdesc:pull[]
-stglink:rebase[]::
- stgdesc:rebase[]
-
-stglink:commit[]::
- stgdesc:commit[]
-stglink:uncommit[]::
- stgdesc:uncommit[]
-stglink:repair[]::
- stgdesc:repair[]
-
-Controlling what patches are applied
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-stglink:series[]::
- stgdesc:series[]
-stglink:push[]::
- stgdesc:push[]
-stglink:pop[]::
- stgdesc:pop[]
-stglink:goto[]::
- stgdesc:goto[]
-stglink:float[]::
- stgdesc:float[]
-stglink:sink[]::
- stgdesc:sink[]
-stglink:applied[]::
- stgdesc:applied[]
-stglink:unapplied[]::
- stgdesc:unapplied[]
-stglink:top[]::
- stgdesc:top[]
-
-stglink:hide[]::
- stgdesc:hide[]
-stglink:unhide[]::
- stgdesc:unhide[]
-
-Miscellaneous stack commands
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-stglink:patches[]::
- stgdesc:patches[]
-
-
-Patch commands
-~~~~~~~~~~~~~~
-
-Patch management
-^^^^^^^^^^^^^^^^
-
-stglink:new[]::
- stgdesc:new[]
-stglink:delete[]::
- stgdesc:delete[]
-stglink:rename[]::
- stgdesc:rename[]
-stglink:log[]::
- stgdesc:log[]
-
-Controlling patch contents
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-stglink:files[]::
- stgdesc:files[]
-stglink:show[]::
- stgdesc:show[]
-stglink:refresh[]::
- stgdesc:refresh[]
-stglink:fold[]::
- stgdesc:fold[]
-stglink:pick[]::
- stgdesc:pick[]
-stglink:sync[]::
- stgdesc:sync[]
-
-Interaction with the rest of the world
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-stglink:export[]::
- stgdesc:export[]
-stglink:import[]::
- stgdesc:import[]
-stglink:mail[]::
- stgdesc:mail[]
-
-
-Working-copy commands
-~~~~~~~~~~~~~~~~~~~~~
-
-stglink:add[]::
- stgdesc:add[]
-stglink:rm[]::
- stgdesc:rm[]
-stglink:cp[]::
- stgdesc:cp[]
-stglink:status[]::
- stgdesc:status[]
-stglink:diff[]::
- stgdesc:diff[]
-stglink:resolved[]::
- stgdesc:resolved[]
+include::stg-cmd-list.txt[]
CONFIGURATION MECHANISM
-----------------------
TEST_PATCHES ?= ..
-all:
+all: build
$(PYTHON) setup.py build
-install:
+build: stgit/commands/cmdlist.py
+
+ALL_PY = $(shell find stgit -name '*.py')
+
+stgit/commands/cmdlist.py: $(ALL_PY)
+ $(PYTHON) stg-build --py-cmd-list > $@
+
+install: build
$(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR) --force
doc:
install-html:
$(MAKE) -C Documentation install-html
-test:
+test: build
cd t && $(MAKE) all
-test_patches:
+test_patches: build
for patch in $$(stg series --noprefix $(TEST_PATCHES)); do \
stg goto $$patch && $(MAKE) test || break; \
done
rm -f stgit/*.pyc
rm -f stgit/commands/*.pyc
rm -f TAGS
+ rm -f stgit/commands/cmdlist.py
tags:
ctags -e -R stgit/*
-.PHONY: all install doc install-doc install-html test test_patches clean
+.PHONY: all build install doc install-doc install-html test test_patches clean
# -*- python -*-
import optparse, sys
import stgit.main
-from stgit import argparse
+from stgit import argparse, commands
def main():
op = optparse.OptionParser()
help = 'Print asciidoc documentation for a command')
op.add_option('--commands', action = 'store_true',
help = 'Print list of all stg subcommands')
+ op.add_option('--cmd-list', action = 'store_true',
+ help = 'Print asciidoc command list')
+ op.add_option('--py-cmd-list', action = 'store_true',
+ help = 'Write Python command list')
options, args = op.parse_args()
if args:
op.error('Wrong number of arguments')
argparse.write_asciidoc(stgit.main.commands[options.asciidoc],
sys.stdout)
elif options.commands:
- for cmd in sorted(stgit.main.commands.iterkeys()):
+ for cmd in sorted(commands.get_commands(
+ allow_cached = False).iterkeys()):
print cmd
+ elif options.cmd_list:
+ commands.asciidoc_command_list(
+ commands.get_commands(allow_cached = False), sys.stdout)
+ elif options.py_cmd_list:
+ commands.py_commands(commands.get_commands(allow_cached = False),
+ sys.stdout)
else:
op.error('No command')
--- /dev/null
+/cmdlist.py
+# -*- coding: utf-8 -*-
+
__copyright__ = """
Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>
+Copyright (C) 2008, Karl Hasselström <kha@treskal.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
+
+import os
+from stgit import utils
+
+def get_command(mod):
+ """Import and return the given command module."""
+ return __import__(__name__ + '.' + mod, globals(), locals(), ['*'])
+
+_kinds = [('repo', 'Repository commands'),
+ ('stack', 'Stack (branch) commands'),
+ ('patch', 'Patch commands'),
+ ('wc', 'Index/worktree commands')]
+_kind_order = [kind for kind, desc in _kinds]
+_kinds = dict(_kinds)
+
+def _find_commands():
+ for p in __path__:
+ for fn in os.listdir(p):
+ if not fn.endswith('.py'):
+ continue
+ mod = utils.strip_suffix('.py', fn)
+ m = get_command(mod)
+ if not hasattr(m, 'usage'):
+ continue
+ yield mod, m
+
+def get_commands(allow_cached = True):
+ """Return a map from command name to a tuple of module name, command
+ type, and one-line command help."""
+ if allow_cached:
+ try:
+ from stgit.commands.cmdlist import command_list
+ return command_list
+ except ImportError:
+ # cmdlist.py doesn't exist, so do it the expensive way.
+ pass
+ return dict((getattr(m, 'name', mod), (mod, _kinds[m.kind], m.help))
+ for mod, m in _find_commands())
+
+def py_commands(commands, f):
+ f.write('command_list = {\n')
+ for key, val in sorted(commands.iteritems()):
+ f.write(' %r: %r,\n' % (key, val))
+ f.write(' }\n')
+
+def _command_list(commands):
+ kinds = {}
+ for cmd, (mod, kind, help) in commands.iteritems():
+ kinds.setdefault(kind, {})[cmd] = help
+ for kind in _kind_order:
+ kind = _kinds[kind]
+ yield kind, sorted(kinds[kind].iteritems())
+
+def pretty_command_list(commands, f):
+ cmd_len = max(len(cmd) for cmd in commands.iterkeys())
+ sep = ''
+ for kind, cmds in _command_list(commands):
+ f.write(sep)
+ sep = '\n'
+ f.write('%s:\n' % kind)
+ for cmd, help in cmds:
+ f.write(' %*s %s\n' % (-cmd_len, cmd, help))
+
+def _write_underlined(s, u, f):
+ f.write(s + '\n')
+ f.write(u*len(s) + '\n')
+
+def asciidoc_command_list(commands, f):
+ for kind, cmds in _command_list(commands):
+ _write_underlined(kind, '~', f)
+ f.write('\n')
+ for cmd, help in cmds:
+ f.write('stgsublink:%s[]::\n' % cmd)
+ f.write(' %s\n' % help)
+ f.write('\n')
from stgit import stack, git, basedir
help = 'Branch operations: switch, list, create, rename, delete, ...'
+kind = 'stack'
usage = ['',
'<branch>',
'--list',
from stgit.lib import transaction
help = 'Delete the empty patches in the series'
+kind = 'stack'
usage = ['']
description = """
Delete the empty patches in the whole series or only those applied or
from stgit import stack, git
help = 'Make a local clone of a remote repository'
+kind = 'repo'
usage = ['<repository> <dir>']
description = """
Clone a git repository into the local directory <dir> (using
from stgit.lib import git, transaction
help = 'Coalesce two or more patches into one'
+kind = 'stack'
usage = ['[options] <patches>']
description = """
Coalesce two or more patches, creating one big patch that contains all
from stgit.out import *
help = 'Permanently store the applied patches into the stack base'
+kind = 'stack'
usage = ['',
'<patchnames>',
'-n NUM',
from stgit.lib import transaction
help = 'Delete patches'
+kind = 'patch'
usage = ['[options] <patch1> [<patch2>] [<patch3>..<patch4>]']
description = """
Delete the patches passed as arguments.
from stgit import argparse, stack, git
help = 'Show the tree diff'
+kind = 'wc'
usage = ['[options] [<files or dirs>]']
description = """
Show the diff (default) or diffstat between the current working copy
from stgit.out import *
help = 'edit a patch description or diff'
+kind = 'patch'
usage = ['[options] [<patch>]']
description = """
Edit the description and author information of the given patch (or the
from stgit.lib import git as gitlib
help = 'Export patches to a directory'
+kind = 'patch'
usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = """
Export a range of applied patches to a given directory (defaults to
from stgit import argparse, stack, git
help = 'Show the files modified by a patch (or the current patch)'
+kind = 'patch'
usage = ['[options] [[<branch>:]<patch>]']
description = """
List the files modified by the given patch (defaulting to the current
from stgit import stack, git
help = 'Push patches to the top, even if applied'
+kind = 'stack'
usage = ['<patches>',
'-s <series>']
description = """
from stgit import stack, git
help = 'Integrate a GNU diff patch into the current patch'
+kind = 'patch'
usage = ['[options] [<file>]']
description = """
Apply the given GNU diff file (or the standard input) onto the top of
from stgit.lib import transaction
help = 'Push or pop patches to the given one'
+kind = 'stack'
usage = ['<patch-name>']
description = """
Push/pop patches to/from the stack until the one given on the command
from stgit import stack, git
help = 'Hide a patch in the series'
+kind = 'stack'
usage = ['[options] <patch-range>']
description = """
Hide a range of unapplied patches so that they are no longer shown in
from stgit.lib import stack
help = 'Print the git hash value of a StGit reference'
+kind = 'repo'
usage = ['[options] [id]']
description = """
Print the SHA1 value of a Git id (defaulting to HEAD). In addition to
name = 'import'
help = 'Import a GNU diff file as a new patch'
+kind = 'patch'
usage = ['[options] [<file>|<url>]']
description = """
Create a new patch and apply the given GNU diff file (or the standard
from stgit.lib import stack
help = 'Initialise the current branch for use with StGIT'
+kind = 'stack'
usage = ['']
description = """
Initialise the current git branch to be used as an StGIT stack. The
from stgit.run import Run
help = 'Display the patch changelog'
+kind = 'patch'
usage = ['[options] [patch]']
description = """
List all the current and past commit ids of the given patch. The
from stgit.run import Run
help = 'Send a patch or series of patches by e-mail'
+kind = 'patch'
usage = [' [options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = r"""
Send a patch or a range of patches by e-mail using the SMTP server
from stgit.config import config
help = 'Create a new, empty patch'
+kind = 'patch'
usage = ['[options] [<name>]']
description = """
Create a new, empty patch on the current stack. The new patch is
from stgit import stack, git
help = 'Show the applied patches modifying a file'
+kind = 'stack'
usage = ['[options] [<files or dirs>]']
description = """
Show the applied patches modifying the given files. Without arguments,
from stgit.stack import Series
help = 'Import a patch from a different branch or a commit object'
+kind = 'patch'
usage = ['[options] ([<patch1>] [<patch2>] [<patch3>..<patch4>])|<commit>']
description = """
Import one or more patches from a different branch or a commit object
from stgit import stack, git
help = 'Pop one or more patches from the stack'
+kind = 'stack'
usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = """
Pop the topmost patch or a range of patches from the stack. The
from stgit import stack, git
help = 'Pull changes from a remote repository'
+kind = 'stack'
usage = ['[options] [<repository>]']
description = """
Pull the latest changes from the given remote repository (defaulting
from stgit import stack, git
help = 'Push one or more patches onto the stack'
+kind = 'stack'
usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = """
Push one or more patches (defaulting to the first unapplied one) onto
from stgit import stack, git
help = 'Move the stack base to another point in history'
+kind = 'stack'
usage = ['[options] <new-base-id>']
description = """
Pop all patches from current stack, move the stack base to the given
from stgit.config import config
help = 'Generate a new commit for the current patch'
+kind = 'patch'
usage = ['[options] [<files or dirs>]']
description = """
Include the latest tree changes in the current patch. This command
from stgit import stack, git
help = 'Rename a patch'
+kind = 'patch'
usage = ['[options] [oldpatch] <newpatch>']
description = """
Rename <oldpatch> into <newpatch> in a series. If <oldpatch> is not
from stgit import stack, git
help = 'Fix StGit metadata if branch was modified with git commands'
+kind = 'stack'
usage = ['']
description = """
If you modify an StGit stack (branch) with some git commands -- such
from stgit.gitmergeonefile import interactive_merge
help = 'Mark a file conflict as solved'
+kind = 'wc'
usage = ['[options] [<files...>]']
description = """
Mark a merge conflict as resolved. The conflicts can be seen with the
from stgit.config import config
help = 'Print the patch series'
+kind = 'stack'
usage = ['[options] [<patch-range>]']
description = """
Show all the patches in the series or just those in the given
from stgit import argparse, git
help = 'Show the commit corresponding to a patch'
+kind = 'patch'
usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = """
Show the commit log and the diff corresponding to the given patches.
from stgit import stack, git
help = 'Send patches deeper down the stack'
+kind = 'stack'
usage = ['[-t <target patch>] [-n] [<patches>]']
description = """
This is the opposite operation of stglink:float[]: move the specified
from stgit import stack, git
help = 'Show the tree status'
+kind = 'wc'
usage = ['[options] [<files or dirs>]']
description = """
Show the status of the whole working copy or the given files. The
from stgit import stack, git
help = 'Synchronise patches with a branch or a series'
+kind = 'patch'
usage = ['[options] [<patch1>] [<patch2>] [<patch3>..<patch4>]']
description = """
For each of the specified patches perform a three-way merge with the
from stgit.out import out
help = 'Print the name of the top patch'
+kind = 'stack'
usage = ['']
description = """
Print the name of the current (topmost) patch."""
from stgit import utils
help = 'Turn regular git commits into StGit patches'
+kind = 'stack'
usage = ['<patch-name-1> [<patch-name-2> ...]',
'-n NUM [<prefix>]',
'-t <committish> [-x]']
from stgit import stack, git
help = 'Unhide a hidden patch'
+kind = 'stack'
usage = ['[options] <patch-range>']
description = """
Unhide a hidden range of patches so that they are shown in the plain
return candidates[0]
def __getitem__(self, key):
- """Return the command python module name based.
- """
- global prog
-
cmd_mod = self.get(key) or self.get(self.canonical_cmd(key))
-
- __import__('stgit.commands.' + cmd_mod)
- return getattr(stgit.commands, cmd_mod)
-
-commands = Commands({
- 'branch': 'branch',
- 'delete': 'delete',
- 'diff': 'diff',
- 'clean': 'clean',
- 'clone': 'clone',
- 'coalesce': 'coalesce',
- 'commit': 'commit',
- 'edit': 'edit',
- 'export': 'export',
- 'files': 'files',
- 'float': 'float',
- 'fold': 'fold',
- 'goto': 'goto',
- 'hide': 'hide',
- 'id': 'id',
- 'import': 'imprt',
- 'init': 'init',
- 'log': 'log',
- 'mail': 'mail',
- 'new': 'new',
- 'patches': 'patches',
- 'pick': 'pick',
- 'pop': 'pop',
- 'pull': 'pull',
- 'push': 'push',
- 'rebase': 'rebase',
- 'refresh': 'refresh',
- 'rename': 'rename',
- 'repair': 'repair',
- 'resolved': 'resolved',
- 'series': 'series',
- 'show': 'show',
- 'sink': 'sink',
- 'status': 'status',
- 'sync': 'sync',
- 'top': 'top',
- 'uncommit': 'uncommit',
- 'unhide': 'unhide'
- })
+ return stgit.commands.get_command(cmd_mod)
-# classification: repository, stack, patch, working copy
-repocommands = (
- 'clone',
- 'id',
- )
-stackcommands = (
- 'branch',
- 'clean',
- 'coalesce',
- 'commit',
- 'float',
- 'goto',
- 'hide',
- 'init',
- 'patches',
- 'pop',
- 'pull',
- 'push',
- 'rebase',
- 'repair',
- 'series',
- 'sink',
- 'top',
- 'uncommit',
- 'unhide',
- )
-patchcommands = (
- 'delete',
- 'edit',
- 'export',
- 'files',
- 'fold',
- 'import',
- 'log',
- 'mail',
- 'new',
- 'pick',
- 'refresh',
- 'rename',
- 'show',
- 'sync',
- )
-wccommands = (
- 'diff',
- 'resolved',
- 'status',
- )
+cmd_list = stgit.commands.get_commands()
+commands = Commands((cmd, mod) for cmd, (mod, kind, help)
+ in cmd_list.iteritems())
-def _print_helpstring(cmd):
- print ' ' + cmd + ' ' * (12 - len(cmd)) + commands[cmd].help
-
def print_help():
print 'usage: %s <command> [options]' % os.path.basename(sys.argv[0])
print
print ' help print the detailed command usage'
print ' version display version information'
print ' copyright display copyright information'
- # unclassified commands if any
- cmds = commands.keys()
- cmds.sort()
- for cmd in cmds:
- if not cmd in repocommands and not cmd in stackcommands \
- and not cmd in patchcommands and not cmd in wccommands:
- _print_helpstring(cmd)
- print
-
- print 'Repository commands:'
- for cmd in repocommands:
- _print_helpstring(cmd)
print
-
- print 'Stack commands:'
- for cmd in stackcommands:
- _print_helpstring(cmd)
- print
-
- print 'Patch commands:'
- for cmd in patchcommands:
- _print_helpstring(cmd)
- print
-
- print 'Working-copy commands:'
- for cmd in wccommands:
- _print_helpstring(cmd)
+ stgit.commands.pretty_command_list(cmd_list, sys.stdout)
#
# The main function (command dispatcher)