Code

blame.c: move code to output metainfo into a separate function.
[git.git] / diff-lib.c
index 63da3b521d3bf580709ef6bf0f6e4aa83ff7d958..fc69fb92a50c3dff67da76fedf1bf1df561c6065 100644 (file)
@@ -34,21 +34,23 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
                        continue;
 
                if (ce_stage(ce)) {
-                       struct {
-                               struct combine_diff_path p;
-                               struct combine_diff_parent filler[5];
-                       } combine;
+                       struct combine_diff_path *dpath;
                        int num_compare_stages = 0;
+                       size_t path_len;
 
-                       combine.p.next = NULL;
-                       combine.p.len = ce_namelen(ce);
-                       combine.p.path = xmalloc(combine.p.len + 1);
-                       memcpy(combine.p.path, ce->name, combine.p.len);
-                       combine.p.path[combine.p.len] = 0;
-                       combine.p.mode = 0;
-                       memset(combine.p.sha1, 0, 20);
-                       memset(&combine.p.parent[0], 0,
-                              sizeof(combine.filler));
+                       path_len = ce_namelen(ce);
+
+                       dpath = xmalloc (combine_diff_path_size (5, path_len));
+                       dpath->path = (char *) &(dpath->parent[5]);
+
+                       dpath->next = NULL;
+                       dpath->len = path_len;
+                       memcpy(dpath->path, ce->name, path_len);
+                       dpath->path[path_len] = '\0';
+                       dpath->mode = 0;
+                       hashclr(dpath->sha1);
+                       memset(&(dpath->parent[0]), 0,
+                                       sizeof(struct combine_diff_parent)*5);
 
                        while (i < entries) {
                                struct cache_entry *nce = active_cache[i];
@@ -64,11 +66,10 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
                                if (2 <= stage) {
                                        int mode = ntohl(nce->ce_mode);
                                        num_compare_stages++;
-                                       memcpy(combine.p.parent[stage-2].sha1,
-                                              nce->sha1, 20);
-                                       combine.p.parent[stage-2].mode =
+                                       hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
+                                       dpath->parent[stage-2].mode =
                                                canon_mode(mode);
-                                       combine.p.parent[stage-2].status =
+                                       dpath->parent[stage-2].status =
                                                DIFF_STATUS_MODIFIED;
                                }
 
@@ -83,13 +84,14 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
                        i--;
 
                        if (revs->combine_merges && num_compare_stages == 2) {
-                               show_combined_diff(&combine.p, 2,
+                               show_combined_diff(dpath, 2,
                                                   revs->dense_combined_merges,
                                                   revs);
-                               free(combine.p.path);
+                               free(dpath);
                                continue;
                        }
-                       free(combine.p.path);
+                       free(dpath);
+                       dpath = NULL;
 
                        /*
                         * Show the diff for the 'ce' if we found the one
@@ -211,8 +213,33 @@ static int show_modified(struct rev_info *revs,
                return -1;
        }
 
+       if (revs->combine_merges && !cached &&
+           (hashcmp(sha1, old->sha1) || hashcmp(old->sha1, new->sha1))) {
+               struct combine_diff_path *p;
+               int pathlen = ce_namelen(new);
+
+               p = xmalloc(combine_diff_path_size(2, pathlen));
+               p->path = (char *) &p->parent[2];
+               p->next = NULL;
+               p->len = pathlen;
+               memcpy(p->path, new->name, pathlen);
+               p->path[pathlen] = 0;
+               p->mode = ntohl(mode);
+               hashclr(p->sha1);
+               memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent));
+               p->parent[0].status = DIFF_STATUS_MODIFIED;
+               p->parent[0].mode = ntohl(new->ce_mode);
+               hashcpy(p->parent[0].sha1, new->sha1);
+               p->parent[1].status = DIFF_STATUS_MODIFIED;
+               p->parent[1].mode = ntohl(old->ce_mode);
+               hashcpy(p->parent[1].sha1, old->sha1);
+               show_combined_diff(p, 2, revs->dense_combined_merges, revs);
+               free(p);
+               return 0;
+       }
+
        oldmode = old->ce_mode;
-       if (mode == oldmode && !memcmp(sha1, old->sha1, 20) &&
+       if (mode == oldmode && !hashcmp(sha1, old->sha1) &&
            !revs->diffopt.find_copies_harder)
                return 0;
 
@@ -308,12 +335,20 @@ static void mark_merge_entries(void)
        }
 }
 
-int run_diff_index(struct rev_info *revs, int cached, int match_missing)
+int run_diff_index(struct rev_info *revs, int cached)
 {
        int ret;
        struct object *ent;
        struct tree *tree;
        const char *tree_name;
+       int match_missing = 0;
+
+       /* 
+        * Backward compatibility wart - "diff-index -m" does
+        * not mean "do not ignore merges", but totally different.
+        */
+       if (!revs->ignore_merges)
+               match_missing = 1;
 
        if (read_cache() < 0) {
                perror("read_cache");
@@ -321,8 +356,8 @@ int run_diff_index(struct rev_info *revs, int cached, int match_missing)
        }
        mark_merge_entries();
 
-       ent = revs->pending_objects->item;
-       tree_name = revs->pending_objects->name;
+       ent = revs->pending.objects[0].item;
+       tree_name = revs->pending.objects[0].name;
        tree = parse_tree_indirect(ent->sha1);
        if (!tree)
                return error("bad tree object %s", tree_name);