commit 4626e416306921d48e15bacb31618804cf08c252 from: Stefan Sperling date: Sun Jun 10 23:25:06 2018 UTC parse commit timestamps when opening commits commit - 6e790f45d64975dc0b774d672fa3577dfcfafdc9 commit + 4626e416306921d48e15bacb31618804cf08c252 blob - 6a104bbde53b6ab5aa419027b762dc8b49c7426a blob + 1e65e1de77e0c082ed43fbd729a6aded82589fb4 --- include/got_object.h +++ include/got_object.h @@ -40,7 +40,9 @@ struct got_commit_object { unsigned int nparents; SIMPLEQ_HEAD(, got_parent_id) parent_ids; char *author; + time_t author_time; /* UTC */ char *committer; + time_t committer_time; /* UTC */ char *logmsg; }; @@ -122,14 +124,6 @@ const struct got_error *got_object_commit_open(struct /* Dispose of a commit object. */ void got_object_commit_close(struct got_commit_object *); -/* Get the commit's committer timestamp (in UTC). */ -const struct got_error *got_object_commit_get_committer_time(time_t *, - struct got_commit_object *); - -/* Get the commit's author timestamp (in UTC). */ -const struct got_error *got_object_commit_get_committer_time(time_t *, - struct got_commit_object *); - /* * Attempt to open a tree object in a repository. * The provided object must be of type GOT_OBJ_TYPE_TREE. blob - 5d6edcfd4343961cb8e7b00e4596e9d0fff68613 blob + 2743d3872f876458a7e854774c25fa8cdcd0417a --- lib/commit_graph.c +++ lib/commit_graph.c @@ -134,32 +134,21 @@ is_root_node(struct got_commit_graph_node *node) return node->commit->nparents == 0; } -static const struct got_error * -compare_commits(int *cmp, struct got_commit_object *c1, - struct got_commit_object *c2) +static int +compare_commits(struct got_commit_object *c1, struct got_commit_object *c2) { - const struct got_error *err; - int64_t t1, t2; + time_t t1, t2; - err = got_object_commit_get_committer_time(&t1, c1); - if (err) - return err; - err = got_object_commit_get_committer_time(&t2, c2); - - if (err) - return err; - + t1 = c1->committer_time; + t2 = c2->committer_time; if (t1 == t2) - *cmp = 0; + return 0; else if (t1 < t2) - *cmp = -1; - else - *cmp = 1; - - return NULL; + return -1; + return 1; } -static const struct got_error * +static void add_iteration_candidate(struct got_commit_graph *graph, struct got_commit_graph_node *node) { @@ -167,15 +156,11 @@ add_iteration_candidate(struct got_commit_graph *graph if (TAILQ_EMPTY(&graph->iter_candidates)) { TAILQ_INSERT_TAIL(&graph->iter_candidates, node, entry); - return NULL; + return; } TAILQ_FOREACH(n, &graph->iter_candidates, entry) { - const struct got_error *err; - int cmp; - err = compare_commits(&cmp, node->commit, n->commit); - if (err) - return err; + int cmp = compare_commits(node->commit, n->commit); if (cmp < 0) { next = TAILQ_NEXT(n, entry); if (next == NULL) { @@ -183,9 +168,7 @@ add_iteration_candidate(struct got_commit_graph *graph node, entry); break; } - err = compare_commits(&cmp, node->commit, next->commit); - if (err) - return err; + cmp = compare_commits(node->commit, next->commit); if (cmp >= 0) { TAILQ_INSERT_BEFORE(next, node, entry); break; @@ -195,8 +178,6 @@ add_iteration_candidate(struct got_commit_graph *graph break; } } - - return NULL; } static const struct got_error * @@ -222,10 +203,7 @@ add_node(struct got_commit_graph_node **new_node, if (err == NULL) { struct got_parent_id *pid; - err = add_iteration_candidate(graph, node); - if (err) - return err; - + add_iteration_candidate(graph, node); err = got_object_idset_remove(graph->open_branches, commit_id); if (err && err->code != GOT_ERR_NO_OBJ) return err; @@ -476,12 +454,8 @@ got_commit_graph_iter_start(struct got_commit_graph *g /* Put all known parents of this commit on the candidate list. */ SIMPLEQ_FOREACH(pid, &start_node->commit->parent_ids, entry) { node = got_object_idset_get(graph->node_ids, pid->id); - if (node) { - const struct got_error *err; - err = add_iteration_candidate(graph, node); - if (err) - return err; - } + if (node) + add_iteration_candidate(graph, node); } return NULL; blob - 679abeccb798c260183c7938c2b076e5824d5197 blob + 71c594ecb4163354cb87b7f2722eb4ea8c6a3576 --- lib/object.c +++ lib/object.c @@ -467,7 +467,35 @@ got_object_commit_add_parent(struct got_commit_object SIMPLEQ_INSERT_TAIL(&commit->parent_ids, pid, entry); commit->nparents++; + + return NULL; +} + +static const struct got_error * +parse_commit_time(time_t *time, char *committer) +{ + const char *errstr; + char *space; + + *time = 0; + + /* Strip off trailing timezone indicator. */ + space = strrchr(committer, ' '); + if (space == NULL) + return got_error(GOT_ERR_BAD_OBJ_DATA); + *space = '\0'; + + /* Timestamp is separated from committer name + email by space. */ + space = strrchr(committer, ' '); + if (space == NULL) + return got_error(GOT_ERR_BAD_OBJ_DATA); + + *time = strtonum(space + 1, 0, INT64_MAX, &errstr); + if (errstr) + return got_error(GOT_ERR_BAD_OBJ_DATA); + /* Strip off parsed time information, leaving just author and email. */ + *space = '\0'; return NULL; } @@ -521,6 +549,7 @@ parse_commit_object(struct got_commit_object **commit, tlen = strlen(GOT_COMMIT_TAG_AUTHOR); if (strncmp(s, GOT_COMMIT_TAG_AUTHOR, tlen) == 0) { char *p; + size_t slen; remain -= tlen; if (remain <= 0) { @@ -534,18 +563,23 @@ parse_commit_object(struct got_commit_object **commit, goto done; } *p = '\0'; + slen = strlen(s); + err = parse_commit_time(&(*commit)->author_time, s); + if (err) + goto done; (*commit)->author = strdup(s); if ((*commit)->author == NULL) { err = got_error_from_errno(); goto done; } - s += strlen((*commit)->author) + 1; - remain -= strlen((*commit)->author) + 1; + s += slen + 1; + remain -= slen + 1; } tlen = strlen(GOT_COMMIT_TAG_COMMITTER); if (strncmp(s, GOT_COMMIT_TAG_COMMITTER, tlen) == 0) { char *p; + size_t slen; remain -= tlen; if (remain <= 0) { @@ -559,13 +593,17 @@ parse_commit_object(struct got_commit_object **commit, goto done; } *p = '\0'; + slen = strlen(s); + err = parse_commit_time(&(*commit)->committer_time, s); + if (err) + goto done; (*commit)->committer = strdup(s); if ((*commit)->committer == NULL) { err = got_error_from_errno(); goto done; } - s += strlen((*commit)->committer) + 1; - remain -= strlen((*commit)->committer) + 1; + s += slen + 1; + remain -= slen + 1; } (*commit)->logmsg = strndup(s, remain); @@ -581,57 +619,6 @@ done: return err; } -static const struct got_error * -parse_commit_time(time_t *time, const char *author_str) -{ - const struct got_error *err = NULL; - const char *errstr; - char *committer, *space; - - *time = 0; - - committer = strdup(author_str); - if (committer == NULL) - return got_error_from_errno(); - - /* Strip off trailing timezone indicator. */ - space = strrchr(committer, ' '); - if (space == NULL) { - err = got_error(GOT_ERR_BAD_OBJ_DATA); - goto done; - } - *space = '\0'; - - /* Timestamp is separated from committer name + email by space. */ - space = strrchr(committer, ' '); - if (space == NULL) { - err = got_error(GOT_ERR_BAD_OBJ_DATA); - goto done; - } - - *time = strtonum(space + 1, 0, INT64_MAX, &errstr); - if (errstr) - err = got_error(GOT_ERR_BAD_OBJ_DATA); - -done: - free(committer); - return err; -} - -const struct got_error * -got_object_commit_get_committer_time(time_t *time, - struct got_commit_object *commit) -{ - return parse_commit_time(time, commit->committer); -} - -const struct got_error * -got_object_commit_get_author_time(time_t *time, - struct got_commit_object *commit) -{ - return parse_commit_time(time, commit->committer); -} - static void tree_entry_close(struct got_tree_entry *te) {