summaryrefslogtreecommitdiff
path: root/diff-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff-lib.c')
-rw-r--r--diff-lib.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/diff-lib.c b/diff-lib.c
index 116b5a9d68..fc69fb92a5 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -48,7 +48,7 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
memcpy(dpath->path, ce->name, path_len);
dpath->path[path_len] = '\0';
dpath->mode = 0;
- memset(dpath->sha1, 0, 20);
+ hashclr(dpath->sha1);
memset(&(dpath->parent[0]), 0,
sizeof(struct combine_diff_parent)*5);
@@ -66,8 +66,7 @@ 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(dpath->parent[stage-2].sha1,
- nce->sha1, 20);
+ hashcpy(dpath->parent[stage-2].sha1, nce->sha1);
dpath->parent[stage-2].mode =
canon_mode(mode);
dpath->parent[stage-2].status =
@@ -214,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;