make 'got log -c' accept a branch name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
diff --git a/got/got.1 b/got/got.1
index 8ead4c5..9e3a090 100644
--- a/got/got.1
+++ b/got/got.1
@@ -106,7 +106,8 @@ Display the patch of modifications made in each commit.
.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
diff --git a/got/got.c b/got/got.c
index 61a7b2a..6319c20 100644
--- a/got/got.c
+++ b/got/got.c
@@ -438,7 +438,7 @@ cmd_log(int argc, char *argv[])
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;
@@ -502,8 +502,22 @@ cmd_log(int argc, char *argv[])
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();
diff --git a/lib/reference.c b/lib/reference.c
index 90e79b5..8336d48 100644
--- a/lib/reference.c
+++ b/lib/reference.c
@@ -35,6 +35,10 @@
#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;
@@ -153,13 +157,35 @@ get_refs_dir_path(struct got_repository *repo, const char *refname)
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) {
@@ -169,21 +195,14 @@ got_ref_open(struct got_reference **ref, struct got_repository *repo,
/* 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;
}