Skip to content

Commit 808d3d7

Browse files
committed
git add: -u/-A now affects the entire working tree
As promised in 0fa2eb5 (add: warn when -u or -A is used without pathspec, 2013-01-28), in Git 2.0, "git add -u/-A" that is run without pathspec in a subdirectory updates all updated paths in the entire working tree, not just the current directory and its subdirectories. Signed-off-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b75cdfa commit 808d3d7

File tree

4 files changed

+19
-121
lines changed

4 files changed

+19
-121
lines changed

Documentation/git-add.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,10 @@ apply to the index. See EDITING PATCHES below.
104104
<pathspec>. This removes as well as modifies index entries to
105105
match the working tree, but adds no new files.
106106
+
107-
If no <pathspec> is given, the current version of Git defaults to
108-
"."; in other words, update all tracked files in the current directory
109-
and its subdirectories. This default will change in a future version
110-
of Git, hence the form without <pathspec> should not be used.
107+
If no <pathspec> is given when `-u` option is used, all
108+
tracked files in the entire working tree are updated (old versions
109+
of Git used to limit the update to the current directory and its
110+
subdirectories).
111111

112112
-A::
113113
--all::
@@ -117,10 +117,10 @@ of Git, hence the form without <pathspec> should not be used.
117117
entry. This adds, modifies, and removes index entries to
118118
match the working tree.
119119
+
120-
If no <pathspec> is given, the current version of Git defaults to
121-
"."; in other words, update all files in the current directory
122-
and its subdirectories. This default will change in a future version
123-
of Git, hence the form without <pathspec> should not be used.
120+
If no <pathspec> is given when `-A` option is used, all
121+
files in the entire working tree are updated (old versions
122+
of Git used to limit the update to the current directory and its
123+
subdirectories).
124124

125125
--no-all::
126126
--ignore-removal::

builtin/add.c

Lines changed: 9 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -26,55 +26,10 @@ static int take_worktree_changes;
2626
struct update_callback_data {
2727
int flags;
2828
int add_errors;
29-
const char *implicit_dot;
30-
size_t implicit_dot_len;
31-
3229
/* only needed for 2.0 transition preparation */
3330
int warn_add_would_remove;
3431
};
3532

