stagit

git site generator
Contents

optimization: only diff the tree when it is needed for the diffstat...

... also clear all fields in the structure on failure.

This is not as big an optimization as stagit-gopher, because the diffstat is
displayed in the log, but the difference is still measurable.

Hiltjo Posthuma hiltjo@codemadness.org

commit: 7013a46 parent: 29d0a52
1 files changed, 27 insertions(+), 17 deletions(-)
Mstagit.c+27-17
M · stagit.c +27, -17
 1@@ -87,7 +87,7 @@ deltainfo_free(struct deltainfo *di)
 2 if (!di)
 3 return;
 4
git_patch_free(di->patch);
 5- di->patch = NULL;
 6+ memset(di, 0,
sizeof(*di));
 7 free(di);
 8 }
 9
10@@ -95,6 +95,7 @@ int
11 commitinfo_getstats(struct commitinfo *ci)
12 {
13 struct deltainfo
*di;
14+ git_diff_options opts;
15 const git_diff_delta *delta;
16 const
git_diff_hunk *hunk;
17 const
git_diff_line *line;
18@@ -102,6 +103,20 @@ commitinfo_getstats(struct commitinfo *ci)
19 size_t ndeltas, nhunks, nhunklines;
20 size_t i, j, k;
21
22+ if (git_tree_lookup(&(ci->commit_tree), repo,
git_commit_tree_id(ci->commit)))
23+ goto err;
24+ if
(!git_commit_parent(&(ci->parent), ci->commit, 0)) {
25+ if
(git_tree_lookup(&(ci->parent_tree), repo, git_commit_tree_id(ci->parent))) {
26+ ci->parent =
NULL;
27+
ci->parent_tree = NULL;
28+ }
29+ }
30+
31+
git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION);
32+ opts.flags |=
GIT_DIFF_DISABLE_PATHSPEC_MATCH;
33+ if
(git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))
34+ goto err;
35+
36 ndeltas = git_diff_num_deltas(ci->diff);
37 if (ndeltas
&& !(ci->deltas = calloc(ndeltas, sizeof(struct deltainfo *))))
38 err(1,
"calloc");
39@@ -143,6 +158,15 @@ commitinfo_getstats(struct commitinfo *ci)
40 return 0;
41
42 err:
43+ git_diff_free(ci->diff);
44+ ci->diff =
NULL;
45+
git_tree_free(ci->commit_tree);
46+
ci->commit_tree = NULL;
47+
git_tree_free(ci->parent_tree);
48+
ci->parent_tree = NULL;
49+
git_commit_free(ci->parent);
50+ ci->parent =
NULL;
51+
52 if (ci->deltas)
53 for (i = 0; i
< ci->ndeltas; i++)
54
deltainfo_free(ci->deltas[i]);
55@@ -166,13 +190,14 @@ commitinfo_free(struct commitinfo *ci)
56 if (ci->deltas)
57 for (i = 0; i
< ci->ndeltas; i++)
58
deltainfo_free(ci->deltas[i]);
59+
60 free(ci->deltas);
61- ci->deltas = NULL;
62 git_diff_free(ci->diff);
63
git_tree_free(ci->commit_tree);
64
git_tree_free(ci->parent_tree);
65
git_commit_free(ci->commit);
66
git_commit_free(ci->parent);
67+ memset(ci, 0, sizeof(*ci));
68 free(ci);
69 }
70
71@@ -180,7 +205,6 @@ struct commitinfo *
72 commitinfo_getbyoid(const git_oid *id)
73 {
74 struct commitinfo
*ci;
75- git_diff_options opts;
76
77 if (!(ci =
calloc(1, sizeof(struct commitinfo))))
78 err(1,
"calloc");
79@@ -197,20 +221,6 @@ commitinfo_getbyoid(const git_oid *id)
80 ci->summary =
git_commit_summary(ci->commit);
81 ci->msg =
git_commit_message(ci->commit);
82
83- if (git_tree_lookup(&(ci->commit_tree), repo,
git_commit_tree_id(ci->commit)))
84- goto err;
85- if
(!git_commit_parent(&(ci->parent), ci->commit, 0)) {
86- if
(git_tree_lookup(&(ci->parent_tree), repo, git_commit_tree_id(ci->parent))) {
87- ci->parent =
NULL;
88-
ci->parent_tree = NULL;
89- }
90- }
91-
92-
git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION);
93- opts.flags |=
GIT_DIFF_DISABLE_PATHSPEC_MATCH;
94- if
(git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))
95- goto err;
96-
97 return ci;
98
99 err: