<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2099,7 +2099,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
 			return -1;
 		return 0;
 	}
-	return ce_match_stat(ce, st, 1);
+	return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID);
 }
 
 static int check_patch(struct patch *patch, struct patch *prev_patch)</diff>
      <filename>builtin-apply.c</filename>
    </modified>
    <modified>
      <diff>@@ -174,8 +174,8 @@ extern struct index_state the_index;
 #define remove_file_from_cache(path) remove_file_from_index(&amp;the_index, (path))
 #define add_file_to_cache(path, verbose) add_file_to_index(&amp;the_index, (path), (verbose))
 #define refresh_cache(flags) refresh_index(&amp;the_index, (flags), NULL, NULL)
-#define ce_match_stat(ce, st, really) ie_match_stat(&amp;the_index, (ce), (st), (really))
-#define ce_modified(ce, st, really) ie_modified(&amp;the_index, (ce), (st), (really))
+#define ce_match_stat(ce, st, options) ie_match_stat(&amp;the_index, (ce), (st), (options))
+#define ce_modified(ce, st, options) ie_modified(&amp;the_index, (ce), (st), (options))
 #endif
 
 enum object_type {
@@ -266,8 +266,14 @@ extern int remove_file_from_index(struct index_state *, const char *path);
 extern int add_file_to_index(struct index_state *, const char *path, int verbose);
 extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
 extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
-extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int);
-extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
+
+/* do stat comparison even if CE_VALID is true */
+#define CE_MATCH_IGNORE_VALID		01
+/* do not check the contents but report dirty on racily-clean entries */
+#define CE_MATCH_RACY_IS_DIRTY	02
+extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+
 extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
 extern int read_fd(int fd, char **return_buf, unsigned long *return_size);</diff>
      <filename>cache.h</filename>
    </modified>
    <modified>
      <diff>@@ -18,7 +18,7 @@ int main(int ac, char **av)
 
 		if (ce_match_stat(ce, &amp;st, 0))
 			dirty++;
