Commit Diff


commit - 1fd6d7eaef8643842b590fd6ffeedb6058fae21b
commit + d1f2edc95ce19d76654b6ac6616fa33a9086540c
blob - 8ead4c57ca8473ba946ed37a8f7cd071e558e3c0
blob + 9e3a0907d01c5fcd10e75dbba0e903134f19fdc3
--- got/got.1
+++ 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
blob - 61a7b2a7f1aa2c2c00203f9f5cd92cd5180e5654
blob + 6319c20a471cb8961ca9f4fd5de83aeef380f174
--- got/got.c
+++ 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();
blob - 90e79b5d45614cce794d98450f5555c99fb41354
blob + 8336d486ab9d4e22fab6d158517d9809b5c84bbf
--- lib/reference.c
+++ 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 c
 	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_re
 	
 	/* 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;
 }