[PATCH 1/2] Test suite fixup.
[gitweb.git] / diff-cache.c
index 03dd69df3eb3bc9a516f3bec06a3580a78abf632..84527190fef259dc8e8865693fe5591be86f79c4 100644 (file)
@@ -3,6 +3,7 @@
 
 static int cached_only = 0;
 static int generate_patch = 0;
+static int match_nonexisting = 0;
 static int line_termination = '\n';
 
 /* A file entry went away or appeared */
@@ -24,8 +25,14 @@ static int get_stat_data(struct cache_entry *ce, unsigned char **sha1p, unsigned
                static unsigned char no_sha1[20];
                int changed;
                struct stat st;
-               if (stat(ce->name, &st) < 0)
+               if (lstat(ce->name, &st) < 0) {
+                       if (errno == ENOENT && match_nonexisting) {
+                               *sha1p = sha1;
+                               *modep = mode;
+                               return 0;
+                       }
                        return -1;
+               }
                changed = cache_match_stat(ce, &st);
                if (changed) {
                        mode = create_ce_mode(st.st_mode);
@@ -50,14 +57,17 @@ static void show_new_file(struct cache_entry *new)
        show_file("+", new, sha1, mode);
 }
 
-static int show_modified(struct cache_entry *old, struct cache_entry *new)
+static int show_modified(struct cache_entry *old,
+                        struct cache_entry *new,
+                        int report_missing)
 {
        unsigned int mode, oldmode;
        unsigned char *sha1;
        unsigned char old_sha1_hex[60];
 
        if (get_stat_data(new, &sha1, &mode) < 0) {
-               show_file("-", old, old->sha1, old->ce_mode);
+               if (report_missing)
+                       show_file("-", old, old->sha1, old->ce_mode);
                return -1;
        }
 
@@ -94,7 +104,7 @@ static int diff_cache(struct cache_entry **ac, int entries)
                                break;
                        }
                        /* Show difference between old and new */
-                       show_modified(ac[1], ce);
+                       show_modified(ac[1], ce, 1);
                        break;
                case 1:
                        /* No stage 3 (merge) entry? That means it's been deleted */
@@ -102,7 +112,19 @@ static int diff_cache(struct cache_entry **ac, int entries)
                                show_file("-", ce, ce->sha1, ce->ce_mode);
                                break;
                        }
-                       /* Otherwise we fall through to the "unmerged" case */
+                       /* We come here with ce pointing at stage 1
+                        * (original tree) and ac[1] pointing at stage
+                        * 3 (unmerged).  show-modified with
+                        * report-mising set to false does not say the
+                        * file is deleted but reports true if work
+                        * tree does not have it, in which case we
+                        * fall through to report the unmerged state.
+                        * Otherwise, we show the differences between
+                        * the original tree and the work tree.
+                        */
+                       if (!cached_only && !show_modified(ce, ac[1], 0))
+                               break;
+                       /* fallthru */
                case 3:
                        if (generate_patch)
                                diff_unmerge(ce->name);
@@ -143,7 +165,7 @@ static void mark_merge_entries(void)
 }
 
 static char *diff_cache_usage =
-"diff-cache [-r] [-z] [-p] [--cached] <tree sha1>";
+"git-diff-cache [-p] [-r] [-z] [-m] [--cached] <tree sha1>";
 
 int main(int argc, char **argv)
 {
@@ -168,6 +190,10 @@ int main(int argc, char **argv)
                        line_termination = '\0';
                        continue;
                }
+               if (!strcmp(arg, "-m")) {
+                       match_nonexisting = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--cached")) {
                        cached_only = 1;
                        continue;