treewide: rename tree to maybe_tree

Using the commit-graph file to walk commit history removes the large cost of parsing commits during the walk. This exposes a performance issue: lookup_tree() takes a large portion of the computation time, even when Git never uses those trees. In anticipation of lazy-loading these trees, rename the 'tree' member of struct commit to 'maybe_tree'. This serves two purposes: it hints at the future role of possibly being NULL even if the commit has a valid tree, and it allows for unambiguous transformation from simple member access (i.e. commit->maybe_tree) to method access. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Apr 6, 2018 at 19:09 UTC 891435d55da80ca3654b19834481205be6bdfe33
24 files changed +65 -64
blame.c
+9 -9
@@ -553,10 +553,10 @@ static struct blame_origin *find_origin(struct commit *parent,
553 diff_setup_done(&diff_opts);
554
555 if (is_null_oid(&origin->commit->object.oid))
556 - do_diff_cache(&parent->tree->object.oid, &diff_opts);
556 + do_diff_cache(&parent->maybe_tree->object.oid, &diff_opts);
557 else
558 - diff_tree_oid(&parent->tree->object.oid,
559 - &origin->commit->tree->object.oid,
558 + diff_tree_oid(&parent->maybe_tree->object.oid,
559 + &origin->commit->maybe_tree->object.oid,
560 "", &diff_opts);
561 diffcore_std(&diff_opts);
562
@@ -622,10 +622,10 @@ static struct blame_origin *find_rename(struct commit *parent,
622 diff_setup_done(&diff_opts);
623
624 if (is_null_oid(&origin->commit->object.oid))
625 - do_diff_cache(&parent->tree->object.oid, &diff_opts);
625 + do_diff_cache(&parent->maybe_tree->object.oid, &diff_opts);
626 else
627 - diff_tree_oid(&parent->tree->object.oid,
628 - &origin->commit->tree->object.oid,
627 + diff_tree_oid(&parent->maybe_tree->object.oid,
628 + &origin->commit->maybe_tree->object.oid,
629 "", &diff_opts);
630 diffcore_std(&diff_opts);
631
@@ -1257,10 +1257,10 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
1257 diff_opts.flags.find_copies_harder = 1;
1258
1259 if (is_null_oid(&target->commit->object.oid))
1260 - do_diff_cache(&parent->tree->object.oid, &diff_opts);
1260 + do_diff_cache(&parent->maybe_tree->object.oid, &diff_opts);
1261 else
1262 - diff_tree_oid(&parent->tree->object.oid,
1263 - &target->commit->tree->object.oid,
1262 + diff_tree_oid(&parent->maybe_tree->object.oid,
1263 + &target->commit->maybe_tree->object.oid,
1264 "", &diff_opts);
1265
1266 if (!diff_opts.flags.find_copies_harder)
builtin/checkout.c
+6 -6
@@ -484,7 +484,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
484
485 resolve_undo_clear();
486 if (opts->force) {
487 - ret = reset_tree(new_branch_info->commit->tree, opts, 1, writeout_error);
487 + ret = reset_tree(new_branch_info->commit->maybe_tree, opts, 1, writeout_error);
488 if (ret)
489 return ret;
490 } else {
@@ -570,18 +570,18 @@ static int merge_working_tree(const struct checkout_opts *opts,
570 o.verbosity = 0;
571 work = write_tree_from_memory(&o);
572
573 - ret = reset_tree(new_branch_info->commit->tree, opts, 1,
573 + ret = reset_tree(new_branch_info->commit->maybe_tree, opts, 1,
574 writeout_error);
575 if (ret)
576 return ret;
577 o.ancestor = old_branch_info->name;
578 o.branch1 = new_branch_info->name;
579 o.branch2 = "local";
580 - ret = merge_trees(&o, new_branch_info->commit->tree, work,
581 - old_branch_info->commit->tree, &result);
580 + ret = merge_trees(&o, new_branch_info->commit->maybe_tree, work,
581 + old_branch_info->commit->maybe_tree, &result);
582 if (ret < 0)
583 exit(128);
584 - ret = reset_tree(new_branch_info->commit->tree, opts, 0,
584 + ret = reset_tree(new_branch_info->commit->maybe_tree, opts, 0,
585 writeout_error);
586 strbuf_release(&o.obuf);
587 if (ret)
@@ -1002,7 +1002,7 @@ static int parse_branchname_arg(int argc, const char **argv,
1002 *source_tree = parse_tree_indirect(rev);
1003 } else {
1004 parse_commit_or_die(new_branch_info->commit);
1005 - *source_tree = new_branch_info->commit->tree;
1005 + *source_tree = new_branch_info->commit->maybe_tree;
1006 }
1007
1008 if (!*source_tree) /* case (1): want a tree */
builtin/diff.c
+1 -1
@@ -398,7 +398,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
398 if (!obj)
399 die(_("invalid object '%s' given."), name);
400 if (obj->type == OBJ_COMMIT)
401 - obj = &((struct commit *)obj)->tree->object;
401 + obj = &((struct commit *)obj)->maybe_tree->object;
402
403 if (obj->type == OBJ_TREE) {
404 obj->flags |= flags;
builtin/fast-export.c
+3 -3
@@ -578,11 +578,11 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
578 get_object_mark(&commit->parents->item->object) != 0 &&
579 !full_tree) {
580 parse_commit_or_die(commit->parents->item);
581 - diff_tree_oid(&commit->parents->item->tree->object.oid,
582 - &commit->tree->object.oid, "", &rev->diffopt);
581 + diff_tree_oid(&commit->parents->item->maybe_tree->object.oid,
582 + &commit->maybe_tree->object.oid, "", &rev->diffopt);
583 }
584 else
585 - diff_root_tree_oid(&commit->tree->object.oid,
585 + diff_root_tree_oid(&commit->maybe_tree->object.oid,
586 "", &rev->diffopt);
587
588 /* Export the referenced blobs, and remember the marks. */
builtin/log.c
+2 -2
@@ -1064,8 +1064,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
1064
1065 diff_setup_done(&opts);
1066
1067 - diff_tree_oid(&origin->tree->object.oid,
1068 - &head->tree->object.oid,
1067 + diff_tree_oid(&origin->maybe_tree->object.oid,
1068 + &head->maybe_tree->object.oid,
1069 "", &opts);
1070 diffcore_std(&opts);
1071 diff_flush(&opts);
builtin/reflog.c
+1 -1
@@ -153,7 +153,7 @@ static int commit_is_complete(struct commit *commit)
153 for (i = 0; i < found.nr; i++) {
154 struct commit *c =
155 (struct commit *)found.objects[i].item;
156 - if (!tree_is_complete(&c->tree->object.oid)) {
156 + if (!tree_is_complete(&c->maybe_tree->object.oid)) {
157 is_incomplete = 1;
158 c->object.flags |= INCOMPLETE;
159 }
commit-graph.c
+2 -2
@@ -258,7 +258,7 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin
258 item->graph_pos = pos;
259
260 hashcpy(oid.hash, commit_data);
261 - item->tree = lookup_tree(&oid);
261 + item->maybe_tree = lookup_tree(&oid);
262
263 date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
264 date_low = get_be32(commit_data + g->hash_len + 12);
@@ -369,7 +369,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
369 uint32_t packedDate[2];
370
371 parse_commit(*list);
372 - hashwrite(f, (*list)->tree->object.oid.hash, hash_len);
372 + hashwrite(f, (*list)->maybe_tree->object.oid.hash, hash_len);
373
374 parent = (*list)->parents;
375
commit.c
+1 -1
@@ -335,7 +335,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
335 if (get_sha1_hex(bufptr + 5, parent.hash) < 0)
336 return error("bad tree pointer in commit %s",
337 oid_to_hex(&item->object.oid));
338 - item->tree = lookup_tree(&parent);
338 + item->maybe_tree = lookup_tree(&parent);
339 bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */
340 pptr = &item->parents;
341
commit.h
+1 -1
@@ -22,7 +22,7 @@ struct commit {
22 unsigned int index;
23 timestamp_t date;
24 struct commit_list *parents;
25 - struct tree *tree;
25 + struct tree *maybe_tree;
26 uint32_t graph_pos;
27 };
28
fsck.c
+3 -3
@@ -396,9 +396,9 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
396
397 name = get_object_name(options, &commit->object);
398 if (name)
399 - put_object_name(options, &commit->tree->object, "%s:", name);
399 + put_object_name(options, &commit->maybe_tree->object, "%s:", name);
400
401 - result = options->walk((struct object *)commit->tree, OBJ_TREE, data, options);
401 + result = options->walk((struct object *)commit->maybe_tree, OBJ_TREE, data, options);
402 if (result < 0)
403 return result;
404 res = result;
@@ -772,7 +772,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
772 err = fsck_ident(&buffer, &commit->object, options);
773 if (err)
774 return err;
775 - if (!commit->tree) {
775 + if (!commit->maybe_tree) {
776 err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
777 if (err)
778 return err;
http-push.c
+1 -1
@@ -1330,7 +1330,7 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
1330 int count = 0;
1331
1332 while ((commit = get_revision(revs)) != NULL) {
1333 - p = process_tree(commit->tree, p);
1333 + p = process_tree(commit->maybe_tree, p);
1334 commit->object.flags |= LOCAL;
1335 if (!(commit->object.flags & UNINTERESTING))
1336 count += add_send_request(&commit->object, lock);
line-log.c
+2 -2
@@ -817,8 +817,8 @@ static void queue_diffs(struct line_log_data *range,
817 assert(commit);
818
819 DIFF_QUEUE_CLEAR(&diff_queued_diff);
820 - diff_tree_oid(parent ? &parent->tree->object.oid : NULL,
821 - &commit->tree->object.oid, "", opt);
820 + diff_tree_oid(parent ? &parent->maybe_tree->object.oid : NULL,
821 + &commit->maybe_tree->object.oid, "", opt);
822 if (opt->detect_rename) {
823 filter_diffs_for_paths(range, 1);
824 if (diff_might_be_rename())
list-objects.c
+5 -5
@@ -195,7 +195,7 @@ static void mark_edge_parents_uninteresting(struct commit *commit,
195 struct commit *parent = parents->item;
196 if (!(parent->object.flags & UNINTERESTING))
197 continue;
198 - mark_tree_uninteresting(parent->tree);
198 + mark_tree_uninteresting(parent->maybe_tree);
199 if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
200 parent->object.flags |= SHOWN;
201 show_edge(parent);
@@ -212,7 +212,7 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
212 struct commit *commit = list->item;
213
214 if (commit->object.flags & UNINTERESTING) {
215 - mark_tree_uninteresting(commit->tree);
215 + mark_tree_uninteresting(commit->maybe_tree);
216 if (revs->edge_hint_aggressive && !(commit->object.flags & SHOWN)) {
217 commit->object.flags |= SHOWN;
218 show_edge(commit);
@@ -227,7 +227,7 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
227 struct commit *commit = (struct commit *)obj;
228 if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
229 continue;
230 - mark_tree_uninteresting(commit->tree);
230 + mark_tree_uninteresting(commit->maybe_tree);
231 if (!(obj->flags & SHOWN)) {
232 obj->flags |= SHOWN;
233 show_edge(commit);
@@ -300,8 +300,8 @@ static void do_traverse(struct rev_info *revs,
300 * an uninteresting boundary commit may not have its tree
301 * parsed yet, but we are not going to show them anyway
302 */
303 - if (commit->tree)
304 - add_pending_tree(revs, commit->tree);
303 + if (commit->maybe_tree)
304 + add_pending_tree(revs, commit->maybe_tree);
305 show_commit(commit, show_data);
306
307 if (revs->tree_blobs_in_commit_order)
log-tree.c
+3 -3
@@ -806,7 +806,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
806 return 0;
807
808 parse_commit_or_die(commit);
809 - oid = &commit->tree->object.oid;
809 + oid = &commit->maybe_tree->object.oid;
810
811 /* Root commit? */
812 parents = get_saved_parents(opt, commit);
@@ -831,7 +831,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
831 * we merged _in_.
832 */
833 parse_commit_or_die(parents->item);
834 - diff_tree_oid(&parents->item->tree->object.oid,
834 + diff_tree_oid(&parents->item->maybe_tree->object.oid,
835 oid, "", &opt->diffopt);
836 log_tree_diff_flush(opt);
837 return !opt->loginfo;
@@ -846,7 +846,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
846 struct commit *parent = parents->item;
847
848 parse_commit_or_die(parent);
849 - diff_tree_oid(&parent->tree->object.oid,
849 + diff_tree_oid(&parent->maybe_tree->object.oid,
850 oid, "", &opt->diffopt);
851 log_tree_diff_flush(opt);
852
merge-recursive.c
+3 -2
@@ -101,7 +101,7 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment
101 struct commit *commit = alloc_commit_node();
102
103 set_merge_remote_desc(commit, comment, (struct object *)commit);
104 - commit->tree = tree;
104 + commit->maybe_tree = tree;
105 commit->object.parsed = 1;
106 return commit;
107 }
@@ -2154,7 +2154,8 @@ int merge_recursive(struct merge_options *o,
2154 read_cache();
2155
2156 o->ancestor = "merged common ancestors";
2157 - clean = merge_trees(o, h1->tree, h2->tree, merged_common_ancestors->tree,
2157 + clean = merge_trees(o, h1->maybe_tree, h2->maybe_tree,
2158 + merged_common_ancestors->maybe_tree,
2159 &mrtree);
2160 if (clean < 0) {
2161 flush_output(o);
notes-merge.c
+4 -4
@@ -600,14 +600,14 @@ int notes_merge(struct notes_merge_options *o,
600 printf("No merge base found; doing history-less merge\n");
601 } else if (!bases->next) {
602 base_oid = &bases->item->object.oid;
603 - base_tree_oid = &bases->item->tree->object.oid;
603 + base_tree_oid = &bases->item->maybe_tree->object.oid;
604 if (o->verbosity >= 4)
605 printf("One merge base found (%.7s)\n",
606 oid_to_hex(base_oid));
607 } else {
608 /* TODO: How to handle multiple merge-bases? */
609 base_oid = &bases->item->object.oid;
610 - base_tree_oid = &bases->item->tree->object.oid;
610 + base_tree_oid = &bases->item->maybe_tree->object.oid;
611 if (o->verbosity >= 3)
612 printf("Multiple merge bases found. Using the first "
613 "(%.7s)\n", oid_to_hex(base_oid));
@@ -634,8 +634,8 @@ int notes_merge(struct notes_merge_options *o,
634 goto found_result;
635 }
636
637 - result = merge_from_diffs(o, base_tree_oid, &local->tree->object.oid,
638 - &remote->tree->object.oid, local_tree);
637 + result = merge_from_diffs(o, base_tree_oid, &local->maybe_tree->object.oid,
638 + &remote->maybe_tree->object.oid, local_tree);
639
640 if (result != 0) { /* non-trivial merge (with or without conflicts) */
641 /* Commit (partial) result */
packfile.c
+1 -1
@@ -1925,7 +1925,7 @@ static int add_promisor_object(const struct object_id *oid,
1925 struct commit *commit = (struct commit *) obj;
1926 struct commit_list *parents = commit->parents;
1927
1928 - oidset_insert(set, &commit->tree->object.oid);
1928 + oidset_insert(set, &commit->maybe_tree->object.oid);
1929 for (; parents; parents = parents->next)
1930 oidset_insert(set, &parents->item->object.oid);
1931 } else if (obj->type == OBJ_TAG) {
pretty.c
+2 -2
@@ -1161,10 +1161,10 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
1161 strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
1162 return 1;
1163 case 'T': /* tree hash */
1164 - strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
1164 + strbuf_addstr(sb, oid_to_hex(&commit->maybe_tree->object.oid));
1165 return 1;
1166 case 't': /* abbreviated tree hash */
1167 - strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
1167 + strbuf_add_unique_abbrev(sb, commit->maybe_tree->object.oid.hash,
1168 c->pretty_ctx->abbrev);
1169 return 1;
1170 case 'P': /* parent hashes */
ref-filter.c
+1 -1
@@ -815,7 +815,7 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
815 if (deref)
816 name++;
817 if (!strcmp(name, "tree")) {
818 - v->s = xstrdup(oid_to_hex(&commit->tree->object.oid));
818 + v->s = xstrdup(oid_to_hex(&commit->maybe_tree->object.oid));
819 }
820 else if (!strcmp(name, "numparent")) {
821 v->value = commit_list_count(commit->parents);
revision.c
+4 -4
@@ -439,8 +439,8 @@ static void file_change(struct diff_options *options,
439 static int rev_compare_tree(struct rev_info *revs,
440 struct commit *parent, struct commit *commit)
441 {
442 - struct tree *t1 = parent->tree;
443 - struct tree *t2 = commit->tree;
442 + struct tree *t1 = parent->maybe_tree;
443 + struct tree *t2 = commit->maybe_tree;
444
445 if (!t1)
446 return REV_TREE_NEW;
@@ -476,7 +476,7 @@ static int rev_compare_tree(struct rev_info *revs,
476 static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
477 {
478 int retval;
479 - struct tree *t1 = commit->tree;
479 + struct tree *t1 = commit->maybe_tree;
480
481 if (!t1)
482 return 0;
@@ -614,7 +614,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
614 if (!revs->prune)
615 return;
616
617 - if (!commit->tree)
617 + if (!commit->maybe_tree)
618 return;
619
620 if (!commit->parents) {
sequencer.c
+6 -6
@@ -501,8 +501,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
501 o.show_rename_progress = 1;
502
503 head_tree = parse_tree_indirect(head);
504 - next_tree = next ? next->tree : empty_tree();
505 - base_tree = base ? base->tree : empty_tree();
504 + next_tree = next ? next->maybe_tree : empty_tree();
505 + base_tree = base ? base->maybe_tree : empty_tree();
506
507 for (xopt = opts->xopts; xopt != opts->xopts + opts->xopts_nr; xopt++)
508 parse_merge_opt(&o, *xopt);
@@ -562,7 +562,7 @@ static int is_index_unchanged(void)
562 return error(_("unable to update cache tree"));
563
564 return !oidcmp(&active_cache_tree->oid,
565 - &head_commit->tree->object.oid);
565 + &head_commit->maybe_tree->object.oid);
566 }
567
568 static int write_author_script(const char *message)
@@ -1119,7 +1119,7 @@ static int try_to_commit(struct strbuf *msg, const char *author,
1119 }
1120
1121 if (!(flags & ALLOW_EMPTY) && !oidcmp(current_head ?
1122 - &current_head->tree->object.oid :
1122 + &current_head->maybe_tree->object.oid :
1123 &empty_tree_oid, &tree)) {
1124 res = 1; /* run 'git commit' to display error message */
1125 goto out;
@@ -1217,12 +1217,12 @@ static int is_original_commit_empty(struct commit *commit)
1217 if (parse_commit(parent))
1218 return error(_("could not parse parent commit %s"),
1219 oid_to_hex(&parent->object.oid));
1220 - ptree_oid = &parent->tree->object.oid;
1220 + ptree_oid = &parent->maybe_tree->object.oid;
1221 } else {
1222 ptree_oid = the_hash_algo->empty_tree; /* commit is root */
1223 }
1224
1225 - return !oidcmp(ptree_oid, &commit->tree->object.oid);
1225 + return !oidcmp(ptree_oid, &commit->maybe_tree->object.oid);
1226 }
1227
1228 /*
sha1_name.c
+1 -1
@@ -896,7 +896,7 @@ struct object *peel_to_type(const char *name, int namelen,
896 if (o->type == OBJ_TAG)
897 o = ((struct tag*) o)->tagged;
898 else if (o->type == OBJ_COMMIT)
899 - o = &(((struct commit *) o)->tree->object);
899 + o = &(((struct commit *) o)->maybe_tree->object);
900 else {
901 if (name)
902 error("%.*s: expected %s type, but the object "
tree.c
+2 -2
@@ -109,7 +109,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
109 oid_to_hex(entry.oid),
110 base->buf, entry.path);
111
112 - oidcpy(&oid, &commit->tree->object.oid);
112 + oidcpy(&oid, &commit->maybe_tree->object.oid);
113 }
114 else
115 continue;
@@ -248,7 +248,7 @@ struct tree *parse_tree_indirect(const struct object_id *oid)
248 if (obj->type == OBJ_TREE)
249 return (struct tree *) obj;
250 else if (obj->type == OBJ_COMMIT)
251 - obj = &(((struct commit *) obj)->tree->object);
251 + obj = &(((struct commit *) obj)->maybe_tree->object);
252 else if (obj->type == OBJ_TAG)
253 obj = ((struct tag *) obj)->tagged;
254 else
walker.c
+1 -1
@@ -87,7 +87,7 @@ static int process_commit(struct walker *walker, struct commit *commit)
87 walker_say(walker, "walk %s\n", oid_to_hex(&commit->object.oid));
88
89 if (walker->get_tree) {
90 - if (process(walker, &commit->tree->object))
90 + if (process(walker, &commit->maybe_tree->object))
91 return -1;
92 if (!walker->get_all)
93 walker->get_tree = 0;