X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tree-diff.c;h=bbb126fc46cfb28a0bc92cc0842c0dc72017751d;hb=0513f241cc2d757371dc7ba6b065366de044862e;hp=aa0a100295c5c48483c6bfbbfc0105b70680becc;hpb=8f67f8aefb1b751073f8b36fae8be8f72eb93f4a;p=git.git diff --git a/tree-diff.c b/tree-diff.c index aa0a10029..bbb126fc4 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -15,6 +15,15 @@ static char *malloc_base(const char *base, int baselen, const char *path, int pa return newbase; } +static char *malloc_fullname(const char *base, int baselen, const char *path, int pathlen) +{ + char *fullname = xmalloc(baselen + pathlen + 1); + memcpy(fullname, base, baselen); + memcpy(fullname + baselen, path, pathlen); + fullname[baselen + pathlen] = 0; + return fullname; +} + static void show_entry(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen); @@ -24,6 +33,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const const char *path1, *path2; const unsigned char *sha1, *sha2; int cmp, pathlen1, pathlen2; + char *fullname; sha1 = tree_entry_extract(t1, &path1, &mode1); sha2 = tree_entry_extract(t2, &path2, &mode2); @@ -55,15 +65,20 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) { int retval; char *newbase = malloc_base(base, baselen, path1, pathlen1); - if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) + if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE)) { + newbase[baselen + pathlen1] = 0; opt->change(opt, mode1, mode2, - sha1, sha2, base, path1); + sha1, sha2, newbase); + newbase[baselen + pathlen1] = '/'; + } retval = diff_tree_sha1(sha1, sha2, newbase, opt); free(newbase); return retval; } - opt->change(opt, mode1, mode2, sha1, sha2, base, path1); + fullname = malloc_fullname(base, baselen, path1, pathlen1); + opt->change(opt, mode1, mode2, sha1, sha2, fullname); + free(fullname); return 0; } @@ -205,10 +220,10 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree unsigned mode; const char *path; const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode); + int pathlen = tree_entry_len(path, sha1); if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) { enum object_type type; - int pathlen = tree_entry_len(path, sha1); char *newbase = malloc_base(base, baselen, path, pathlen); struct tree_desc inner; void *tree; @@ -224,7 +239,9 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree free(tree); free(newbase); } else { - opt->add_remove(opt, prefix[0], mode, sha1, base, path); + char *fullname = malloc_fullname(base, baselen, path, pathlen); + opt->add_remove(opt, prefix[0], mode, sha1, fullname); + free(fullname); } } @@ -326,6 +343,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co die("unable to set up diff options to follow renames"); diff_tree(t1, t2, base, &diff_opts); diffcore_std(&diff_opts); + diff_tree_release_paths(&diff_opts); /* Go through the new set of filepairing, and see if we find a more interesting one */ for (i = 0; i < q->nr; i++) { @@ -342,6 +360,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co choice = p; /* Update the path we use from now on.. */ + diff_tree_release_paths(opt); opt->paths[0] = xstrdup(p->one->path); diff_tree_setup_paths(opt->paths, opt); break;