36-
static const char *option_with_implicit_dot;
37-
static const char *short_option_with_implicit_dot;
38-
39-
static void warn_pathless_add(void)
40-
{
41-
static int shown;
42-
assert(option_with_implicit_dot && short_option_with_implicit_dot);
43-
44-
if (shown)
45-
return;
46-
shown = 1;
47-
48-
/*
49-
* To be consistent with "git add -p" and most Git
50-
* commands, we should default to being tree-wide, but
51-
* this is not the original behavior and can't be
52-
* changed until users trained themselves not to type
53-
* "git add -u" or "git add -A". For now, we warn and
54-
* keep the old behavior. Later, the behavior can be changed
55-
* to tree-wide, keeping the warning for a while, and
56-
* eventually we can drop the warning.
57-
*/
58-
warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n"
59-
"subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n"
60-
"To add content for the whole tree, run:\n"
61-
"\n"
62-
" git add %s :/\n"
63-
" (or git add %s :/)\n"
64-
"\n"
65-
"To restrict the command to the current directory, run:\n"
66-
"\n"
67-
" git add %s .\n"
68-
" (or git add %s .)\n"
69-
"\n"
70-
"With the current Git version, the command is restricted to "
71-
"the current directory.\n"
72-
""),
73-
option_with_implicit_dot, short_option_with_implicit_dot,
74-
option_with_implicit_dot, short_option_with_implicit_dot,
75-
option_with_implicit_dot, short_option_with_implicit_dot);
76-
}
77-
7833
static int fix_unmerged_status(struct diff_filepair *p,
7934
struct update_callback_data *data)
8035
{
@@ -119,26 +74,10 @@ static void update_callback(struct diff_queue_struct *q,
11974
{
12075
int i;
12176
struct update_callback_data *data = cbdata;
122-
const char *implicit_dot = data->implicit_dot;
123-
size_t implicit_dot_len = data->implicit_dot_len;
12477

12578
for (i = 0; i < q->nr; i++) {
12679
struct diff_filepair *p = q->queue[i];
12780
const char *path = p->one->path;
128-
/*
129-
* Check if "git add -A" or "git add -u" was run from a
130-
* subdirectory with a modified file outside that directory,
131-
* and warn if so.
132-
*
133-
* "git add -u" will behave like "git add -u :/" instead of
134-
* "git add -u ." in the future. This warning prepares for
135-
* that change.
136-
*/
137-
if (implicit_dot &&
138-
strncmp_icase(path, implicit_dot, implicit_dot_len)) {
139-
warn_pathless_add();
140-
continue;
141-
}
14281
switch (fix_unmerged_status(p, data)) {
14382
default:
14483
die(_("unexpected diff status %c"), p->status);
@@ -191,9 +130,7 @@ int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
191130
return !!data.add_errors;
192131
}
193132

194-
#define WARN_IMPLICIT_DOT (1u << 0)
195-
static char *prune_directory(struct dir_struct *dir, const char **pathspec,
196-
int prefix, unsigned flag)
133+
static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
197134
{
198135
char *seen;
199136
int i, specs;
@@ -210,16 +147,6 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec,
210147
if (match_pathspec(pathspec, entry->name, entry->len,
211148
prefix, seen))
212149
*dst++ = entry;
213-
else if (flag & WARN_IMPLICIT_DOT)
214-
/*
215-
* "git add -A" was run from a subdirectory with a
216-
* new file outside that directory.
217-
*
218-
* "git add -A" will behave like "git add -A :/"
219-
* instead of "git add -A ." in the future.
220-
* Warn about the coming behavior change.
221-
*/
222-
warn_pathless_add();
223150
}
224151
dir->nr = dst - dir->entries;
225152
add_pathspec_matches_against_index(pathspec, seen, specs);
@@ -451,7 +378,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
451378
int add_new_files;
452379
int require_pathspec;
453380
char *seen = NULL;
454-
int implicit_dot = 0;
455381
struct update_callback_data update_data;
456382

457383
git_config(add_config, NULL);
@@ -493,19 +419,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
493419

494420
if (!show_only && ignore_missing)
495421
die(_("Option --ignore-missing can only be used together with --dry-run"));
496-
if (addremove) {
497-
option_with_implicit_dot = "--all";
498-
short_option_with_implicit_dot = "-A";
499-
}
500-
if (take_worktree_changes) {
501-
option_with_implicit_dot = "--update";
502-
short_option_with_implicit_dot = "-u";
503-
}
504-
if (option_with_implicit_dot && !argc) {
505-
static const char *here[2] = { ".", NULL };
422+
423+
if ((addremove || take_worktree_changes) && !argc) {
424+
static const char *whole[2] = { ":/", NULL };
506425
argc = 1;
507-
argv = here;
508-
implicit_dot = 1;
426+
argv = whole;
509427
}
510428

511429
add_new_files = !take_worktree_changes && !refresh_only;
@@ -518,8 +436,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
518436
(intent_to_add ? ADD_CACHE_INTENT : 0) |
519437
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
520438
(!(addremove || take_worktree_changes)
521-
? ADD_CACHE_IGNORE_REMOVAL : 0)) |
522-
(implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0);
439+
? ADD_CACHE_IGNORE_REMOVAL : 0));
523440

524441
if (require_pathspec && argc == 0) {
525442
fprintf(stderr, _("Nothing specified, nothing added.\n"));
@@ -543,18 +460,15 @@ int cmd_add(int argc, const char **argv, const char *prefix)
543460
}
544461

545462
/* This picks up the paths that are not tracked */
546-
baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec);
463+
baselen = fill_directory(&dir, pathspec);
547464
if (pathspec)
548-
seen = prune_directory(&dir, pathspec, baselen,
549-
implicit_dot ? WARN_IMPLICIT_DOT : 0);
465+
seen = prune_directory(&dir, pathspec, baselen);
550466
}
551467

552468
if (refresh_only) {
553469
refresh(verbose, pathspec);
554470
goto finish;
555471
}
556-
if (implicit_dot && prefix)
557-
refresh_cache(REFRESH_QUIET);
558472

559473
if (pathspec) {
560474
int i;
@@ -578,17 +492,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
578492

579493
plug_bulk_checkin();
580494

581-
if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) {
582-
/*
583-
* Check for modified files throughout the worktree so
584-
* update_callback has a chance to warn about changes
585-
* outside the cwd.
586-
*/
587-
update_data.implicit_dot = prefix;
588-
update_data.implicit_dot_len = strlen(prefix);
589-
pathspec = NULL;
590-
}
591-
update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT;
495+
update_data.flags = flags;
592496
update_files_in_cache(prefix, pathspec, &update_data);
593497

594498
exit_status |= !!update_data.add_errors;

cache.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ extern int remove_file_from_index(struct index_state *, const char *path);
466466
#define ADD_CACHE_IGNORE_ERRORS 4
467467
#define ADD_CACHE_IGNORE_REMOVAL 8
468468
#define ADD_CACHE_INTENT 16
469-
#define ADD_CACHE_IMPLICIT_DOT 32 /* internal to "git add -u/-A" */
470469
extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);
471470
extern int add_file_to_index(struct index_state *, const char *path, int flags);
472471
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);

t/t2200-add-update.sh

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,13 @@ test_expect_success 'change gets noticed' '
8080
8181
'
8282

83-
# Note that this is scheduled to change in Git 2.0, when
84-
# "git add -u" will become full-tree by default.
85-
test_expect_success 'non-limited update in subdir leaves root alone' '
83+
test_expect_success 'non-qualified update in subdir updates from the root' '
8684
(
8785
cd dir1 &&
8886
echo even more >>sub2 &&
8987
git add -u
9088
) &&
91-
cat >expect <<-\EOF &&
92-
check
93-
top
94-
EOF
89+
: >expect &&
9590
git diff-files --name-only >actual &&
9691
test_cmp expect actual
9792
'

0 commit comments

Comments
 (0)