This is mainly achieved by checking the file arguments with
git-ls-files. The patch solves two main issues - the refresh/diff/st
can run properly in subdirectories and commands like diff and status
may no longer get nonexistent files as arguments without complaining.
If one wants to check the status/diff or refresh the files in a
subdirectory, the command arguments should be "." and this is expanded
by git-ls-files to the subdirectory content (recursively).
The patch removes some asserts as they are no longer needed since
checks are performed by git-ls-files.
Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
help = 'show the tree diff'
help = 'show the tree diff'
-usage = """%prog [options] [<files...>]
+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
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
def func(parser, options, args):
"""Show the tree diff
"""
def func(parser, options, args):
"""Show the tree diff
"""
+ args = git.ls_files(args)
+ directory.cd_to_topdir()
+
if options.revs:
rev_list = options.revs.split('..')
rev_list_len = len(rev_list)
if options.revs:
rev_list = options.revs.split('..')
rev_list_len = len(rev_list)
help = 'show the applied patches modifying a file'
help = 'show the applied patches modifying a file'
-usage = """%prog [options] [<files...>]
+usage = """%prog [options] [<files or dirs>]
Show the applied patches modifying the given files. Without arguments,
it shows the patches affected by the local tree modifications. The
Show the applied patches modifying the given files. Without arguments,
it shows the patches affected by the local tree modifications. The
"""
if not args:
files = [path for (stat,path) in git.tree_status(verbose = True)]
"""
if not args:
files = [path for (stat,path) in git.tree_status(verbose = True)]
+ # git.tree_status returns absolute paths
+ files = git.ls_files(args)
+ directory.cd_to_topdir()
if not files:
raise CmdException, 'No files specified or no local changes'
if not files:
raise CmdException, 'No files specified or no local changes'
help = 'generate a new commit for the current patch'
help = 'generate a new commit for the current patch'
-usage = """%prog [options] [<files...>]
+usage = """%prog [options] [<files or dirs>]
Include the latest tree changes in the current patch. This command
generates a new GIT commit object with the patch details, the previous
Include the latest tree changes in the current patch. This command
generates a new GIT commit object with the patch details, the previous
created with a different tool but the changes need to be included in
the current patch."""
created with a different tool but the changes need to be included in
the current patch."""
-directory = DirectoryGotoToplevel()
+directory = DirectoryHasRepository()
options = [make_option('-f', '--force',
help = 'force the refresh even if HEAD and '\
'top differ',
options = [make_option('-f', '--force',
help = 'force the refresh even if HEAD and '\
'top differ',
]
def func(parser, options, args):
]
def func(parser, options, args):
- autoresolved = config.get('stgit.autoresolved')
+ """Generate a new commit for the current or given patch.
+ """
+ args = git.ls_files(args)
+ directory.cd_to_topdir()
+ autoresolved = config.get('stgit.autoresolved')
if autoresolved != 'yes':
check_conflicts()
if autoresolved != 'yes':
check_conflicts()
- files = [path for (stat,path) in git.tree_status(verbose = True)]
- if args:
- files = [f for f in files if f in args]
+ files = [path for (stat, path) in git.tree_status(files = args, verbose = True)]
if files or not crt_series.head_top_equal():
if options.patch:
if files or not crt_series.head_top_equal():
if options.patch:
help = 'show the tree status'
help = 'show the tree status'
-usage = """%prog [options] [<files...>]
+usage = """%prog [options] [<files or dirs>]
Show the status of the whole working copy or the given files. The
command also shows the files in the current directory which are not
Show the status of the whole working copy or the given files. The
command also shows the files in the current directory which are not
"""Show the tree status
"""
cache_files = git.tree_status(files,
"""Show the tree status
"""
cache_files = git.tree_status(files,
- unknown = (files == None),
noexclude = noexclude,
diff_flags = diff_flags)
filtered = (modified or new or deleted or conflict or unknown)
noexclude = noexclude,
diff_flags = diff_flags)
filtered = (modified or new or deleted or conflict or unknown)
output = []
for st, fn in cache_files:
output = []
for st, fn in cache_files:
- assert files == None or fn in files
if filtered:
output.append(fn)
else:
if filtered:
output.append(fn)
else:
def func(parser, options, args):
"""Show the tree status
"""
def func(parser, options, args):
"""Show the tree status
"""
+ args = git.ls_files(args)
+ directory.cd_to_topdir()
+
if options.reset:
if args:
for f in args:
if options.reset:
if args:
for f in args:
- # No args means all files
- if not args:
- args = None
status(args, options.modified, options.new, options.deleted,
options.conflict, options.unknown, options.noexclude,
diff_flags = diff_flags)
status(args, options.modified, options.new, options.deleted,
options.conflict, options.unknown, options.noexclude,
diff_flags = diff_flags)
files.append(user_exclude)
return files
files.append(user_exclude)
return files
+def ls_files(files, tree = None, full_name = True):
+ """Return the files known to GIT or raise an error otherwise. It also
+ converts the file to the full path relative the the .git directory.
+ """
+ if not files:
+ return []
+
+ args = []
+ if tree:
+ args.append('--with-tree=%s' % tree)
+ if full_name:
+ args.append('--full-name')
+ args.append('--')
+ args.extend(files)
+ try:
+ return GRun('git-ls-files', '--error-unmatch', *args).output_lines()
+ except GitRunException:
+ # just hide the details of the git-ls-files command we use
+ raise GitException, \
+ 'Some of the given paths are either missing or not known to GIT'
+
def tree_status(files = None, tree_id = 'HEAD', unknown = False,
noexclude = True, verbose = False, diff_flags = []):
"""Get the status of all changed files, or of a selected set of
files. Returns a list of pairs - (status, filename).
def tree_status(files = None, tree_id = 'HEAD', unknown = False,
noexclude = True, verbose = False, diff_flags = []):
"""Get the status of all changed files, or of a selected set of
files. Returns a list of pairs - (status, filename).
- If 'files' is None, it will check all files, and optionally all
+ If 'not files', it will check all files, and optionally all
unknown files. If 'files' is a list, it will only check the files
in the list.
"""
unknown files. If 'files' is a list, it will only check the files
in the list.
"""
- assert files == None or not unknown
+ assert not files or not unknown
if verbose:
out.start('Checking for changes in the working directory')
if verbose:
out.start('Checking for changes in the working directory')
if not conflicts:
conflicts = []
cache_files += [('C', filename) for filename in conflicts
if not conflicts:
conflicts = []
cache_files += [('C', filename) for filename in conflicts
- if files == None or filename in files]
+ if not files or filename in files]
# the rest
args = diff_flags + [tree_id]
# the rest
args = diff_flags + [tree_id]
args += ['--'] + files
for line in GRun('git-diff-index', *args).output_lines():
fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
args += ['--'] + files
for line in GRun('git-diff-index', *args).output_lines():
fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
- assert files == None or set(f for s,f in cache_files) <= set(files)
return cache_files
def local_changes(verbose = True):
return cache_files
def local_changes(verbose = True):
'
cat > expected.txt <<EOF
'
cat > expected.txt <<EOF
EOF
test_expect_success 'Status of dir' '
stg status foo > output.txt &&
EOF
test_expect_success 'Status of dir' '
stg status foo > output.txt &&
[ "$(stg status)" = "" ]
'
[ "$(stg status)" = "" ]
'
+test_expect_success 'Refresh file in subdirectory' '
+ echo foo3 >> foo.txt &&
+ echo bar3 >> bar/bar.txt &&
+ cd bar &&
+ stg refresh bar.txt &&
+ cd .. &&
+ [ "$(stg status)" = "M foo.txt" ]
+'
+
+test_expect_success 'Refresh whole subdirectory' '
+ echo bar4 >> bar/bar.txt &&
+ stg refresh bar &&
+ [ "$(stg status)" = "M foo.txt" ]
+'
+
+test_expect_success 'Refresh subdirectories recursively' '
+ echo bar5 >> bar/bar.txt &&
+ stg refresh . &&
+ [ "$(stg status)" = "" ]
+'
+