allow creating branches based on commit IDs as well as other branch references
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
diff --git a/got/got.1 b/got/got.1
index ffc4d07..977bfb4 100644
--- a/got/got.1
+++ b/got/got.1
@@ -475,7 +475,7 @@ which must be an existing reference.
Care should be taken not to create loops between references when
this option is used.
.El
-.It Cm branch Oo Fl r Ar repository-path Oc Oo Fl l Oc Oo Fl d Ar name Oc Op Ar name Op Ar base-branch
+.It Cm branch Oo Fl r Ar repository-path Oc Oo Fl l Oc Oo Fl d Ar name Oc Op Ar name Op Ar commit
Manage branches in a repository.
.Pp
Branches are managed via references which live in the
@@ -486,14 +486,19 @@ The
command operates on references in this namespace only.
.Pp
If no options are passed, expect one or two arguments and attempt to create
-a branch with the given
+a branch reference with the given
.Ar name ,
and make it point at the given
-.Ar base-branch .
+.Ar commit .
+The expected
+.Ar commit
+argument is a commit ID SHA1 hash or an existing reference
+or tag name which will be resolved to a commit ID.
If no
-.Ar base-branch
-is specified, default to the work tree's current branch if invoked in a
-work tree, or to the repository's HEAD reference.
+.Ar commit
+is specified, default to the latest commit on the work tree's current
+branch if invoked in a work tree, or to a commit resolved via the
+repository's HEAD reference.
.Pp
The options for
.Cm got branch
diff --git a/got/got.c b/got/got.c
index 7daf89c..c5f0c6c 100644
--- a/got/got.c
+++ b/got/got.c
@@ -3056,7 +3056,7 @@ usage_branch(void)
{
fprintf(stderr,
"usage: %s branch [-r repository] -l | -d name | "
- "name [base-branch]\n", getprogname());
+ "name [commit]\n", getprogname());
exit(1);
}
@@ -3140,9 +3140,9 @@ add_branch(struct got_repository *repo, const char *branch_name,
{
const struct got_error *err = NULL;
struct got_object_id *id = NULL;
+ char *label;
struct got_reference *ref = NULL;
char *base_refname = NULL, *refname = NULL;
- struct got_reference *base_ref;
/*
* Don't let the user create a branch named '-'.
@@ -3152,20 +3152,10 @@ add_branch(struct got_repository *repo, const char *branch_name,
if (branch_name[0] == '-' && branch_name[1] == '\0')
return got_error(GOT_ERR_BAD_REF_NAME);
- if (strcmp(GOT_REF_HEAD, base_branch) == 0) {
- base_refname = strdup(GOT_REF_HEAD);
- if (base_refname == NULL)
- return got_error_from_errno("strdup");
- } else if (asprintf(&base_refname, "refs/heads/%s", base_branch) == -1)
- return got_error_from_errno("asprintf");
-
- err = got_ref_open(&base_ref, repo, base_refname, 0);
- if (err)
- goto done;
- err = got_ref_resolve(&id, repo, base_ref);
- got_ref_close(base_ref);
+ err = match_object_id(&id, &label, base_branch,
+ GOT_OBJ_TYPE_COMMIT, 1, repo);
if (err)
- goto done;
+ return err;
if (asprintf(&refname, "refs/heads/%s", branch_name) == -1) {
err = got_error_from_errno("asprintf");
diff --git a/regress/cmdline/branch.sh b/regress/cmdline/branch.sh
index a2f5c35..3b0f39a 100755
--- a/regress/cmdline/branch.sh
+++ b/regress/cmdline/branch.sh
@@ -85,6 +85,24 @@ function test_branch_create {
ret="$?"
if [ "$ret" != "0" ]; then
echo "git checkout command failed unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # Create a branch based on a specific commit
+ local commit_id=`git_show_head $testroot/repo`
+ got branch -r $testroot/repo commitbranch $commit_id
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got branch command failed unexpectedly"
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/repo && git checkout -q commitbranch)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "git checkout command failed unexpectedly"
fi
test_done "$testroot" "$ret"
}