add: convert to use parse_pathspec

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2013-07-14 15:35:46 +07:00 committed by Junio C Hamano
parent 931eab64ad
commit 5a76aff1a6
2 changed files with 45 additions and 101 deletions

View file

@ -226,21 +226,6 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec,
return seen; return seen;
} }
/*
* Checks the index to see whether any path in pathspec refers to
* something inside a submodule. If so, dies with an error message.
*/
static void treat_gitlinks(const char **pathspec)
{
int i;
if (!pathspec || !*pathspec)
return;
for (i = 0; pathspec[i]; i++)
pathspec[i] = check_path_for_gitlink(pathspec[i]);
}
static void refresh(int verbose, const char **pathspec) static void refresh(int verbose, const char **pathspec)
{ {
char *seen; char *seen;
@ -258,25 +243,6 @@ static void refresh(int verbose, const char **pathspec)
free(seen); free(seen);
} }
/*
* Normalizes argv relative to prefix, via get_pathspec(), and then
* runs die_if_path_beyond_symlink() on each path in the normalized
* list.
*/
static const char **validate_pathspec(const char **argv, const char *prefix)
{
const char **pathspec = get_pathspec(prefix, argv);
if (pathspec) {
const char **p;
for (p = pathspec; *p; p++) {
die_if_path_beyond_symlink(*p, prefix);
}
}
return pathspec;
}
int run_add_interactive(const char *revision, const char *patch_mode, int run_add_interactive(const char *revision, const char *patch_mode,
const char **pathspec) const char **pathspec)
{ {
@ -308,17 +274,23 @@ int run_add_interactive(const char *revision, const char *patch_mode,
int interactive_add(int argc, const char **argv, const char *prefix, int patch) int interactive_add(int argc, const char **argv, const char *prefix, int patch)
{ {
const char **pathspec = NULL; struct pathspec pathspec;
if (argc) { /*
pathspec = validate_pathspec(argv, prefix); * git-add--interactive itself does not parse pathspec. It
if (!pathspec) * simply passes the pathspec to other builtin commands. Let's
return -1; * hope all of them support all magic, or we'll need to limit
} * the magic here. There is still a problem with prefix. But
* that'll be worked on later on.
*/
parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
PATHSPEC_PREFER_FULL |
PATHSPEC_SYMLINK_LEADING_PATH,
prefix, argv);
return run_add_interactive(NULL, return run_add_interactive(NULL,
patch ? "--patch" : NULL, patch ? "--patch" : NULL,
pathspec); pathspec.raw);
} }
static int edit_patch(int argc, const char **argv, const char *prefix) static int edit_patch(int argc, const char **argv, const char *prefix)
@ -445,7 +417,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
{ {
int exit_status = 0; int exit_status = 0;
int newfd; int newfd;
const char **pathspec; struct pathspec pathspec;
struct dir_struct dir; struct dir_struct dir;
int flags; int flags;
int add_new_files; int add_new_files;
@ -526,11 +498,19 @@ int cmd_add(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n")); fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
return 0; return 0;
} }
pathspec = validate_pathspec(argv, prefix);
if (read_cache() < 0) if (read_cache() < 0)
die(_("index file corrupt")); die(_("index file corrupt"));
treat_gitlinks(pathspec);
/*
* Check the "pathspec '%s' did not match any files" block
* below before enabling new magic.
*/
parse_pathspec(&pathspec, 0,
PATHSPEC_PREFER_FULL |
PATHSPEC_SYMLINK_LEADING_PATH |
PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
prefix, argv);
if (add_new_files) { if (add_new_files) {
int baselen; int baselen;
@ -543,34 +523,40 @@ int cmd_add(int argc, const char **argv, const char *prefix)
} }
/* This picks up the paths that are not tracked */ /* This picks up the paths that are not tracked */
baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec); baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec.raw);
if (pathspec) if (pathspec.nr)
seen = prune_directory(&dir, pathspec, baselen, seen = prune_directory(&dir, pathspec.raw, baselen,
implicit_dot ? WARN_IMPLICIT_DOT : 0); implicit_dot ? WARN_IMPLICIT_DOT : 0);
} }
if (refresh_only) { if (refresh_only) {
refresh(verbose, pathspec); refresh(verbose, pathspec.raw);
goto finish; goto finish;
} }
if (implicit_dot && prefix) if (implicit_dot && prefix)
refresh_cache(REFRESH_QUIET); refresh_cache(REFRESH_QUIET);
if (pathspec) { if (pathspec.nr) {
int i; int i;
if (!seen) if (!seen)
seen = find_pathspecs_matching_against_index(pathspec); seen = find_pathspecs_matching_against_index(pathspec.raw);
for (i = 0; pathspec[i]; i++) {
if (!seen[i] && pathspec[i][0] /*
&& !file_exists(pathspec[i])) { * file_exists() assumes exact match
*/
GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP);
for (i = 0; pathspec.raw[i]; i++) {
if (!seen[i] && pathspec.raw[i][0]
&& !file_exists(pathspec.raw[i])) {
if (ignore_missing) { if (ignore_missing) {
int dtype = DT_UNKNOWN; int dtype = DT_UNKNOWN;
if (is_excluded(&dir, pathspec[i], &dtype)) if (is_excluded(&dir, pathspec.raw[i], &dtype))
dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));
} else } else
die(_("pathspec '%s' did not match any files"), die(_("pathspec '%s' did not match any files"),
pathspec[i]); pathspec.raw[i]);
} }
} }
free(seen); free(seen);
@ -586,10 +572,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
*/ */
update_data.implicit_dot = prefix; update_data.implicit_dot = prefix;
update_data.implicit_dot_len = strlen(prefix); update_data.implicit_dot_len = strlen(prefix);
pathspec = NULL; free_pathspec(&pathspec);
memset(&pathspec, 0, sizeof(pathspec));
} }
update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT; update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
update_files_in_cache(prefix, pathspec, &update_data); update_files_in_cache(prefix, pathspec.raw, &update_data);
exit_status |= !!update_data.add_errors; exit_status |= !!update_data.add_errors;
if (add_new_files) if (add_new_files)

View file

@ -57,49 +57,6 @@ char *find_pathspecs_matching_against_index(const char **pathspec)
return seen; return seen;
} }
/*
* Check the index to see whether path refers to a submodule, or
* something inside a submodule. If the former, returns the path with
* any trailing slash stripped. If the latter, dies with an error
* message.
*/
const char *check_path_for_gitlink(const char *path)
{
int i, path_len = strlen(path);
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (S_ISGITLINK(ce->ce_mode)) {
int ce_len = ce_namelen(ce);
if (path_len <= ce_len || path[ce_len] != '/' ||
memcmp(ce->name, path, ce_len))
/* path does not refer to this
* submodule or anything inside it */
continue;
if (path_len == ce_len + 1) {
/* path refers to submodule;
* strip trailing slash */
return xstrndup(ce->name, ce_len);
} else {
die (_("Path '%s' is in submodule '%.*s'"),
path, ce_len, ce->name);
}
}
}
return path;
}
/*
* Dies if the given path refers to a file inside a symlinked
* directory in the index.
*/
void die_if_path_beyond_symlink(const char *path, const char *prefix)
{
if (has_symlink_leading_path(path, strlen(path))) {
int len = prefix ? strlen(prefix) : 0;
die(_("'%s' is beyond a symbolic link"), path + len);
}
}
/* /*
* Magic pathspec * Magic pathspec
* *