commit - e0e55b50ec1b9458bbd145dc18635a8a8265d4db
commit + 199a402734c6e8d1b44fd3f607459b9fb94e0cb0
blob - f51496b4e866a28f5c434c1c9224ea9a7986724f
blob + 587273c102a98dd8c5922774fd868a687ac32886
--- got/got.c
+++ got/got.c
static const struct got_error *
print_commit(struct got_commit_object *commit, struct got_object_id *id,
- struct got_repository *repo, int show_patch, int diff_context)
+ struct got_repository *repo, int show_patch, int diff_context,
+ struct got_reflist_head *refs)
{
const struct got_error *err = NULL;
char *id_str, *datestr, *logmsg0, *logmsg, *line;
char datebuf[26];
time_t committer_time;
const char *author, *committer;
+ char *refs_str = NULL;
+ struct got_reflist_entry *re;
+ SIMPLEQ_FOREACH(re, refs, entry) {
+ char *s;
+ const char *name;
+ if (got_object_id_cmp(re->id, id) != 0)
+ continue;
+ name = got_ref_get_name(re->ref);
+ if (strncmp(name, "refs/", 5) == 0)
+ name += 5;
+ s = refs_str;
+ if (asprintf(&refs_str, "%s%s%s", s ? s : "", s ? ", " : "",
+ name) == -1) {
+ err = got_error_from_errno();
+ free(s);
+ break;
+ }
+ free(s);
+ }
err = got_object_id_str(&id_str, id);
if (err)
return err;
printf("-----------------------------------------------\n");
- printf("commit %s\n", id_str);
+ printf("commit %s%s%s%s\n", id_str, refs_str ? " (" : "",
+ refs_str ? refs_str : "", refs_str ? ")" : "");
free(id_str);
printf("from: %s\n", got_object_commit_get_author(commit));
committer_time = got_object_commit_get_committer_time(commit);
static const struct got_error *
print_commits(struct got_object_id *root_id, struct got_repository *repo,
char *path, int show_patch, int diff_context, int limit,
- int first_parent_traversal)
+ int first_parent_traversal, struct got_reflist_head *refs)
{
const struct got_error *err;
struct got_commit_graph *graph;
err = got_object_open_as_commit(&commit, repo, id);
if (err)
break;
- err = print_commit(commit, id, repo, show_patch, diff_context);
+ err = print_commit(commit, id, repo, show_patch, diff_context,
+ refs);
got_object_commit_close(commit);
if (err || (limit && --limit == 0))
break;
int diff_context = 3, ch;
int show_patch = 0, limit = 0, first_parent_traversal = 0;
const char *errstr;
+ struct got_reflist_head refs;
#ifndef PROFILE
if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
free(path);
path = in_repo_path;
}
+
+ SIMPLEQ_INIT(&refs);
+ error = got_ref_list(&refs, repo);
+ if (error)
+ goto done;
error = print_commits(id, repo, path, show_patch,
- diff_context, limit, first_parent_traversal);
+ diff_context, limit, first_parent_traversal, &refs);
done:
free(path);
free(repo_path);
blob - 3845b3eb503de4c17e6c6393d03d9ed1d8294dcd
blob + 18c0c225b798cff70d3e761c60fdd025660ad701
--- include/got_reference.h
+++ include/got_reference.h
* The caller must dispose of it with free(3).
*/
char *got_ref_to_str(struct got_reference *);
+
+/* A list of references and the object ID which they resolve to. */
+struct got_reflist_entry {
+ SIMPLEQ_ENTRY(got_reflist_entry) entry;
+ struct got_reference *ref;
+ struct got_object_id *id;
+};
+SIMPLEQ_HEAD(got_reflist_head, got_reflist_entry);
+
+/* Append all known references to a caller-provided ref list head. */
+const struct got_error *got_ref_list(struct got_reflist_head *,
+ struct got_repository *);
blob - b10ac6f0ab6d2274599af6367b05460f121abe76
blob + 8cf17a7dc99101cfd244574281974a3b86e0d666
--- lib/reference.c
+++ lib/reference.c
if (!got_parse_sha1_digest(digest, line))
return got_error(GOT_ERR_NOT_REF);
- if (strcmp(line + SHA1_DIGEST_STRING_LENGTH, abs_refname) != 0)
- return NULL;
+ if (abs_refname) {
+ if (strcmp(line + SHA1_DIGEST_STRING_LENGTH, abs_refname) != 0)
+ return NULL;
- name = strdup(abs_refname);
- if (name == NULL)
- return got_error_from_errno();
+ name = strdup(abs_refname);
+ if (name == NULL)
+ return got_error_from_errno();
+ } else
+ name = strdup(line + SHA1_DIGEST_STRING_LENGTH);
*ref = calloc(1, sizeof(**ref));
if (*ref == NULL)
return ref->ref.symref.name;
return ref->ref.ref.name;
+}
+
+static const struct got_error *
+append_ref(struct got_reflist_head *refs, struct got_reference *ref,
+ struct got_repository *repo)
+{
+ const struct got_error *err;
+ struct got_object_id *id;
+ struct got_reflist_entry *entry;
+
+ err = got_ref_resolve(&id, repo, ref);
+ if (err)
+ return err;
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL)
+ return got_error_from_errno();
+ entry->ref = ref;
+ entry->id = id;
+ SIMPLEQ_INSERT_TAIL(refs, entry, entry);
+ return NULL;
}
+
+const struct got_error *
+got_ref_list(struct got_reflist_head *refs, struct got_repository *repo)
+{
+ const struct got_error *err;
+ char *packed_refs_path, *path_refs;
+ FILE *f;
+ struct got_reference *ref;
+
+ packed_refs_path = got_repo_get_path_packed_refs(repo);
+ if (packed_refs_path == NULL)
+ return got_error_from_errno();
+
+ f = fopen(packed_refs_path, "r");
+ free(packed_refs_path);
+ if (f) {
+ char *line;
+ size_t len;
+ const char delim[3] = {'\0', '\0', '\0'};
+ while (1) {
+ line = fparseln(f, &len, NULL, delim, 0);
+ if (line == NULL)
+ break;
+ err = parse_packed_ref_line(&ref, NULL, line);
+ if (err)
+ goto done;
+ if (ref)
+ append_ref(refs, ref, repo);
+ }
+ }
+
+ /* HEAD ref should always exist. */
+ path_refs = get_refs_dir_path(repo, GOT_REF_HEAD);
+ if (path_refs == NULL) {
+ err = got_error_from_errno();
+ goto done;
+ }
+ err = open_ref(&ref, path_refs, "", GOT_REF_HEAD);
+ free(path_refs);
+ if (err)
+ goto done;
+ append_ref(refs, ref, repo);
+
+done:
+ if (f)
+ fclose(f);
+ return err;
+}