Commit Diff


commit - 8d301dd94ca3964729aa83b8031e7502a1111f49
commit + 08573d5b25f67f49eebace9318c417f8d384ab10
blob - b395b0e16bd20defe533b90d41b218dde97c723b
blob + fe652787be00cc913d2c8b2aea7b0a18025407f1
--- got/got.1
+++ got/got.1
@@ -60,7 +60,7 @@ The commands for
 .Nm
 are as follows:
 .Bl -tag -width checkout
-.It Cm checkout [ Fl c Ar commit ] [ Fl p Ar path-prefix ] repository-path [ work-tree-path ]
+.It Cm checkout [ Fl b Ar branch ] [ Fl c Ar commit ] [ Fl p Ar path-prefix ] repository-path [ work-tree-path ]
 Copy files from a repository into a new work tree.
 If the
 .Ar work tree path
@@ -75,11 +75,16 @@ The options for
 .Cm got checkout
 are as follows:
 .Bl -tag -width Ds
+.It Fl b Ar branch
+Check out files from the specified
+.Ar branch .
+If this option is not specified, a branch resolved via the repository's HEAD
+reference will be used.
 .It Fl c Ar commit
 Check out files from the specified
 .Ar commit .
-If this option is not specified, a commit resolved via the repository's HEAD
-reference will be used.
+If this option is not specified, the most recent commit on the selected
+branch will be used.
 .It Fl p Ar path-prefix
 Restrict the work tree to a subset of the repository's tree hierarchy.
 Only files beneath the specified
blob - dcd21cd3c3334dd5c39e8c4ef4908d903ae8478d
blob + 6196ec8e1aee73ae1e808d8789afab3b6a6a8f03
--- got/got.c
+++ got/got.c
@@ -271,8 +271,8 @@ apply_unveil(const char *repo_path, int repo_read_only
 __dead static void
 usage_checkout(void)
 {
-	fprintf(stderr, "usage: %s checkout [-p prefix] repository-path "
-	    "[worktree-path]\n", getprogname());
+	fprintf(stderr, "usage: %s checkout [-b branch] [-c commit] "
+	    "[-p prefix] repository-path [worktree-path]\n", getprogname());
 	exit(1);
 }
 
@@ -348,11 +348,15 @@ cmd_checkout(int argc, char *argv[])
 	char *repo_path = NULL;
 	char *worktree_path = NULL;
 	const char *path_prefix = "";
+	const char *branch_name = GOT_REF_HEAD;
 	char *commit_id_str = NULL;
 	int ch, same_path_prefix;
 
-	while ((ch = getopt(argc, argv, "c:p:")) != -1) {
+	while ((ch = getopt(argc, argv, "b:c:p:")) != -1) {
 		switch (ch) {
+		case 'b':
+			branch_name = optarg;
+			break;
 		case 'c':
 			commit_id_str = strdup(optarg);
 			if (commit_id_str == NULL)
@@ -434,7 +438,7 @@ cmd_checkout(int argc, char *argv[])
 	if (error)
 		goto done;
 
-	error = got_ref_open(&head_ref, repo, GOT_REF_HEAD, 0);
+	error = got_ref_open(&head_ref, repo, branch_name, 0);
 	if (error != NULL)
 		goto done;
 
blob - c6e5bb6cbe9b53419ce886ccea0a6899b78ca368
blob + 674f852d118ec5c1e19ba14a93ab7f8731b9a8a4
--- lib/worktree.c
+++ lib/worktree.c
@@ -257,10 +257,18 @@ got_worktree_init(const char *path, struct got_referen
 		goto done;
 
 	/* Write the HEAD reference. */
-	refstr = got_ref_to_str(head_ref);
-	if (refstr == NULL) {
-		err = got_error_from_errno("got_ref_to_str");
-		goto done;
+	if (got_ref_is_symbolic(head_ref)) {
+		refstr = got_ref_to_str(head_ref);
+		if (refstr == NULL) {
+			err = got_error_from_errno("got_ref_to_str");
+			goto done;
+		}
+	} else {
+		refstr = strdup(got_ref_get_name(head_ref));
+		if (refstr == NULL) {
+			err = got_error_from_errno("strdup");
+			goto done;
+		}
 	}
 	err = create_meta_file(path_got, GOT_WORKTREE_HEAD_REF, refstr);
 	if (err)