A common workflow in large projects is to chdir into a subdirectory of interest and only do work there: cd src vi foo.c make test git add -u git commit The upcoming change to 'git add -u' behavior would not affect such a workflow: when the only changes present are in the current directory, 'git add -u' will add all changes, and whether that happens via an implicit "." or implicit ":/" parameter is an unimportant implementation detail. The warning about use of 'git add -u' with no pathspec is annoying because it serves no purpose in this case. So suppress the warning unless there are changes outside the cwd that are not being added. Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- builtin/add.c | 51 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/builtin/add.c b/builtin/add.c index a424e69d..f05ec1c1 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -89,6 +89,22 @@ static int fix_unmerged_status(struct diff_filepair *p, return DIFF_STATUS_MODIFIED; } +static void warn_if_outside_pathspec(struct diff_queue_struct *q, + struct diff_options *opt, void *cbdata) +{ + int i; + const char **pathspec = cbdata; + + for (i = 0; i < q->nr; i++) { + const char *path = q->queue[i]->one->path; + + if (!match_pathspec(pathspec, path, strlen(path), 0, NULL)) { + warn_pathless_add(); + return; + } + } +} + static void update_callback(struct diff_queue_struct *q, struct diff_options *opt, void *cbdata) { @@ -121,20 +137,26 @@ static void update_callback(struct diff_queue_struct *q, } } -int add_files_to_cache(const char *prefix, const char **pathspec, int flags) +static void diff_files_with_callback(const char *prefix, const char **pathspec, + diff_format_fn_t callback, void *data) { - struct update_callback_data data; struct rev_info rev; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); init_pathspec(&rev.prune_data, pathspec); rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; - rev.diffopt.format_callback = update_callback; - data.flags = flags; - data.add_errors = 0; - rev.diffopt.format_callback_data = &data; + rev.diffopt.format_callback = callback; + rev.diffopt.format_callback_data = data; rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); +} + +int add_files_to_cache(const char *prefix, const char **pathspec, int flags) +{ + struct update_callback_data data; + data.flags = flags; + data.add_errors = 0; + diff_files_with_callback(prefix, pathspec, update_callback, &data); return !!data.add_errors; } @@ -371,6 +393,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) int add_new_files; int require_pathspec; char *seen = NULL; + int implicit_dot = 0; git_config(add_config, NULL); @@ -400,10 +423,11 @@ int cmd_add(int argc, const char **argv, const char *prefix) } if (option_with_implicit_dot && !argc) { static const char *here[2] = { ".", NULL }; - if (prefix) + if (prefix && addremove) warn_pathless_add(); argc = 1; argv = here; + implicit_dot = 1; } add_new_files = !take_worktree_changes && !refresh_only; @@ -450,6 +474,19 @@ int cmd_add(int argc, const char **argv, const char *prefix) goto finish; } + /* + * Check if "git add -A" or "git add -u" was run from a + * subdirectory with a modified file outside that directory, + * and warn if so. + * + * "git add -u" will behave like "git add -u :/" instead of + * "git add -u ." in the future. This warning prepares for + * that change. + */ + if (implicit_dot) + diff_files_with_callback(prefix, NULL, + warn_if_outside_pathspec, pathspec); + if (pathspec) { int i; struct path_exclude_check check; -- 1.8.2.rc3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html