commit - 1fd6d7eaef8643842b590fd6ffeedb6058fae21b
commit + d1f2edc95ce19d76654b6ac6616fa33a9086540c
blob - 8ead4c57ca8473ba946ed37a8f7cd071e558e3c0
blob + 9e3a0907d01c5fcd10e75dbba0e903134f19fdc3
--- got/got.1
+++ got/got.1
.It Fl c Ar commit
Start traversing history at the specified
.Ar commit .
-The expected argument is the SHA1 hash which corresponds to the commit object.
+The expected argument is the name of a branch or a SHA1 hash which corresponds
+to the commit object.
.It Fl l Ar N
Limit history traversal to a given number of commits.
.It Fl f
blob - 61a7b2a7f1aa2c2c00203f9f5cd92cd5180e5654
blob + 6319c20a471cb8961ca9f4fd5de83aeef380f174
--- got/got.c
+++ got/got.c
const struct got_error *error;
struct got_repository *repo;
struct got_object_id *id = NULL;
- struct got_object *obj;
+ struct got_object *obj = NULL;
char *repo_path = NULL;
char *start_commit = NULL;
int ch;
return error;
error = got_object_open(&obj, repo, id);
} else {
- error = got_object_open_by_id_str(&obj, repo, start_commit);
+ struct got_reference *ref;
+ error = got_ref_open(&ref, repo, start_commit);
if (error == NULL) {
+ error = got_ref_resolve(&id, repo, ref);
+ got_ref_close(ref);
+ if (error != NULL)
+ return error;
+ error = got_object_open(&obj, repo, id);
+ if (error != NULL)
+ return error;
+ }
+ if (obj == NULL) {
+ error = got_object_open_by_id_str(&obj, repo,
+ start_commit);
+ if (error != NULL)
+ return error;
id = got_object_get_id(obj);
if (id == NULL)
error = got_error_from_errno();
blob - 90e79b5d45614cce794d98450f5555c99fb41354
blob + 8336d486ab9d4e22fab6d158517d9809b5c84bbf
--- lib/reference.c
+++ lib/reference.c
#include "got_lib_zbuf.h"
#include "got_lib_object.h"
+#define GOT_REF_HEADS "heads"
+#define GOT_REF_TAGS "tags"
+#define GOT_REF_REMOTES "remotes"
+
/* A symbolic reference. */
struct got_symref {
char *name;
return got_repo_get_path_refs(repo);
}
+static const struct got_error *
+open_ref(struct got_reference **ref, const char *path_refs, const char *subdir,
+ const char *refname)
+{
+ const struct got_error *err = NULL;
+ char *path_ref;
+ char *normpath;
+
+ if (asprintf(&path_ref, "%s/%s/%s", path_refs, subdir, refname) == -1)
+ return got_error_from_errno();
+
+ normpath = got_path_normalize(path_ref);
+ if (normpath == NULL) {
+ err = got_error(GOT_ERR_NOT_REF);
+ goto done;
+ }
+
+ err = parse_ref_file(ref, refname, normpath);
+done:
+ free(path_ref);
+ free(normpath);
+ return err;
+}
+
const struct got_error *
got_ref_open(struct got_reference **ref, struct got_repository *repo,
const char *refname)
{
const struct got_error *err = NULL;
- char *path_ref = NULL;
- char *normpath = NULL;
char *path_refs = get_refs_dir_path(repo, refname);
if (path_refs == NULL) {
/* XXX For now, this assumes that refs exist in the filesystem. */
- if (asprintf(&path_ref, "%s/%s", path_refs, refname) == -1) {
- err = got_error_from_errno();
- goto done;
- }
-
- normpath = got_path_normalize(path_ref);
- if (normpath == NULL) {
- err = got_error(GOT_ERR_NOT_REF);
- goto done;
- }
-
- err = parse_ref_file(ref, refname, normpath);
+ err = open_ref(ref, path_refs, GOT_REF_HEADS, refname);
+ if (err != NULL)
+ err = open_ref(ref, path_refs, GOT_REF_TAGS, refname);
+ if (err != NULL)
+ err = open_ref(ref, path_refs, GOT_REF_REMOTES, refname);
+ if (err != NULL)
+ err = open_ref(ref, path_refs, "", refname);
done:
- free(normpath);
- free(path_ref);
free(path_refs);
return err;
}