commit 84de91061b4d6cf5649efd5a42c4c3b90550332c from: Stefan Sperling date: Sat Dec 26 20:48:43 2020 UTC Add a refs argument to got_repo_match_object_id(), replacing 'resolve_tags' Make use of this where possible to avoid re-reading references from disk. ok naddy commit - 8924d611db93087fb80e3221b1876b5ebabe5f0b commit + 84de91061b4d6cf5649efd5a42c4c3b90550332c blob - 5f87f8a6758feb7e94e8c6665cab42a06ff59f62 blob + 5ae8df4581b3c8b1b606407a8243cf633db3b443 --- got/got.c +++ got/got.c @@ -2743,8 +2743,15 @@ cmd_checkout(int argc, char *argv[]) if (commit_id_str) { struct got_object_id *commit_id; + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, + NULL); + if (error) + goto done; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); + got_ref_list_free(&refs); if (error) goto done; error = check_linear_ancestry(commit_id, @@ -3050,8 +3057,15 @@ cmd_update(int argc, char *argv[]) if (error != NULL) goto done; } else { + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, + NULL); + if (error) + goto done; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); + got_ref_list_free(&refs); free(commit_id_str); commit_id_str = NULL; if (error) @@ -3815,6 +3829,10 @@ cmd_log(int argc, char *argv[]) if (error) goto done; + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); + if (error) + goto done; + if (start_commit == NULL) { struct got_reference *head_ref; struct got_commit_object *commit = NULL; @@ -3834,13 +3852,13 @@ cmd_log(int argc, char *argv[]) got_object_commit_close(commit); } else { error = got_repo_match_object_id(&start_id, NULL, - start_commit, GOT_OBJ_TYPE_COMMIT, 1, repo); + start_commit, GOT_OBJ_TYPE_COMMIT, &refs, repo); if (error != NULL) goto done; } if (end_commit != NULL) { error = got_repo_match_object_id(&end_id, NULL, - end_commit, GOT_OBJ_TYPE_COMMIT, 1, repo); + end_commit, GOT_OBJ_TYPE_COMMIT, &refs, repo); if (error != NULL) goto done; } @@ -3870,10 +3888,6 @@ cmd_log(int argc, char *argv[]) path = in_repo_path; } - error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); - if (error) - goto done; - error = print_commits(start_id, end_id, repo, path ? path : "", show_changed_paths, show_patch, search_pattern, diff_context, limit, log_branches, reverse_display_order, &refs); @@ -4114,7 +4128,10 @@ cmd_diff(int argc, char *argv[]) int force_text_diff = 0; const char *errstr; char *path = NULL; + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + #ifndef PROFILE if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil", NULL) == -1) @@ -4255,14 +4272,18 @@ cmd_diff(int argc, char *argv[]) got_pathlist_free(&paths); goto done; } + + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); + if (error) + return error; error = got_repo_match_object_id(&id1, &label1, id_str1, - GOT_OBJ_TYPE_ANY, 1, repo); + GOT_OBJ_TYPE_ANY, &refs, repo); if (error) goto done; error = got_repo_match_object_id(&id2, &label2, id_str2, - GOT_OBJ_TYPE_ANY, 1, repo); + GOT_OBJ_TYPE_ANY, &refs, repo); if (error) goto done; @@ -4313,6 +4334,7 @@ done: if (error == NULL) error = repo_error; } + got_ref_list_free(&refs); return error; } @@ -4559,8 +4581,15 @@ cmd_blame(int argc, char *argv[]) if (error != NULL) goto done; } else { + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, + NULL); + if (error) + goto done; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); + got_ref_list_free(&refs); if (error) goto done; } @@ -4895,8 +4924,15 @@ cmd_tree(int argc, char *argv[]) if (error != NULL) goto done; } else { + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, + NULL); + if (error) + goto done; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); + got_ref_list_free(&refs); if (error) goto done; } @@ -5609,12 +5645,19 @@ cmd_branch(int argc, char *argv[]) else if (delref) error = delete_branch(repo, worktree, delref); else { + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, + NULL); + if (error) + goto done; if (commit_id_arg == NULL) commit_id_arg = worktree ? got_worktree_get_head_ref_name(worktree) : GOT_REF_HEAD; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_arg, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_arg, GOT_OBJ_TYPE_COMMIT, &refs, repo); + got_ref_list_free(&refs); if (error) goto done; error = add_branch(repo, argv[0], commit_id); @@ -5931,7 +5974,10 @@ add_tag(struct got_repository *repo, struct got_worktr char *refname = NULL, *tagmsg = NULL, *tagger = NULL; char *tagmsg_path = NULL, *tag_id_str = NULL; int preserve_tagmsg = 0; + struct got_reflist_head refs; + SIMPLEQ_INIT(&refs); + /* * Don't let the user create a tag name with a leading '-'. * While technically a valid reference name, this case is usually @@ -5944,8 +5990,12 @@ add_tag(struct got_repository *repo, struct got_worktr if (err) return err; + err = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); + if (err) + goto done; + err = got_repo_match_object_id(&commit_id, &label, commit_arg, - GOT_OBJ_TYPE_COMMIT, 1, repo); + GOT_OBJ_TYPE_COMMIT, &refs, repo); if (err) goto done; @@ -6027,6 +6077,7 @@ done: free(tagmsg); free(tagmsg_path); free(tagger); + got_ref_list_free(&refs); return err; } @@ -9571,6 +9622,9 @@ cmd_cat(int argc, char *argv[]) const char *commit_id_str = NULL; struct got_object_id *id = NULL, *commit_id = NULL; int ch, obj_type, i, force_path = 0; + struct got_reflist_head refs; + + SIMPLEQ_INIT(&refs); #ifndef PROFILE if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil", @@ -9636,10 +9690,14 @@ cmd_cat(int argc, char *argv[]) if (error) goto done; + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); + if (error) + goto done; + if (commit_id_str == NULL) commit_id_str = GOT_REF_HEAD; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &refs, repo); if (error) goto done; @@ -9651,7 +9709,8 @@ cmd_cat(int argc, char *argv[]) break; } else { error = got_repo_match_object_id(&id, &label, argv[i], - GOT_OBJ_TYPE_ANY, 0, repo); + GOT_OBJ_TYPE_ANY, NULL /* do not resolve tags */, + repo); if (error) { if (error->code != GOT_ERR_BAD_OBJ_ID_STR && error->code != GOT_ERR_NOT_REF) @@ -9703,6 +9762,7 @@ done: if (error == NULL) error = repo_error; } + got_ref_list_free(&refs); return error; } blob - fe98a9294517fd1c072b9a28b7f9d272389c72f7 blob + 53ce046986e836dd5050f4b5ede182d2d14a06e0 --- gotweb/gotweb.c +++ gotweb/gotweb.c @@ -175,9 +175,12 @@ static const struct got_error *gw_get_repo_owner(char static const struct got_error *gw_get_time_str(char **, time_t, int); static const struct got_error *gw_get_repo_age(char **, struct gw_trans *, char *, const char *, int); -static const struct got_error *gw_output_file_blame(struct gw_trans *); -static const struct got_error *gw_output_blob_buf(struct gw_trans *); -static const struct got_error *gw_output_repo_tree(struct gw_trans *); +static const struct got_error *gw_output_file_blame(struct gw_trans *, + struct gw_header *); +static const struct got_error *gw_output_blob_buf(struct gw_trans *, + struct gw_header *); +static const struct got_error *gw_output_repo_tree(struct gw_trans *, + struct gw_header *); static const struct got_error *gw_output_diff(struct gw_trans *, struct gw_header *); static const struct got_error *gw_output_repo_tags(struct gw_trans *, @@ -399,7 +402,7 @@ gw_blame(struct gw_trans *gw_trans) "blame", KATTR__MAX); if (kerr != KCGI_OK) goto done; - error = gw_output_file_blame(gw_trans); + error = gw_output_file_blame(gw_trans, header); if (error) goto done; kerr = khtml_closeelem(gw_trans->gw_html_req, 2); @@ -443,7 +446,7 @@ gw_blob(struct gw_trans *gw_trans) if (error) goto done; - error = gw_output_blob_buf(gw_trans); + error = gw_output_blob_buf(gw_trans, header); done: if (error) { @@ -1653,7 +1656,7 @@ gw_tree(struct gw_trans *gw_trans) "tree", KATTR__MAX); if (kerr != KCGI_OK) goto done; - error = gw_output_repo_tree(gw_trans); + error = gw_output_repo_tree(gw_trans, header); if (error) goto done; @@ -2854,13 +2857,15 @@ gw_output_diff(struct gw_trans *gw_trans, struct gw_he if (header->parent_id != NULL && strncmp(header->parent_id, "/dev/null", 9) != 0) { error = got_repo_match_object_id(&id1, &label1, - header->parent_id, GOT_OBJ_TYPE_ANY, 1, gw_trans->repo); + header->parent_id, GOT_OBJ_TYPE_ANY, + &header->refs, gw_trans->repo); if (error) goto done; } error = got_repo_match_object_id(&id2, &label2, - header->commit_id, GOT_OBJ_TYPE_ANY, 1, gw_trans->repo); + header->commit_id, GOT_OBJ_TYPE_ANY, &header->refs, + gw_trans->repo); if (error) goto done; @@ -3951,7 +3956,7 @@ done: } static const struct got_error * -gw_output_file_blame(struct gw_trans *gw_trans) +gw_output_file_blame(struct gw_trans *gw_trans, struct gw_header *header) { const struct got_error *error = NULL; struct got_object_id *obj_id = NULL; @@ -3975,7 +3980,7 @@ gw_output_file_blame(struct gw_trans *gw_trans) goto done; error = got_repo_match_object_id(&commit_id, NULL, gw_trans->commit_id, - GOT_OBJ_TYPE_COMMIT, 1, gw_trans->repo); + GOT_OBJ_TYPE_COMMIT, &header->refs, gw_trans->repo); if (error) goto done; @@ -4056,7 +4061,7 @@ done: } static const struct got_error * -gw_output_blob_buf(struct gw_trans *gw_trans) +gw_output_blob_buf(struct gw_trans *gw_trans, struct gw_header *header) { const struct got_error *error = NULL; struct got_object_id *obj_id = NULL; @@ -4081,7 +4086,7 @@ gw_output_blob_buf(struct gw_trans *gw_trans) goto done; error = got_repo_match_object_id(&commit_id, NULL, gw_trans->commit_id, - GOT_OBJ_TYPE_COMMIT, 1, gw_trans->repo); + GOT_OBJ_TYPE_COMMIT, &header->refs, gw_trans->repo); if (error) goto done; @@ -4148,7 +4153,7 @@ done: } static const struct got_error * -gw_output_repo_tree(struct gw_trans *gw_trans) +gw_output_repo_tree(struct gw_trans *gw_trans, struct gw_header *header) { const struct got_error *error = NULL; struct got_object_id *tree_id = NULL, *commit_id = NULL; @@ -4198,7 +4203,7 @@ gw_output_repo_tree(struct gw_trans *gw_trans) } else { error = got_repo_match_object_id(&commit_id, NULL, - gw_trans->commit_id, GOT_OBJ_TYPE_COMMIT, 1, + gw_trans->commit_id, GOT_OBJ_TYPE_COMMIT, &header->refs, gw_trans->repo); if (error) goto done; blob - 58d890d3d6f831f42b34c8497b53e4dbaafb6eb3 blob + 1b274cc91e744b2672ce8c785379d258cd79f4cb --- include/got_repository.h +++ include/got_repository.h @@ -94,6 +94,7 @@ char *got_repo_get_path_gitconfig(struct got_repositor char *got_repo_get_path_gotconfig(struct got_repository *); struct got_reference; +struct got_reflist_head; /* * Obtain a reference, by name, from a repository. @@ -119,22 +120,25 @@ const struct got_error *got_repo_match_object_id_prefi /* * Given an object ID string or reference name, attempt to find a corresponding - * commit object. Tags can optionally be ignored during matching. + * commit object. * The object type may be restricted to commit, tree, blob, or tag. + * Tags will only be matched if a list of references is provided. * GOT_OBJ_TYPE_ANY will match any type of object. * A human-readable label can optionally be returned, which the caller should * dispose of with free(3). * Return GOT_ERR_NO_OBJ if no matching commit can be found. */ const struct got_error *got_repo_match_object_id(struct got_object_id **, - char **, const char *, int, int, struct got_repository *); + char **, const char *, int, struct got_reflist_head *, + struct got_repository *); /* - * Attempt to find a tag object with a given name and target object type. + * Search the provided list of references for a tag with a given name + * and target object type. * Return GOT_ERR_NO_OBJ if no matching tag can be found. */ const struct got_error *got_repo_object_match_tag(struct got_tag_object **, - const char *, int, struct got_repository *); + const char *, int, struct got_reflist_head *, struct got_repository *); /* A callback function which is invoked when a path is imported. */ typedef const struct got_error *(*got_repo_import_cb)(void *, const char *); blob - 7a2d2999eee396614f65ab978214ffc035a1f4c2 blob + bfbd39aabab2179cdbf0100c7d1b2534617f140e --- lib/repository.c +++ lib/repository.c @@ -1467,7 +1467,7 @@ done: const struct got_error * got_repo_match_object_id(struct got_object_id **id, char **label, - const char *id_str, int obj_type, int resolve_tags, + const char *id_str, int obj_type, struct got_reflist_head *refs, struct got_repository *repo) { const struct got_error *err; @@ -1478,9 +1478,9 @@ got_repo_match_object_id(struct got_object_id **id, ch if (label) *label = NULL; - if (resolve_tags) { + if (refs) { err = got_repo_object_match_tag(&tag, id_str, GOT_OBJ_TYPE_ANY, - repo); + refs, repo); if (err == NULL) { *id = got_object_id_dup( got_object_tag_get_object_id(tag)); @@ -1529,26 +1529,22 @@ done: const struct got_error * got_repo_object_match_tag(struct got_tag_object **tag, const char *name, - int obj_type, struct got_repository *repo) + int obj_type, struct got_reflist_head *refs, struct got_repository *repo) { - const struct got_error *err; - struct got_reflist_head refs; + const struct got_error *err = NULL; struct got_reflist_entry *re; struct got_object_id *tag_id; int name_is_absolute = (strncmp(name, "refs/", 5) == 0); - SIMPLEQ_INIT(&refs); *tag = NULL; - - err = got_ref_list(&refs, repo, "refs/tags", got_ref_cmp_by_name, NULL); - if (err) - return err; - SIMPLEQ_FOREACH(re, &refs, entry) { + SIMPLEQ_FOREACH(re, refs, entry) { const char *refname; refname = got_ref_get_name(re->ref); if (got_ref_is_symbolic(re->ref)) continue; + if (strncmp(refname, "refs/tags/", 10) != 0) + continue; if (!name_is_absolute) refname += strlen("refs/tags/"); if (strcmp(refname, name) != 0) @@ -1567,7 +1563,6 @@ got_repo_object_match_tag(struct got_tag_object **tag, *tag = NULL; } - got_ref_list_free(&refs); if (err == NULL && *tag == NULL) err = got_error_path(name, GOT_ERR_NO_OBJ); return err; blob - ee2324cc37e9714754f8a581d0e546d0ef5f385c blob + c02189d556c9524c29a6a39fe32265db45eaf932 --- tog/tog.c +++ tog/tog.c @@ -2537,7 +2537,7 @@ input_log_view(struct tog_view **new_view, struct tog_ struct got_object_id *start_id; err = got_repo_match_object_id(&start_id, NULL, s->head_ref_name ? s->head_ref_name : GOT_REF_HEAD, - GOT_OBJ_TYPE_COMMIT, 1, s->repo); + GOT_OBJ_TYPE_COMMIT, &tog_refs, s->repo); if (err) return err; free(s->start_id); @@ -2763,7 +2763,7 @@ cmd_log(int argc, char *argv[]) if (start_commit == NULL) { error = got_repo_match_object_id(&start_id, &label, worktree ? got_worktree_get_head_ref_name(worktree) : - GOT_REF_HEAD, GOT_OBJ_TYPE_COMMIT, 1, repo); + GOT_REF_HEAD, GOT_OBJ_TYPE_COMMIT, &tog_refs, repo); if (error) goto done; head_ref_name = label; @@ -2774,7 +2774,7 @@ cmd_log(int argc, char *argv[]) else if (error->code != GOT_ERR_NOT_REF) goto done; error = got_repo_match_object_id(&start_id, NULL, - start_commit, GOT_OBJ_TYPE_COMMIT, 1, repo); + start_commit, GOT_OBJ_TYPE_COMMIT, &tog_refs, repo); if (error) goto done; } @@ -3833,12 +3833,12 @@ cmd_diff(int argc, char *argv[]) goto done; error = got_repo_match_object_id(&id1, &label1, id_str1, - GOT_OBJ_TYPE_ANY, 1, repo); + GOT_OBJ_TYPE_ANY, &tog_refs, repo); if (error) goto done; error = got_repo_match_object_id(&id2, &label2, id_str2, - GOT_OBJ_TYPE_ANY, 1, repo); + GOT_OBJ_TYPE_ANY, &tog_refs, repo); if (error) goto done; @@ -4740,7 +4740,7 @@ cmd_blame(int argc, char *argv[]) got_ref_close(head_ref); } else { error = got_repo_match_object_id(&commit_id, NULL, - commit_id_str, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_str, GOT_OBJ_TYPE_COMMIT, &tog_refs, repo); } if (error != NULL) goto done; @@ -5548,7 +5548,7 @@ cmd_tree(int argc, char *argv[]) if (commit_id_arg == NULL) { error = got_repo_match_object_id(&commit_id, &label, worktree ? got_worktree_get_head_ref_name(worktree) : - GOT_REF_HEAD, GOT_OBJ_TYPE_COMMIT, 1, repo); + GOT_REF_HEAD, GOT_OBJ_TYPE_COMMIT, &tog_refs, repo); if (error) goto done; head_ref_name = label; @@ -5559,7 +5559,7 @@ cmd_tree(int argc, char *argv[]) else if (error->code != GOT_ERR_NOT_REF) goto done; error = got_repo_match_object_id(&commit_id, NULL, - commit_id_arg, GOT_OBJ_TYPE_COMMIT, 1, repo); + commit_id_arg, GOT_OBJ_TYPE_COMMIT, &tog_refs, repo); if (error) goto done; } @@ -6353,6 +6353,9 @@ tog_log_with_path(int argc, char *argv[]) struct got_object_id *commit_id = NULL, *id = NULL; char *cwd = NULL, *repo_path = NULL, *in_repo_path = NULL; char *commit_id_str = NULL, **cmd_argv = NULL; + struct got_reflist_head refs; + + SIMPLEQ_INIT(&refs); cwd = getcwd(NULL, 0); if (cwd == NULL) @@ -6380,9 +6383,12 @@ tog_log_with_path(int argc, char *argv[]) if (error) goto done; + error = got_ref_list(&refs, repo, NULL, got_ref_cmp_by_name, NULL); + if (error) + goto done; error = got_repo_match_object_id(&commit_id, NULL, worktree ? got_worktree_get_head_ref_name(worktree) : GOT_REF_HEAD, - GOT_OBJ_TYPE_COMMIT, 1, repo); + GOT_OBJ_TYPE_COMMIT, &refs, repo); if (error) goto done; @@ -6429,6 +6435,7 @@ done: free(cmd_argv[i]); free(cmd_argv); } + got_ref_list_free(&refs); return error; }