-		else if (ce_match_stat(ce, &amp;st, 2))
+		else if (ce_match_stat(ce, &amp;st, CE_MATCH_RACY_IS_DIRTY))
 			racy++;
 		else
 			clean++;</diff>
      <filename>check-racy.c</filename>
    </modified>
    <modified>
      <diff>@@ -173,9 +173,10 @@ static int is_in_index(const char *path)
 }
 
 static int handle_diff_files_args(struct rev_info *revs,
-		int argc, const char **argv, int *silent)
+				  int argc, const char **argv,
+				  unsigned int *options)
 {
-	*silent = 0;
+	*options = 0;
 
 	/* revs-&gt;max_count == -2 means --no-index */
 	while (1 &lt; argc &amp;&amp; argv[1][0] == '-') {
@@ -192,7 +193,7 @@ static int handle_diff_files_args(struct rev_info *revs,
 			revs-&gt;diffopt.no_index = 1;
 		}
 		else if (!strcmp(argv[1], &quot;-q&quot;))
-			*silent = 1;
+			*options |= DIFF_SILENT_ON_REMOVED;
 		else
 			return error(&quot;invalid option: %s&quot;, argv[1]);
 		argv++; argc--;
@@ -305,9 +306,9 @@ int setup_diff_no_index(struct rev_info *revs,
 
 int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
 {
-	int silent_on_removed;
+	unsigned int options;
 
-	if (handle_diff_files_args(revs, argc, argv, &amp;silent_on_removed))
+	if (handle_diff_files_args(revs, argc, argv, &amp;options))
 		return -1;
 
 	if (revs-&gt;diffopt.no_index) {
@@ -329,13 +330,16 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
 		perror(&quot;read_cache&quot;);
 		return -1;
 	}
-	return run_diff_files(revs, silent_on_removed);
+	return run_diff_files(revs, options);
 }
 
-int run_diff_files(struct rev_info *revs, int silent_on_removed)
+int run_diff_files(struct rev_info *revs, unsigned int option)
 {
 	int entries, i;
 	int diff_unmerged_stage = revs-&gt;max_count;
+	int silent_on_removed = option &amp; DIFF_SILENT_ON_REMOVED;
+	unsigned ce_option = ((option &amp; DIFF_RACY_IS_MODIFIED)
+			      ? CE_MATCH_RACY_IS_DIRTY : 0);
 
 	if (diff_unmerged_stage &lt; 0)
 		diff_unmerged_stage = 2;
@@ -441,7 +445,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
 				       ce-&gt;sha1, ce-&gt;name, NULL);
 			continue;
 		}
-		changed = ce_match_stat(ce, &amp;st, 0);
+		changed = ce_match_stat(ce, &amp;st, ce_option);
 		if (!changed &amp;&amp; !revs-&gt;diffopt.find_copies_harder)
 			continue;
 		oldmode = ntohl(ce-&gt;ce_mode);</diff>
      <filename>diff-lib.c</filename>
    </modified>
    <modified>
      <diff>@@ -224,7 +224,11 @@ extern void diff_flush(struct diff_options*);
 
 extern const char *diff_unique_abbrev(const unsigned char *, int);
 
-extern int run_diff_files(struct rev_info *revs, int silent_on_removed);
+/* do not report anything on removed paths */
+#define DIFF_SILENT_ON_REMOVED 01
+/* report racily-clean paths as modified */
+#define DIFF_RACY_IS_MODIFIED 02
+extern int run_diff_files(struct rev_info *revs, unsigned int option);
 extern int setup_diff_no_index(struct rev_info *revs,
 		int argc, const char ** argv, int nongit, const char *prefix);
 extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);</diff>
      <filename>diff.h</filename>
    </modified>
    <modified>
      <diff>@@ -200,7 +200,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
 	strcpy(path + len, ce-&gt;name);
 
 	if (!lstat(path, &amp;st)) {
-		unsigned changed = ce_match_stat(ce, &amp;st, 1);
+		unsigned changed = ce_match_stat(ce, &amp;st, CE_MATCH_IGNORE_VALID);
 		if (!changed)
 			return 0;
 		if (!state-&gt;force) {</diff>
      <filename>entry.c</filename>
    </modified>
    <modified>
      <diff>@@ -194,11 +194,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
 }
 
 int ie_match_stat(struct index_state *istate,
-		  struct cache_entry *ce, struct stat *st, int options)
+		  struct cache_entry *ce, struct stat *st,
+		  unsigned int options)
 {
 	unsigned int changed;
-	int ignore_valid = options &amp; 01;
-	int assume_racy_is_modified = options &amp; 02;
+	int ignore_valid = options &amp; CE_MATCH_IGNORE_VALID;
+	int assume_racy_is_modified = options &amp; CE_MATCH_RACY_IS_DIRTY;
 
 	/*
 	 * If it's marked as always valid in the index, it's
@@ -238,10 +239,11 @@ int ie_match_stat(struct index_state *istate,
 }
 
 int ie_modified(struct index_state *istate,
-		struct cache_entry *ce, struct stat *st, int really)
+		struct cache_entry *ce, struct stat *st, unsigned int options)
 {
 	int changed, changed_fs;
-	changed = ie_match_stat(istate, ce, st, really);
+
+	changed = ie_match_stat(istate, ce, st, options);
 	if (!changed)
 		return 0;
 	/*
@@ -386,6 +388,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 	int size, namelen, pos;
 	struct stat st;
 	struct cache_entry *ce;
+	unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
 
 	if (lstat(path, &amp;st))
 		die(&quot;%s: unable to stat (%s)&quot;, path, strerror(errno));
@@ -420,7 +423,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
 	pos = index_name_pos(istate, ce-&gt;name, namelen);
 	if (0 &lt;= pos &amp;&amp;
 	    !ce_stage(istate-&gt;cache[pos]) &amp;&amp;
-	    !ie_modified(istate, istate-&gt;cache[pos], &amp;st, 1)) {
+	    !ie_match_stat(istate, istate-&gt;cache[pos], &amp;st, ce_option)) {
 		/* Nothing changed, really */
 		free(ce);
 		return 0;
@@ -782,11 +785,13 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
  * to link up the stat cache details with the proper files.
  */
 static struct cache_entry *refresh_cache_ent(struct index_state *istate,
-					     struct cache_entry *ce, int really, int *err)
+					     struct cache_entry *ce,
+					     unsigned int options, int *err)
 {
 	struct stat st;
 	struct cache_entry *updated;
 	int changed, size;
+	int ignore_valid = options &amp; CE_MATCH_IGNORE_VALID;
 
 	if (lstat(ce-&gt;name, &amp;st) &lt; 0) {
 		if (err)
@@ -794,16 +799,23 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
 		return NULL;
 	}
 
-	changed = ie_match_stat(istate, ce, &amp;st, really);
+	changed = ie_match_stat(istate, ce, &amp;st, options);
 	if (!changed) {
-		if (really &amp;&amp; assume_unchanged &amp;&amp;
+		/*
+		 * The path is unchanged.  If we were told to ignore
+		 * valid bit, then we did the actual stat check and
+		 * found that the entry is unmodified.  If the entry
+		 * is not marked VALID, this is the place to mark it
+		 * valid again, under &quot;assume unchanged&quot; mode.
+		 */
+		if (ignore_valid &amp;&amp; assume_unchanged &amp;&amp;
 		    !(ce-&gt;ce_flags &amp; htons(CE_VALID)))
 			; /* mark this one VALID again */
 		else
 			return ce;
 	}
 
-	if (ie_modified(istate, ce, &amp;st, really)) {
+	if (ie_modified(istate, ce, &amp;st, options)) {
 		if (err)
 			*err = EINVAL;
 		return NULL;
@@ -814,13 +826,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
 	memcpy(updated, ce, size);
 	fill_stat_cache_info(updated, &amp;st);
 
-	/* In this case, if really is not set, we should leave
-	 * CE_VALID bit alone.  Otherwise, paths marked with
-	 * --no-assume-unchanged (i.e. things to be edited) will
-	 * reacquire CE_VALID bit automatically, which is not
-	 * really what we want.
+	/*
+	 * If ignore_valid is not set, we should leave CE_VALID bit
+	 * alone.  Otherwise, paths marked with --no-assume-unchanged
+	 * (i.e. things to be edited) will reacquire CE_VALID bit
+	 * automatically, which is not really what we want.
 	 */
-	if (!really &amp;&amp; assume_unchanged &amp;&amp; !(ce-&gt;ce_flags &amp; htons(CE_VALID)))
+	if (!ignore_valid &amp;&amp; assume_unchanged &amp;&amp;
+	    !(ce-&gt;ce_flags &amp; htons(CE_VALID)))
 		updated-&gt;ce_flags &amp;= ~htons(CE_VALID);
 
 	return updated;
@@ -834,6 +847,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
 	int allow_unmerged = (flags &amp; REFRESH_UNMERGED) != 0;
 	int quiet = (flags &amp; REFRESH_QUIET) != 0;
 	int not_new = (flags &amp; REFRESH_IGNORE_MISSING) != 0;
+	unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
 
 	for (i = 0; i &lt; istate-&gt;cache_nr; i++) {
 		struct cache_entry *ce, *new;
@@ -855,7 +869,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
 		if (pathspec &amp;&amp; !match_pathspec(pathspec, ce-&gt;name, strlen(ce-&gt;name), 0, seen))
 			continue;
 
-		new = refresh_cache_ent(istate, ce, really, &amp;cache_errno);
+		new = refresh_cache_ent(istate, ce, options, &amp;cache_errno);
 		if (new == ce)
 			continue;
 		if (!new) {</diff>
      <filename>read-cache.c</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 #!/bin/sh
 
-test_description='git add -u with path limiting
+test_description='git add -u
 
 This test creates a working tree state with three files:
 
@@ -9,7 +9,10 @@ This test creates a working tree state with three files:
   dir/other (untracked)
 
 and issues a git add -u with path limiting on &quot;dir&quot; to add
-only the updates to dir/sub.'
+only the updates to dir/sub.
+
+Also tested are &quot;git add -u&quot; without limiting, and &quot;git add -u&quot;
+without contents changes.'
 
 . ./test-lib.sh
 
@@ -85,4 +88,27 @@ test_expect_success 'replace a file with a symlink' '
 
 '
 
+test_expect_success 'add everything changed' '
+
+	git add -u &amp;&amp;
+	test -z &quot;$(git diff-files)&quot;
+
+'
+
+test_expect_success 'touch and then add -u' '
+
+	touch check &amp;&amp;
+	git add -u &amp;&amp;
+	test -z &quot;$(git diff-files)&quot;
+
+'
+
+test_expect_success 'touch and then add explicitly' '
+
+	touch check &amp;&amp;
+	git add check &amp;&amp;
+	test -z &quot;$(git diff-files)&quot;
+
+'
+
 test_done</diff>
      <filename>t/t2200-add-update.sh</filename>
    </modified>
    <modified>
      <diff>@@ -406,7 +406,7 @@ static void verify_uptodate(struct cache_entry *ce,
 		return;
 
 	if (!lstat(ce-&gt;name, &amp;st)) {
-		unsigned changed = ce_match_stat(ce, &amp;st, 1);
+		unsigned changed = ce_match_stat(ce, &amp;st, CE_MATCH_IGNORE_VALID);
 		if (!changed)
 			return;
 		/*
@@ -927,7 +927,7 @@ int oneway_merge(struct cache_entry **src,
 		if (o-&gt;reset) {
 			struct stat st;
 			if (lstat(old-&gt;name, &amp;st) ||
-			    ce_match_stat(old, &amp;st, 1))
+			    ce_match_stat(old, &amp;st, CE_MATCH_IGNORE_VALID))
 				old-&gt;ce_flags |= htons(CE_UPDATE);
 		}
 		return keep_entry(old, o);</diff>
      <filename>unpack-trees.c</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>d1c7cd13dc7839b3c0b4d56a84f9effc9976144e</id>
    </parent>
    <parent>
      <id>25487bde2ab756a423489fc942b37c1550555b93</id>
    </parent>
  </parents>
  <author>
    <name>Junio C Hamano</name>
    <email>gitster@pobox.com</email>
  </author>
  <url>http://github.com/schacon/git-source/commit/bc2b8eafaf074492e0489974b4086b3a0f354e7e</url>
  <id>bc2b8eafaf074492e0489974b4086b3a0f354e7e</id>
  <committed-date>2007-11-24T18:03:04-08:00</committed-date>
  <authored-date>2007-11-24T18:03:04-08:00</authored-date>
  <message>Merge branch 'jc/maint-add-sync-stat' into maint

* jc/maint-add-sync-stat:
  t2200: test more cases of &quot;add -u&quot;
  git-add: make the entry stat-clean after re-adding the same contents
  ce_match_stat, run_diff_files: use symbolic constants for readability</message>
  <tree>a5662a57c224c50309019386707eb95206248191</tree>
  <committer>
    <name>Junio C Hamano</name>
    <email>gitster@pobox.com</email>
  </committer>
</commit>
