aboutsummaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-05-03 13:05:48 -0700
committerJunio C Hamano <junkio@cox.net>2007-05-07 15:54:32 -0700
commitfc3abdf5cb16914fb22747d7c3fb44258712a36d (patch)
treeae601e3fbee59e68acf307689fbfdf6af4ea0d19 /diff.c
parent3082acfa7c626a34aa419a163585051c2df2bf09 (diff)
downloadgit-fc3abdf5cb16914fb22747d7c3fb44258712a36d.tar.gz
git-fc3abdf5cb16914fb22747d7c3fb44258712a36d.tar.xz
diff: release blobs after generating textual diff.
This reduces the memory pressure when dealing with many paths. An unscientific test of running "diff-tree --stat --summary -M" between v2.6.19 and v2.6.20-rc1 in the linux kernel repository indicates that the number of minor faults are reduced by 2/3. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/diff.c b/diff.c
index 7bbe7590b..2979bc57e 100644
--- a/diff.c
+++ b/diff.c
@@ -1236,6 +1236,8 @@ static void builtin_diff(const char *name_a,
}
free_ab_and_return:
+ diff_free_filespec_data(one);
+ diff_free_filespec_data(two);
free(a_one);
free(b_two);
return;
@@ -1262,7 +1264,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
diff_populate_filespec(two, 0);
data->deleted = count_lines(one->data, one->size);
data->added = count_lines(two->data, two->size);
- return;
+ goto free_and_return;
}
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -1284,6 +1286,10 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
ecb.priv = diffstat;
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
}
+
+ free_and_return:
+ diff_free_filespec_data(one);
+ diff_free_filespec_data(two);
}
static void builtin_checkdiff(const char *name_a, const char *name_b,
@@ -1306,7 +1312,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
die("unable to read files to diff");
if (file_is_binary(two))
- return;
+ goto free_and_return;
else {
/* Crazy xdl interfaces.. */
xpparam_t xpp;
@@ -1320,6 +1326,9 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
ecb.priv = &data;
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
}
+ free_and_return:
+ diff_free_filespec_data(one);
+ diff_free_filespec_data(two);
}
struct diff_filespec *alloc_filespec(const char *path)
@@ -1507,7 +1516,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only)
size_only = 0;
if (s->data)
- return err;
+ return 0;
if (S_ISDIRLNK(s->mode))
return diff_populate_gitlink(s, size_only);
@@ -1597,8 +1606,11 @@ void diff_free_filespec_data(struct diff_filespec *s)
free(s->data);
else if (s->should_munmap)
munmap(s->data, s->size);
- s->should_free = s->should_munmap = 0;
- s->data = NULL;
+
+ if (s->should_free || s->should_munmap) {
+ s->should_free = s->should_munmap = 0;
+ s->data = NULL;
+ }
free(s->cnt_data);
s->cnt_data = NULL;
}