#include "string-list.h"
#include "pathspec.h"
#include "run-command.h"
+#include "submodule.h"
static int abbrev;
static int show_deleted;
static int debug_mode;
static int show_eol;
static int recurse_submodules;
+static struct argv_array submodule_options = ARGV_ARRAY_INIT;
static const char *prefix;
static const char *super_prefix;
}
}
+/*
+ * Compile an argv_array with all of the options supported by --recurse_submodules
+ */
+static void compile_submodule_options(const char **argv,
+ const struct dir_struct *dir,
+ int show_tag)
+{
+ if (line_terminator == '\0')
+ argv_array_push(&submodule_options, "-z");
+ if (show_tag)
+ argv_array_push(&submodule_options, "-t");
+ if (show_valid_bit)
+ argv_array_push(&submodule_options, "-v");
+ if (show_cached)
+ argv_array_push(&submodule_options, "--cached");
+ if (show_eol)
+ argv_array_push(&submodule_options, "--eol");
+ if (debug_mode)
+ argv_array_push(&submodule_options, "--debug");
+
+ /* Add Pathspecs */
+ argv_array_push(&submodule_options, "--");
+ for (; *argv; argv++)
+ argv_array_push(&submodule_options, *argv);
+}
+
/**
* Recursively call ls-files on a submodule
*/
{
struct child_process cp = CHILD_PROCESS_INIT;
int status;
+ char *dir;
+
+ prepare_submodule_repo_env(&cp.env_array);
+ argv_array_push(&cp.env_array, GIT_DIR_ENVIRONMENT);
+ if (prefix_len)
+ argv_array_pushf(&cp.env_array, "%s=%s",
+ GIT_TOPLEVEL_PREFIX_ENVIRONMENT,
+ prefix);
argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
super_prefix ? super_prefix : "",
ce->name);
argv_array_push(&cp.args, "ls-files");
argv_array_push(&cp.args, "--recurse-submodules");
+ /* add supported options */
+ argv_array_pushv(&cp.args, submodule_options.argv);
+
cp.git_cmd = 1;
- cp.dir = ce->name;
+ dir = mkpathdup("%s/%s", get_git_work_tree(), ce->name);
+ cp.dir = dir;
status = run_command(&cp);
+ free(dir);
if (status)
exit(status);
}
if (len >= ce_namelen(ce))
die("git ls-files: internal error - cache entry not superset of prefix");
- if (recurse_submodules && S_ISGITLINK(ce->ce_mode)) {
+ if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
+ submodule_path_match(&pathspec, name.buf, ps_matched)) {
show_gitlink(ce);
} else if (match_pathspec(&pathspec, name.buf, name.len,
len, ps_matched,
printf("%s%06o %s %d\t",
tag,
ce->ce_mode,
- find_unique_abbrev(ce->sha1,abbrev),
+ find_unique_abbrev(ce->oid.hash, abbrev),
ce_stage(ce));
}
write_eolinfo(ce, ce->name);
/*
* Prune the index to only contain stuff starting with "prefix"
*/
-static void prune_cache(const char *prefix)
+static void prune_cache(const char *prefix, size_t prefixlen)
{
- int pos = cache_name_pos(prefix, max_prefix_len);
+ int pos;
unsigned int first, last;
+ if (!prefix)
+ return;
+ pos = cache_name_pos(prefix, prefixlen);
if (pos < 0)
pos = -pos-1;
- memmove(active_cache, active_cache + pos,
- (active_nr - pos) * sizeof(struct cache_entry *));
- active_nr -= pos;
- first = 0;
+ first = pos;
last = active_nr;
while (last > first) {
int next = (last + first) >> 1;
const struct cache_entry *ce = active_cache[next];
- if (!strncmp(ce->name, prefix, max_prefix_len)) {
+ if (!strncmp(ce->name, prefix, prefixlen)) {
first = next+1;
continue;
}
last = next;
}
- active_nr = last;
+ memmove(active_cache, active_cache + pos,
+ (last - pos) * sizeof(struct cache_entry *));
+ active_nr = last - pos;
}
/*
void overlay_tree_on_cache(const char *tree_name, const char *prefix)
{
struct tree *tree;
- unsigned char sha1[20];
+ struct object_id oid;
struct pathspec pathspec;
struct cache_entry *last_stage0 = NULL;
int i;
- if (get_sha1(tree_name, sha1))
+ if (get_oid(tree_name, &oid))
die("tree-ish %s not found.", tree_name);
- tree = parse_tree_indirect(sha1);
+ tree = parse_tree_indirect(&oid);
if (!tree)
die("bad tree-ish %s", tree_name);
if (require_work_tree && !is_inside_work_tree())
setup_work_tree();
+ if (recurse_submodules)
+ compile_submodule_options(argv, &dir, show_tag);
+
if (recurse_submodules &&
(show_stage || show_deleted || show_others || show_unmerged ||
- show_killed || show_modified || show_resolve_undo ||
- show_valid_bit || show_tag || show_eol || with_tree ||
- (line_terminator == '\0')))
+ show_killed || show_modified || show_resolve_undo || with_tree))
die("ls-files --recurse-submodules unsupported mode");
if (recurse_submodules && error_unmatch)
die("ls-files --recurse-submodules does not support "
"--error-unmatch");
- if (recurse_submodules && argc)
- die("ls-files --recurse-submodules does not support pathspec");
-
parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_CWD |
PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
prefix, argv);
- /* Find common prefix for all pathspec's */
- max_prefix = common_prefix(&pathspec);
+ /*
+ * Find common prefix for all pathspec's
+ * This is used as a performance optimization which unfortunately cannot
+ * be done when recursing into submodules
+ */
+ if (recurse_submodules)
+ max_prefix = NULL;
+ else
+ max_prefix = common_prefix(&pathspec);
max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
/* Treat unmatching pathspec elements as errors */
show_killed || show_modified || show_resolve_undo))
show_cached = 1;
- if (max_prefix)
- prune_cache(max_prefix);
+ prune_cache(max_prefix, max_prefix_len);
if (with_tree) {
/*
* Basic sanity check; show-stages and show-unmerged