Re: git annotate runs out of memory
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Dec 11, 2007, 21:54 UTC
- Message-ID
- <7vprxcdhis.fsf@gitster.siamese.dyndns.org>
- In-Reply-To
- <alpine.LFD.0.9999.0712111300440.25032@woody.linux-foundation.org>
Linus Torvalds <torvalds@linux-foundation.org> writes:
Show 23 quoted lines
> builtin-blame.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/builtin-blame.c b/builtin-blame.c
> index c158d31..18f9924 100644
> --- a/builtin-blame.c
> +++ b/builtin-blame.c
> @@ -87,6 +87,14 @@ struct origin {
> char path[FLEX_ARRAY];
> };
>
> /*
> * Given an origin, prepare mmfile_t structure to be used by the
> * diff machinery
> @@ -558,6 +566,8 @@ static struct patch *get_patch(struct origin *parent, struct origin *origin)
> if (!file_p.ptr || !file_o.ptr)
> return NULL;
> patch = compare_buffer(&file_p, &file_o, 0);
> + drop_origin_blob(parent);
> + drop_origin_blob(origin);
> num_get_patch++;
> return patch;
> }While this should be safe (because the user of blob lazily re-fetches), it feels a bit too aggressive, especially when -C or other "retry and try harder to assign blame elsewhere" option is used.
Instead, how about discarding after we are done with each origin, like this?
--- builtin-blame.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c index c158d31..eda79d0 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -130,6 +130,14 @@ static void origin_decref(struct origin *o) } } +static void drop_origin_blob(struct origin *o) +{ + if (o->file.ptr) { + free(o->file.ptr); + o->file.ptr = NULL; + } +} + /* * Each group of lines is described by a blame_entry; it can be split * as we pass blame to the parents. They form a linked list in the @@ -1274,8 +1282,13 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt) } finish: - for (i = 0; i < MAXPARENT; i++) - origin_decref(parent_origin[i]); + for (i = 0; i < MAXPARENT; i++) { + if (parent_origin[i]) { + drop_origin_blob(parent_origin[i]); + origin_decref(parent_origin[i]); + } + } + drop_origin_blob(origin); } /*