Merge branch 'se/diff' into next
authorJunio C Hamano <junkio@cox.net>
Mon, 15 May 2006 00:12:37 +0000 (17:12 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 15 May 2006 00:12:37 +0000 (17:12 -0700)
* se/diff:
Convert some "apply --summary" users to "diff --summary".
Add "--summary" option to git diff.

1  2 
diff.c
diff.h
diff --combined diff.c
index be925a3a39d4cdb13c1e728e86438dde9fd5165e,00b1044d3adf7d9e0def6c12888a6abff8a3cd0d..40d9f6e0709b77f613a67da3a458c3c2deb4b642
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -558,7 -558,7 +558,7 @@@ static void builtin_diff(const char *na
  
                ecbdata.label_path = lbl;
                xpp.flags = XDF_NEED_MINIMAL;
 -              xecfg.ctxlen = 3;
 +              xecfg.ctxlen = o->context;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
                if (!diffopts)
                        ;
@@@ -1182,7 -1182,6 +1182,7 @@@ void diff_setup(struct diff_options *op
        options->line_termination = '\n';
        options->break_opt = -1;
        options->rename_limit = -1;
 +      options->context = 3;
  
        options->change = diff_change;
        options->add_remove = diff_addremove;
@@@ -1223,66 -1222,19 +1223,68 @@@ int diff_setup_done(struct diff_option
        return 0;
  }
  
 +int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val)
 +{
 +      char c, *eq;
 +      int len;
 +
 +      if (*arg != '-')
 +              return 0;
 +      c = *++arg;
 +      if (!c)
 +              return 0;
 +      if (c == arg_short) {
 +              c = *++arg;
 +              if (!c)
 +                      return 1;
 +              if (val && isdigit(c)) {
 +                      char *end;
 +                      int n = strtoul(arg, &end, 10);
 +                      if (*end)
 +                              return 0;
 +                      *val = n;
 +                      return 1;
 +              }
 +              return 0;
 +      }
 +      if (c != '-')
 +              return 0;
 +      arg++;
 +      eq = strchr(arg, '=');
 +      if (eq)
 +              len = eq - arg;
 +      else
 +              len = strlen(arg);
 +      if (!len || strncmp(arg, arg_long, len))
 +              return 0;
 +      if (eq) {
 +              int n;
 +              char *end;
 +              if (!isdigit(*++eq))
 +                      return 0;
 +              n = strtoul(eq, &end, 10);
 +              if (*end)
 +                      return 0;
 +              *val = n;
 +      }
 +      return 1;
 +}
 +
  int diff_opt_parse(struct diff_options *options, const char **av, int ac)
  {
        const char *arg = av[0];
        if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
                options->output_format = DIFF_FORMAT_PATCH;
 +      else if (opt_arg(arg, 'U', "unified", &options->context))
 +              options->output_format = DIFF_FORMAT_PATCH;
        else if (!strcmp(arg, "--patch-with-raw")) {
                options->output_format = DIFF_FORMAT_PATCH;
                options->with_raw = 1;
        }
        else if (!strcmp(arg, "--stat"))
                options->output_format = DIFF_FORMAT_DIFFSTAT;
+       else if (!strcmp(arg, "--summary"))
+               options->summary = 1;
        else if (!strcmp(arg, "--patch-with-stat")) {
                options->output_format = DIFF_FORMAT_PATCH;
                options->with_stat = 1;
@@@ -1753,6 -1705,85 +1755,85 @@@ static void flush_one_pair(struct diff_
        }
  }
  
+ static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
+ {
+       if (fs->mode)
+               printf(" %s mode %06o %s\n", newdelete, fs->mode, fs->path);
+       else
+               printf(" %s %s\n", newdelete, fs->path);
+ }
+ static void show_mode_change(struct diff_filepair *p, int show_name)
+ {
+       if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {
+               if (show_name)
+                       printf(" mode change %06o => %06o %s\n",
+                              p->one->mode, p->two->mode, p->two->path);
+               else
+                       printf(" mode change %06o => %06o\n",
+                              p->one->mode, p->two->mode);
+       }
+ }
+ static void show_rename_copy(const char *renamecopy, struct diff_filepair *p)
+ {
+       const char *old, *new;
+       /* Find common prefix */
+       old = p->one->path;
+       new = p->two->path;
+       while (1) {
+               const char *slash_old, *slash_new;
+               slash_old = strchr(old, '/');
+               slash_new = strchr(new, '/');
+               if (!slash_old ||
+                   !slash_new ||
+                   slash_old - old != slash_new - new ||
+                   memcmp(old, new, slash_new - new))
+                       break;
+               old = slash_old + 1;
+               new = slash_new + 1;
+       }
+       /* p->one->path thru old is the common prefix, and old and new
+        * through the end of names are renames
+        */
+       if (old != p->one->path)
+               printf(" %s %.*s{%s => %s} (%d%%)\n", renamecopy,
+                      (int)(old - p->one->path), p->one->path,
+                      old, new, (int)(0.5 + p->score * 100.0/MAX_SCORE));
+       else
+               printf(" %s %s => %s (%d%%)\n", renamecopy,
+                      p->one->path, p->two->path,
+                      (int)(0.5 + p->score * 100.0/MAX_SCORE));
+       show_mode_change(p, 0);
+ }
+ static void diff_summary(struct diff_filepair *p)
+ {
+       switch(p->status) {
+       case DIFF_STATUS_DELETED:
+               show_file_mode_name("delete", p->one);
+               break;
+       case DIFF_STATUS_ADDED:
+               show_file_mode_name("create", p->two);
+               break;
+       case DIFF_STATUS_COPIED:
+               show_rename_copy("copy", p);
+               break;
+       case DIFF_STATUS_RENAMED:
+               show_rename_copy("rename", p);
+               break;
+       default:
+               if (p->score) {
+                       printf(" rewrite %s (%d%%)\n", p->two->path,
+                               (int)(0.5 + p->score * 100.0/MAX_SCORE));
+                       show_mode_change(p, 0);
+               } else  show_mode_change(p, 1);
+               break;
+       }
+ }
  void diff_flush(struct diff_options *options)
  {
        struct diff_queue_struct *q = &diff_queued_diff;
        for (i = 0; i < q->nr; i++) {
                struct diff_filepair *p = q->queue[i];
                flush_one_pair(p, diff_output_format, options, diffstat);
-               diff_free_filepair(p);
        }
  
        if (diffstat) {
                free(diffstat);
        }
  
+       for (i = 0; i < q->nr; i++) {
+               if (options->summary)
+                       diff_summary(q->queue[i]);
+               diff_free_filepair(q->queue[i]);
+       }
        free(q->queue);
        q->queue = NULL;
        q->nr = q->alloc = 0;
diff --combined diff.h
index bef586d8502f6e78b95cce15456704572ffe8c00,70077c6ed938848ba260672f8271a99ecfe9b0a3..3027974c1ec74217a58345b4ab48e673ee3db710
--- 1/diff.h
--- 2/diff.h
+++ b/diff.h
@@@ -31,8 -31,8 +31,9 @@@ struct diff_options 
                 binary:1,
                 full_index:1,
                 silent_on_remove:1,
-                find_copies_harder:1;
+                find_copies_harder:1,
+                summary:1;
 +      int context;
        int break_opt;
        int detect_rename;
        int line_termination;