Skip to content

Commit c78a249

Browse files
committed
Merge branch 'jc/maint-add-sync-stat'
* jc/maint-add-sync-stat: t2200: test more cases of "add -u" git-add: make the entry stat-clean after re-adding the same contents ce_match_stat, run_diff_files: use symbolic constants for readability Conflicts: builtin-add.c
2 parents ef4de83 + 25487bd commit c78a249

File tree

10 files changed

+92
-38
lines changed

10 files changed

+92
-38
lines changed

builtin-add.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void add_files_to_cache(int verbose, const char *prefix, const char **files)
120120
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
121121
rev.diffopt.format_callback = update_callback;
122122
rev.diffopt.format_callback_data = &verbose;
123-
run_diff_files(&rev, 0);
123+
run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
124124
}
125125

126126
static void refresh(int verbose, const char **pathspec)

builtin-apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1993,7 +1993,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
19931993
return -1;
19941994
return 0;
19951995
}
1996-
return ce_match_stat(ce, st, 1);
1996+
return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID);
19971997
}
19981998

19991999
static int check_patch(struct patch *patch, struct patch *prev_patch)

cache.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ extern struct index_state the_index;
175175
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
176176
#define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
177177
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
178-
#define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really))
179-
#define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really))
178+
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
179+
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
180180
#endif
181181

182182
enum object_type {
@@ -268,8 +268,14 @@ extern int remove_file_from_index(struct index_state *, const char *path);
268268
extern int add_file_to_index(struct index_state *, const char *path, int verbose);
269269
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
270270
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
271-
extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int);
272-
extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
271+
272+
/* do stat comparison even if CE_VALID is true */
273+
#define CE_MATCH_IGNORE_VALID 01
274+
/* do not check the contents but report dirty on racily-clean entries */
275+
#define CE_MATCH_RACY_IS_DIRTY 02
276+
extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
277+
extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
278+
273279
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
274280
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
275281
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);

check-racy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ int main(int ac, char **av)
1818

1919
if (ce_match_stat(ce, &st, 0))
2020
dirty++;
21-
else if (ce_match_stat(ce, &st, 2))
21+
else if (ce_match_stat(ce, &st, CE_MATCH_RACY_IS_DIRTY))
2222
racy++;
2323
else
2424
clean++;

diff-lib.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,10 @@ static int is_in_index(const char *path)
173173
}
174174

175175
static int handle_diff_files_args(struct rev_info *revs,
176-
int argc, const char **argv, int *silent)
176+
int argc, const char **argv,
177+
unsigned int *options)
177178
{
178-
*silent = 0;
179+
*options = 0;
179180

180181
/* revs->max_count == -2 means --no-index */
181182
while (1 < argc && argv[1][0] == '-') {
@@ -192,7 +193,7 @@ static int handle_diff_files_args(struct rev_info *revs,
192193
revs->diffopt.no_index = 1;
193194
}
194195
else if (!strcmp(argv[1], "-q"))
195-
*silent = 1;
196+
*options |= DIFF_SILENT_ON_REMOVED;
196197
else
197198
return error("invalid option: %s", argv[1]);
198199
argv++; argc--;
@@ -305,9 +306,9 @@ int setup_diff_no_index(struct rev_info *revs,
305306

306307
int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
307308
{
308-
int silent_on_removed;
309+
unsigned int options;
309310

310-
if (handle_diff_files_args(revs, argc, argv, &silent_on_removed))
311+
if (handle_diff_files_args(revs, argc, argv, &options))
311312
return -1;
312313

313314
if (revs->diffopt.no_index) {
@@ -329,13 +330,16 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
329330
perror("read_cache");
330331
return -1;
331332
}
332-
return run_diff_files(revs, silent_on_removed);
333+
return run_diff_files(revs, options);
333334
}
334335

335-
int run_diff_files(struct rev_info *revs, int silent_on_removed)
336+
int run_diff_files(struct rev_info *revs, unsigned int option)
336337
{
337338
int entries, i;
338339
int diff_unmerged_stage = revs->max_count;
340+
int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
341+
unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
342+
? CE_MATCH_RACY_IS_DIRTY : 0);
339343

340344
if (diff_unmerged_stage < 0)
341345
diff_unmerged_stage = 2;
@@ -441,7 +445,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
441445
ce->sha1, ce->name, NULL);
442446
continue;
443447
}
444-
changed = ce_match_stat(ce, &st, 0);
448+
changed = ce_match_stat(ce, &st, ce_option);
445449
if (!changed && !revs->diffopt.find_copies_harder)
446450
continue;
447451
oldmode = ntohl(ce->ce_mode);

diff.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,11 @@ extern void diff_flush(struct diff_options*);
224224

225225
extern const char *diff_unique_abbrev(const unsigned char *, int);
226226

227-
extern int run_diff_files(struct rev_info *revs, int silent_on_removed);
227+
/* do not report anything on removed paths */
228+
#define DIFF_SILENT_ON_REMOVED 01
229+
/* report racily-clean paths as modified */
230+
#define DIFF_RACY_IS_MODIFIED 02
231+
extern int run_diff_files(struct rev_info *revs, unsigned int option);
228232
extern int setup_diff_no_index(struct rev_info *revs,
229233
int argc, const char ** argv, int nongit, const char *prefix);
230234
extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);

