repository. When a directory name is given, all the files and
subdirectories are recursively added."""
+directory = DirectoryHasRepository()
options = []
stack. They are listed in the order in which they were pushed, the
last one being the current (topmost) patch."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
make_option('-c', '--count',
with the way "assimilate" handles them, you have no reason to avoid
causing them in the first place if that is convenient for you."""
+directory = DirectoryHasRepository()
options = []
class Commit(object):
If not given any options, switch to the named branch."""
+directory = DirectoryHasRepository()
options = [make_option('-c', '--create',
help = 'create a new development branch',
action = 'store_true'),
unapplied. A patch is considered empty if the two commit objects
representing its boundaries refer to the same tree object."""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--applied',
help = 'delete the empty applied patches',
action = 'store_true'),
Clone a GIT <repository> into the local <dir> and initialise the
patch stack."""
+directory = DirectoryAnywhere()
options = []
Use this command only if you want to permanently store the applied
patches and no longer manage them with StGIT."""
+directory = DirectoryHasRepository()
options = []
from stgit.exception import *
from stgit.utils import *
from stgit.out import *
+from stgit.run import *
from stgit import stack, git, basedir
from stgit.config import config, file_extensions
# we don't yet have an agreed place for the creation date.
# Just return None
return (descr, authname, authemail, authdate, diff)
+
+def readonly_constant_property(f):
+ """Decorator that converts a function that computes a value to an
+ attribute that returns the value. The value is computed only once,
+ the first time it is accessed."""
+ def new_f(self):
+ n = '__' + f.__name__
+ if not hasattr(self, n):
+ setattr(self, n, f(self))
+ return getattr(self, n)
+ return property(new_f)
+
+class DirectoryException(StgException):
+ pass
+
+class _Directory(object):
+ @readonly_constant_property
+ def git_dir(self):
+ try:
+ return Run('git-rev-parse', '--git-dir'
+ ).discard_stderr().output_one_line()
+ except RunException:
+ raise DirectoryException('No git repository found')
+ @readonly_constant_property
+ def __topdir_path(self):
+ try:
+ lines = Run('git-rev-parse', '--show-cdup'
+ ).discard_stderr().output_lines()
+ if len(lines) == 0:
+ return '.'
+ elif len(lines) == 1:
+ return lines[0]
+ else:
+ raise RunException('Too much output')
+ except RunException:
+ raise DirectoryException('No git repository found')
+ @readonly_constant_property
+ def is_inside_git_dir(self):
+ return { 'true': True, 'false': False
+ }[Run('git-rev-parse', '--is-inside-git-dir'
+ ).output_one_line()]
+ @readonly_constant_property
+ def is_inside_worktree(self):
+ return { 'true': True, 'false': False
+ }[Run('git-rev-parse', '--is-inside-work-tree'
+ ).output_one_line()]
+ def cd_to_topdir(self):
+ os.chdir(self.__topdir_path)
+
+class DirectoryAnywhere(_Directory):
+ def setup(self):
+ pass
+
+class DirectoryHasRepository(_Directory):
+ def setup(self):
+ self.git_dir # might throw an exception
+
+class DirectoryInWorktree(DirectoryHasRepository):
+ def setup(self):
+ DirectoryHasRepository.setup(self)
+ if not self.is_inside_worktree:
+ raise DirectoryException('Not inside a git worktree')
+
+class DirectoryGotoToplevel(DirectoryInWorktree):
+ def setup(self):
+ DirectoryInWorktree.setup(self)
+ self.cd_to_topdir()
Copy of the files and dirs passed as arguments under another name or
location inside the same repository."""
+directory = DirectoryHasRepository()
options = []
def func(parser, options, args):
Note that the 'delete' operation is irreversible."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
If neither bottom nor top are given but a '//' is present, the command
shows the specified patch (defaulting to the current one)."""
+directory = DirectoryHasRepository()
options = [make_option('-r', '--range',
metavar = 'rev1[..[rev2]]', dest = 'revs',
help = 'show the diff between revisions'),
these files using the '--file' and '--diff' options.
"""
+directory = DirectoryHasRepository()
options = [make_option('-d', '--diff',
help = 'edit the patch diff',
action = 'store_true'),
%(commemail)s - committer's e-mail
"""
+directory = DirectoryHasRepository()
options = [make_option('-d', '--dir',
help = 'export patches to DIR instead of the default'),
make_option('-p', '--patch',
the working tree and not yet included in the patch by a 'refresh'
command. Use the 'diff' or 'status' commands for these files."""
+directory = DirectoryHasRepository()
options = [make_option('-s', '--stat',
help = 'show the diff stat',
action = 'store_true'),
this. The '--series' option can be used to rearrange the (top) patches
as specified by the given series file (or the standard input)."""
+directory = DirectoryHasRepository()
options = [make_option('-s', '--series',
help = 'rearrange according to a series file',
action = 'store_true')]
applied onto the specified base and a three-way merged is performed
with the current top."""
+directory = DirectoryHasRepository()
options = [make_option('-t', '--threeway',
help = 'perform a three-way merge with the current patch',
action = 'store_true'),
--to' commands. There is no '--undo' option for 'goto'. Use the 'push'
command for this."""
+directory = DirectoryHasRepository()
options = [make_option('-k', '--keep',
help = 'keep the local changes when popping patches',
action = 'store_true')]
Hide a range of unapplied patches so that they are no longer shown in
the plain 'series' command output."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
'top' or 'bottom' are passed and <patch> is a valid patch name, 'top'
will be used by default."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
The patch description has to be separated from the data with a '---'
line."""
+directory = DirectoryHasRepository()
options = [make_option('-m', '--mail',
help = 'import the patch from a standard e-mail file',
action = 'store_true'),
that you must already be in a GIT repository and .git/HEAD must point
to a valid file in refs/heads/."""
+directory = DirectoryHasRepository()
options = []
patch. Conflicts reset the patch content and a subsequent 'refresh'
will show the entire patch."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
make_option('-p', '--patch',
%(prefix)s - 'prefix ' string passed on the command line
%(shortdescr)s - the first line of the patch description"""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--all',
help = 'e-mail all the applied patches',
action = 'store_true'),
If no name is given for the new patch, one is generated from the first
line of the commit message."""
+directory = DirectoryHasRepository()
options = [make_option('-m', '--message',
help = 'use MESSAGE as the patch description'),
make_option('-s', '--showpatch',
'--diff' option also lists the patch log and the diff for the given
files."""
+directory = DirectoryHasRepository()
options = [make_option('-d', '--diff',
help = 'show the diff for the given files',
action = 'store_true'),
option. A commit object can be reverted with the '--reverse'
option. The log and author information are those of the commit object."""
+directory = DirectoryHasRepository()
options = [make_option('-n', '--name',
help = 'use NAME as the patch name'),
make_option('-r', '--reverse',
the push operations may fail because of conflicts (push --undo would
revert the last push operation)."""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--all',
help = 'pop all the applied patches',
action = 'store_true'),
Check the 'git fetch' documentation for the <repository> format."""
+directory = DirectoryHasRepository()
options = [make_option('-n', '--nopush',
help = 'do not push the patches back after pulling',
action = 'store_true'),
The command also notifies when the patch becomes empty (fully merged
upstream) or is modified (three-way merged) by the 'push' operation."""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--all',
help = 'push all the unapplied patches',
action = 'store_true'),
Pop all patches from current stack, move the stack base to the given
<new-base-id> and push the patches back."""
+directory = DirectoryHasRepository()
options = [make_option('-n', '--nopush',
help = 'do not push the patches back after rebasing',
action = 'store_true'),
created with a different tool but the changes need to be included in
the current patch."""
+directory = DirectoryHasRepository()
options = [make_option('-f', '--force',
help = 'force the refresh even if HEAD and '\
'top differ',
Rename <oldpatch> into <newpatch> in a series."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
'C'. This command also removes any <file>.{ancestor,current,patched}
files."""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--all',
help = 'mark all conflicts as solved',
action = 'store_true'),
Remove given files from the repository. The command doesn't remove the
working copy of the file."""
+directory = DirectoryHasRepository()
options = [make_option('-f', '--force',
help = 'force removing even if the file exists',
action = 'store_true')]
with a '-' and the hidden ones with a '!'. The current patch is
prefixed with a '>'. Empty patches are prefixed with a '0'."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
make_option('-a', '--all',
patches. The output is similar to that generated by the 'git show'
command."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
make_option('-a', '--applied',
then push back into place the formerly-applied patches (unless -n
is also given)."""
+directory = DirectoryHasRepository()
options = [make_option('-n', '--nopush',
help = 'do not push the patches back after sinking',
action = 'store_true'),
A 'refresh' command clears the status of the modified, new and deleted
files."""
+directory = DirectoryHasRepository()
options = [make_option('-m', '--modified',
help = 'show modified files only',
action = 'store_true'),
The sync operation can be reverted for individual patches with --undo."""
+directory = DirectoryHasRepository()
options = [make_option('-a', '--all',
help = 'synchronise all the patches',
action = 'store_true'),
Print the name of the current (topmost) patch."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
List the patches from the series which are not pushed onto the stack.
They are listed in the reverse order in which they were popped."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
make_option('-c', '--count',
Only commits with exactly one parent can be uncommitted; in other
words, you can't uncommit a merge."""
+directory = DirectoryHasRepository()
options = [make_option('-n', '--number', type = 'int',
help = 'uncommit the specified number of commits'),
make_option('-t', '--to',
Unhide a hidden range of patches so that they are shown in the plain
'series' command output."""
+directory = DirectoryHasRepository()
options = [make_option('-b', '--branch',
help = 'use BRANCH instead of the default one')]
usage = command.usage.split('\n')[0].strip()
parser = OptionParser(usage = usage, option_list = command.options)
options, args = parser.parse_args()
+ directory = command.directory
# These modules are only used from this point onwards and do not
# need to be imported earlier
sys.exit(1)
try:
+ directory.setup()
config_setup()
# 'clone' doesn't expect an already initialised GIT tree. A Series