commit - ee85c5e898e10f72841c918d9f453a6526ef7e2e
commit + 4b6c9460c99283f193f32bd5177bb09047abacf3
blob - 05a4896a63a16b4b11b02defcba785a8a2b95b14
blob + ed10056f87241ad9aa4d28d8c5fc24f1fb04f15f
--- got/got.1
+++ got/got.1
automatically, provided the abbreviation is unique.
If this option is not specified, the most recent commit on the selected
branch will be used.
+.Pp
+If the specified
+.Ar commit
+is not contained in the selected branch, a different branch which contains
+this commit must be specified with the
+.Fl b
+option.
+If no such branch is known a new branch must be created for this
+commit with
+.Cm got branch
+before
+.Cm got checkout
+can be used.
+Checking out work trees with an unknown branch is intentionally not supported.
.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 - 021418d817308d0e1fea429b3210b838b1a14ab3
blob + fc50380bc4c0fb4752f3e1718c004c136733c2e4
--- got/got.c
+++ got/got.c
}
static const struct got_error *
+checkout_ancestry_error(struct got_reference *ref, const char *commit_id_str)
+{
+ static char msg[512];
+ const char *branch_name;
+
+ if (got_ref_is_symbolic(ref))
+ branch_name = got_ref_get_symref_target(ref);
+ else
+ branch_name = got_ref_get_name(ref);
+
+ if (strncmp("refs/heads/", branch_name, 11) == 0)
+ branch_name += 11;
+
+ snprintf(msg, sizeof(msg),
+ "target commit is not contained in branch '%s'; "
+ "the branch to use must be specified with -b; "
+ "if necessary a new branch can be created for "
+ "this commit with 'got branch -c %s BRANCH_NAME'",
+ branch_name, commit_id_str);
+
+ return got_error_msg(GOT_ERR_ANCESTRY, msg);
+}
+
+static const struct got_error *
cmd_checkout(int argc, char *argv[])
{
const struct got_error *error = NULL;
got_worktree_get_base_commit_id(worktree), 0, repo);
if (error != NULL) {
free(commit_id);
+ if (error->code == GOT_ERR_ANCESTRY) {
+ error = checkout_ancestry_error(
+ head_ref, commit_id_str);
+ }
goto done;
}
error = check_same_branch(commit_id, head_ref, NULL, repo);
- if (error)
+ if (error) {
+ if (error->code == GOT_ERR_ANCESTRY) {
+ error = checkout_ancestry_error(
+ head_ref, commit_id_str);
+ }
goto done;
+ }
error = got_worktree_set_base_commit_id(worktree, repo,
commit_id);
free(commit_id);
blob - 6859b9bab3ac0176db628a98074b484d5b80364b
blob + 6d3a99a2cce157075a82450a18aaa39d48615932
--- regress/cmdline/checkout.sh
+++ regress/cmdline/checkout.sh
return 1
fi
- echo "got: target commit is on a different branch" \
+ echo -n "got: target commit is not contained in branch 'master'; " \
> $testroot/stderr.expected
+ echo -n "the branch to use must be specified with -b; if necessary " \
+ >> $testroot/stderr.expected
+ echo -n "a new branch can be created for this commit with "\
+ >> $testroot/stderr.expected
+ echo "'got branch -c $head_rev BRANCH_NAME'" \
+ >> $testroot/stderr.expected
cmp -s $testroot/stderr.expected $testroot/stderr
ret="$?"
if [ "$ret" != "0" ]; then