commit ec19160fa44ca478dd7e319eea8ee1ee1a0973e2
parent ab46ca27fc26888dc6e061c614d085114eb7b1ea
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri, 9 Feb 2018 16:13:57 +0100
optimization: only diff the tree when it is needed for the diffstat...
... also clear all fields in the structure on failure.
Diffstat:
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/stagit-gopher.c b/stagit-gopher.c
@@ -131,7 +131,7 @@ deltainfo_free(struct deltainfo *di)
if (!di)
return;
git_patch_free(di->patch);
- di->patch = NULL;
+ memset(di, 0, sizeof(*di));
free(di);
}
@@ -139,6 +139,7 @@ int
commitinfo_getstats(struct commitinfo *ci)
{
struct deltainfo *di;
+ git_diff_options opts;
const git_diff_delta *delta;
const git_diff_hunk *hunk;
const git_diff_line *line;
@@ -146,6 +147,20 @@ commitinfo_getstats(struct commitinfo *ci)
size_t ndeltas, nhunks, nhunklines;
size_t i, j, k;
+ if (git_tree_lookup(&(ci->commit_tree), repo, git_commit_tree_id(ci->commit)))
+ goto err;
+ if (!git_commit_parent(&(ci->parent), ci->commit, 0)) {
+ if (git_tree_lookup(&(ci->parent_tree), repo, git_commit_tree_id(ci->parent))) {
+ ci->parent = NULL;
+ ci->parent_tree = NULL;
+ }
+ }
+
+ git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION);
+ opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
+ if (git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))
+ goto err;
+
ndeltas = git_diff_num_deltas(ci->diff);
if (ndeltas && !(ci->deltas = calloc(ndeltas, sizeof(struct deltainfo *))))
err(1, "calloc");
@@ -187,6 +202,14 @@ commitinfo_getstats(struct commitinfo *ci)
return 0;
err:
+ git_diff_free(ci->diff);
+ ci->diff = NULL;
+ git_tree_free(ci->commit_tree);
+ ci->commit_tree = NULL;
+ git_tree_free(ci->parent_tree);
+ ci->parent_tree = NULL;
+ git_commit_free(ci->parent);
+ ci->parent = NULL;
if (ci->deltas)
for (i = 0; i < ci->ndeltas; i++)
deltainfo_free(ci->deltas[i]);
@@ -211,12 +234,12 @@ commitinfo_free(struct commitinfo *ci)
for (i = 0; i < ci->ndeltas; i++)
deltainfo_free(ci->deltas[i]);
free(ci->deltas);
- ci->deltas = NULL;
git_diff_free(ci->diff);
git_tree_free(ci->commit_tree);
git_tree_free(ci->parent_tree);
git_commit_free(ci->commit);
git_commit_free(ci->parent);
+ memset(ci, 0, sizeof(*ci));
free(ci);
}
@@ -224,7 +247,6 @@ struct commitinfo *
commitinfo_getbyoid(const git_oid *id)
{
struct commitinfo *ci;
- git_diff_options opts;
if (!(ci = calloc(1, sizeof(struct commitinfo))))
err(1, "calloc");
@@ -241,20 +263,6 @@ commitinfo_getbyoid(const git_oid *id)
ci->summary = git_commit_summary(ci->commit);
ci->msg = git_commit_message(ci->commit);
- if (git_tree_lookup(&(ci->commit_tree), repo, git_commit_tree_id(ci->commit)))
- goto err;
- if (!git_commit_parent(&(ci->parent), ci->commit, 0)) {
- if (git_tree_lookup(&(ci->parent_tree), repo, git_commit_tree_id(ci->parent))) {
- ci->parent = NULL;
- ci->parent_tree = NULL;
- }
- }
-
- git_diff_init_options(&opts, GIT_DIFF_OPTIONS_VERSION);
- opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH;
- if (git_diff_tree_to_tree(&(ci->diff), repo, ci->parent_tree, ci->commit_tree, &opts))
- goto err;
-
return ci;
err: