path: root/diff.c
diff options
authorLinus Torvalds <>2007-10-25 18:19:10 (GMT)
committerJunio C Hamano <>2007-10-27 06:18:05 (GMT)
commit9fb88419ba85e641006c80db53620423f37f1c93 (patch)
tree8faef69079486e3c57cbc0009073b8ae98295c0f /diff.c
parentcb1491b6bff20748532c9e50afc7f9d6896167a8 (diff)
Ref-count the filespecs used by diffcore
Rather than copy the filespecs when introducing new versions of them (for rename or copy detection), use a refcount and increment the count when reusing the diff_filespec. This avoids unnecessary allocations, but the real reason behind this is a future enhancement: we will want to track shared data across the copy/rename detection. In order to efficiently notice when a filespec is used by a rename, the rename machinery wants to keep track of a rename usage count which is shared across all different users of the filespec. Signed-off-by: Linus Torvalds <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'diff.c')
1 files changed, 11 insertions, 4 deletions
diff --git a/diff.c b/diff.c
index dfb8595..0b320f6 100644
--- a/diff.c
+++ b/diff.c
@@ -1440,9 +1440,18 @@ struct diff_filespec *alloc_filespec(const char *path)
memset(spec, 0, sizeof(*spec));
spec->path = (char *)(spec + 1);
memcpy(spec->path, path, namelen+1);
+ spec->count = 1;
return spec;
+void free_filespec(struct diff_filespec *spec)
+ if (!--spec->count) {
+ diff_free_filespec_data(spec);
+ free(spec);
+ }
void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
unsigned short mode)
@@ -2435,10 +2444,8 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *queue,
void diff_free_filepair(struct diff_filepair *p)
- diff_free_filespec_data(p->one);
- diff_free_filespec_data(p->two);
- free(p->one);
- free(p->two);
+ free_filespec(p->one);
+ free_filespec(p->two);