Commit Diff


commit - aedda007f35a0820009e1463c9c804c6dea9acb1
commit + d83d9d5c431189537fc94c38a85ce2b8e3217f5d
blob - d986705a9c7adadbe5ec5065df26335ba048969d
blob + 73e69b62763151177576ecb1f0eeb510d635b994
--- got/got.1
+++ got/got.1
@@ -260,16 +260,17 @@ Show object IDs of files (blob objects) and directorie
 .It Fl R
 Recurse into sub-directories in the repository.
 .El
-.It Cm ref [ Fl r Ar repository-path ] [ Fl l ] [ Fl d Ar name ] [ Ar name Ar object ]
+.It Cm ref [ Fl r Ar repository-path ] [ Fl l ] [ Fl d Ar name ] [ Ar name Ar target ]
 Manage references in a repository.
 .Pp
 If no options are passed, expect two arguments and attempt to create,
 or update, the reference with the given
 .Ar name ,
 and make it point at the given
-.Ar object .
-The object argument is a SHA1 hash which corresponds to an existing
-object in the repository.
+.Ar target .
+The target may be a SHA1 hash which corresponds to an existing object ID
+in the repository, or an existing reference which will be resolved to an
+object ID.
 .Pp
 The options for
 .Cm got ref
@@ -373,6 +374,14 @@ Check out a work tree of
 kernel sources from a Git repository at /var/repo/openbsd-src to ~/sys:
 .Pp
 .Dl $ got checkout -p sys /var/repo/openbsd-src ~/sys
+.Pp
+Create a new branch
+.Dq mybranch
+which is forked off the
+.Dq master
+branch:
+.Pp
+.Dl $ got ref mybranch master
 .Sh SEE ALSO
 .Xr git-repository 5
 .Xr got-worktree 5
blob - 3ef3e75a562a7fdadd4e8d235c892780740d21f3
blob + 9469b96fcd7ac2544a6b09333dd519d5e111779e
--- got/got.c
+++ got/got.c
@@ -1735,7 +1735,7 @@ __dead static void
 usage_ref(void)
 {
 	fprintf(stderr,
-	    "usage: %s ref [-r repository] -l | -d name | name object\n",
+	    "usage: %s ref [-r repository] -l | -d name | name target\n",
 	    getprogname());
 	exit(1);
 }
@@ -1781,16 +1781,27 @@ delete_ref(struct got_repository *repo, const char *re
 }
 
 static const struct got_error *
-add_ref(struct got_repository *repo, const char *refname, const char *id_str)
+add_ref(struct got_repository *repo, const char *refname, const char *target)
 {
 	const struct got_error *err = NULL;
 	struct got_object_id *id;
 	struct got_reference *ref = NULL;
 
-	err = got_object_resolve_id_str(&id, repo, id_str);
-	if (err)
-		return err;
+	err = got_object_resolve_id_str(&id, repo, target);
+	if (err) {
+		struct got_reference *target_ref;
 
+		if (err->code != GOT_ERR_BAD_OBJ_ID_STR)
+			return err;
+		err = got_ref_open(&target_ref, repo, target, 0);
+		if (err)
+			return err;
+		err = got_ref_resolve(&id, repo, target_ref);
+		got_ref_close(target_ref);
+		if (err)
+			return err;
+	}
+
 	err = got_ref_alloc(&ref, refname, id);
 	if (err)
 		goto done;