entry.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
203203
strcpy(path + len, ce->name);
204204

205205
if (!lstat(path, &st)) {
206-
unsigned changed = ce_match_stat(ce, &st, 1);
206+
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
207207
if (!changed)
208208
return 0;
209209
if (!state->force) {

read-cache.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
194194
}
195195

196196
int ie_match_stat(struct index_state *istate,
197-
struct cache_entry *ce, struct stat *st, int options)
197+
struct cache_entry *ce, struct stat *st,
198+
unsigned int options)
198199
{
199200
unsigned int changed;
200-
int ignore_valid = options & 01;
201-
int assume_racy_is_modified = options & 02;
201+
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
202+
int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY;
202203

203204
/*
204205
* If it's marked as always valid in the index, it's
@@ -238,10 +239,11 @@ int ie_match_stat(struct index_state *istate,
238239
}
239240

240241
int ie_modified(struct index_state *istate,
241-
struct cache_entry *ce, struct stat *st, int really)
242+
struct cache_entry *ce, struct stat *st, unsigned int options)
242243
{
243244
int changed, changed_fs;
244-
changed = ie_match_stat(istate, ce, st, really);
245+
246+
changed = ie_match_stat(istate, ce, st, options);
245247
if (!changed)
246248
return 0;
247249
/*
@@ -387,6 +389,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
387389
int size, namelen, pos;
388390
struct stat st;
389391
struct cache_entry *ce;
392+
unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
390393

391394
if (lstat(path, &st))
392395
die("%s: unable to stat (%s)", path, strerror(errno));
@@ -421,7 +424,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
421424
pos = index_name_pos(istate, ce->name, namelen);
422425
if (0 <= pos &&
423426
!ce_stage(istate->cache[pos]) &&
424-
!ie_modified(istate, istate->cache[pos], &st, 1)) {
427+
!ie_match_stat(istate, istate->cache[pos], &st, ce_option)) {
425428
/* Nothing changed, really */
426429
free(ce);
427430
return 0;
@@ -783,28 +786,37 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
783786
* to link up the stat cache details with the proper files.
784787
*/
785788
static struct cache_entry *refresh_cache_ent(struct index_state *istate,
786-
struct cache_entry *ce, int really, int *err)
789+
struct cache_entry *ce,
790+
unsigned int options, int *err)
787791
{
788792
struct stat st;
789793
struct cache_entry *updated;
790794
int changed, size;
795+
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
791796

792797
if (lstat(ce->name, &st) < 0) {
793798
if (err)
794799
*err = errno;
795800
return NULL;
796801
}
797802

798-
changed = ie_match_stat(istate, ce, &st, really);
803+
changed = ie_match_stat(istate, ce, &st, options);
799804
if (!changed) {
800-
if (really && assume_unchanged &&
805+
/*
806+
* The path is unchanged. If we were told to ignore
807+
* valid bit, then we did the actual stat check and
808+
* found that the entry is unmodified. If the entry
809+
* is not marked VALID, this is the place to mark it
810+
* valid again, under "assume unchanged" mode.
811+
*/
812+
if (ignore_valid && assume_unchanged &&
801813
!(ce->ce_flags & htons(CE_VALID)))
802814
; /* mark this one VALID again */
803815
else
804816
return ce;
805817
}
806818

807-
if (ie_modified(istate, ce, &st, really)) {
819+
if (ie_modified(istate, ce, &st, options)) {
808820
if (err)
809821
*err = EINVAL;
810822
return NULL;
@@ -815,13 +827,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
815827
memcpy(updated, ce, size);
816828
fill_stat_cache_info(updated, &st);
817829

818-
/* In this case, if really is not set, we should leave
819-
* CE_VALID bit alone. Otherwise, paths marked with
820-
* --no-assume-unchanged (i.e. things to be edited) will
821-
* reacquire CE_VALID bit automatically, which is not
822-
* really what we want.
830+
/*
831+
* If ignore_valid is not set, we should leave CE_VALID bit
832+
* alone. Otherwise, paths marked with --no-assume-unchanged
833+
* (i.e. things to be edited) will reacquire CE_VALID bit
834+
* automatically, which is not really what we want.
823835
*/
824-
if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
836+
if (!ignore_valid && assume_unchanged &&
837+
!(ce->ce_flags & htons(CE_VALID)))
825838
updated->ce_flags &= ~htons(CE_VALID);
826839

827840
return updated;
@@ -835,6 +848,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
835848
int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
836849
int quiet = (flags & REFRESH_QUIET) != 0;
837850
int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
851+
unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
838852

839853
for (i = 0; i < istate->cache_nr; i++) {
840854
struct cache_entry *ce, *new;
@@ -856,7 +870,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
856870
if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
857871
continue;
858872

859-
new = refresh_cache_ent(istate, ce, really, &cache_errno);
873+
new = refresh_cache_ent(istate, ce, options, &cache_errno);
860874
if (new == ce)
861875
continue;
862876
if (!new) {

t/t2200-add-update.sh

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
test_description='git add -u with path limiting
3+
test_description='git add -u
44
55
This test creates a working tree state with three files:
66
@@ -9,7 +9,10 @@ This test creates a working tree state with three files:
99
dir/other (untracked)
1010
1111
and issues a git add -u with path limiting on "dir" to add
12-
only the updates to dir/sub.'
12+
only the updates to dir/sub.
13+
14+
Also tested are "git add -u" without limiting, and "git add -u"
15+
without contents changes.'
1316

1417
. ./test-lib.sh
1518

@@ -85,4 +88,27 @@ test_expect_success 'replace a file with a symlink' '
8588
8689
'
8790

91+
test_expect_success 'add everything changed' '
92+
93+
git add -u &&
94+
test -z "$(git diff-files)"
95+
96+
'
97+
98+
test_expect_success 'touch and then add -u' '
99+
100+
touch check &&
101+
git add -u &&
102+
test -z "$(git diff-files)"
103+
104+
'
105+
106+
test_expect_success 'touch and then add explicitly' '
107+
108+
touch check &&
109+
git add check &&
110+
test -z "$(git diff-files)"
111+
112+
'
113+
88114
test_done

unpack-trees.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ static void verify_uptodate(struct cache_entry *ce,
404404
return;
405405

406406
if (!lstat(ce->name, &st)) {
407-
unsigned changed = ce_match_stat(ce, &st, 1);
407+
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
408408
if (!changed)
409409
return;
410410
/*
@@ -925,7 +925,7 @@ int oneway_merge(struct cache_entry **src,
925925
if (o->reset) {
926926
struct stat st;
927927
if (lstat(old->name, &st) ||
928-
ce_match_stat(old, &st, 1))
928+
ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID))
929929
old->ce_flags |= htons(CE_UPDATE);
930930
}
931931
return keep_entry(old, o);

0 commit comments

Comments
 (0)