Merge branch 'jc/combine-diff-callback'
authorJunio C Hamano <gitster@pobox.com>
Mon, 29 Aug 2011 04:15:33 +0000 (21:15 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 29 Aug 2011 04:15:33 +0000 (21:15 -0700)
* jc/combine-diff-callback:
  combine-diff: support format_callback

1  2 
combine-diff.c

diff --cc combine-diff.c
index b11eb7102c53d3418aa875ee899e61e01de87bca,de881865109f773a4afb1de0d7784bbd0b1c2068..178313bc23cc2b4bc434bd30934863056823854f
@@@ -1047,9 -967,75 +1047,75 @@@ void show_combined_diff(struct combine_
                                  DIFF_FORMAT_NAME_STATUS))
                show_raw_diff(p, num_parent, rev);
        else if (opt->output_format & DIFF_FORMAT_PATCH)
 -              show_patch_diff(p, num_parent, dense, rev);
 +              show_patch_diff(p, num_parent, dense, 1, rev);
  }
  
+ static void free_combined_pair(struct diff_filepair *pair)
+ {
+       free(pair->two);
+       free(pair);
+ }
+ /*
+  * A combine_diff_path expresses N parents on the LHS against 1 merge
+  * result. Synthesize a diff_filepair that has N entries on the "one"
+  * side and 1 entry on the "two" side.
+  *
+  * In the future, we might want to add more data to combine_diff_path
+  * so that we can fill fields we are ignoring (most notably, size) here,
+  * but currently nobody uses it, so this should suffice for now.
+  */
+ static struct diff_filepair *combined_pair(struct combine_diff_path *p,
+                                          int num_parent)
+ {
+       int i;
+       struct diff_filepair *pair;
+       struct diff_filespec *pool;
+       pair = xmalloc(sizeof(*pair));
+       pool = xcalloc(num_parent + 1, sizeof(struct diff_filespec));
+       pair->one = pool + 1;
+       pair->two = pool;
+       for (i = 0; i < num_parent; i++) {
+               pair->one[i].path = p->path;
+               pair->one[i].mode = p->parent[i].mode;
+               hashcpy(pair->one[i].sha1, p->parent[i].sha1);
+               pair->one[i].sha1_valid = !is_null_sha1(p->parent[i].sha1);
+               pair->one[i].has_more_entries = 1;
+       }
+       pair->one[num_parent - 1].has_more_entries = 0;
+       pair->two->path = p->path;
+       pair->two->mode = p->mode;
+       hashcpy(pair->two->sha1, p->sha1);
+       pair->two->sha1_valid = !is_null_sha1(p->sha1);
+       return pair;
+ }
+ static void handle_combined_callback(struct diff_options *opt,
+                                    struct combine_diff_path *paths,
+                                    int num_parent,
+                                    int num_paths)
+ {
+       struct combine_diff_path *p;
+       struct diff_queue_struct q;
+       int i;
+       q.queue = xcalloc(num_paths, sizeof(struct diff_filepair *));
+       q.alloc = num_paths;
+       q.nr = num_paths;
+       for (i = 0, p = paths; p; p = p->next) {
+               if (!p->len)
+                       continue;
+               q.queue[i++] = combined_pair(p, num_parent);
+       }
+       opt->format_callback(&q, opt, opt->format_callback_data);
+       for (i = 0; i < num_paths; i++)
+               free_combined_pair(q.queue[i]);
+       free(q.queue);
+ }
  void diff_tree_combined(const unsigned char *sha1,
                        const unsigned char parent[][20],
                        int num_parent,