add -c option to 'got branch', replacing the optional second argument
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
diff --git a/got/got.1 b/got/got.1
index 84fbdf4..9320a09 100644
--- a/got/got.1
+++ b/got/got.1
@@ -509,7 +509,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 commit
+.It Cm branch Oo Fl c Ar commit Oc Oo Fl r Ar repository-path Oc Oo Fl l Oc Oo Fl d Ar name Oc Op Ar name
Manage branches in a repository.
.Pp
Branches are managed via references which live in the
@@ -521,25 +521,24 @@ command operates on references in this namespace only.
.Pp
If invoked in a work tree without any arguments, print the name of the
work tree's current branch.
-If one or two arguments are passed, attempt to create a branch reference
-with the given
-.Ar name ,
-and make it point at the given
-.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 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.
+If a
+.Ar name
+argument is passed, attempt to create a branch reference with the given name.
+By default the new branch reference will point at the latest commit on the
+work tree's current branch if invoked in a work tree, and otherwise to a commit
+resolved via the repository's HEAD reference.
.Pp
The options for
.Cm got branch
are as follows:
.Bl -tag -width Ds
+.It Fl c Ar commit
+Make a newly created branch reference point at the specified
+.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.
.It Fl r Ar repository-path
Use the repository at the specified path.
If not specified, assume the repository is located at or above the current
diff --git a/got/got.c b/got/got.c
index 3a3fb51..3b89358 100644
--- a/got/got.c
+++ b/got/got.c
@@ -3275,8 +3275,8 @@ __dead static void
usage_branch(void)
{
fprintf(stderr,
- "usage: %s branch [-r repository] [-l] | -d name | "
- "[name [commit]]\n", getprogname());
+ "usage: %s branch [-c commit] [-r repository] [-l] | -d name | "
+ "[name]\n", getprogname());
exit(1);
}
@@ -3415,11 +3415,9 @@ done:
static const struct got_error *
add_branch(struct got_repository *repo, const char *branch_name,
- const char *base_branch)
+ struct got_object_id *base_commit_id)
{
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;
@@ -3431,11 +3429,6 @@ add_branch(struct got_repository *repo, const char *branch_name,
if (branch_name[0] == '-' && branch_name[1] == '\0')
return got_error_path(branch_name, GOT_ERR_BAD_REF_NAME);
- err = match_object_id(&id, &label, base_branch,
- GOT_OBJ_TYPE_COMMIT, 1, repo);
- if (err)
- return err;
-
if (asprintf(&refname, "refs/heads/%s", branch_name) == -1) {
err = got_error_from_errno("asprintf");
goto done;
@@ -3448,7 +3441,7 @@ add_branch(struct got_repository *repo, const char *branch_name,
} else if (err->code != GOT_ERR_NOT_REF)
goto done;
- err = got_ref_alloc(&ref, refname, id);
+ err = got_ref_alloc(&ref, refname, base_commit_id);
if (err)
goto done;
@@ -3456,7 +3449,6 @@ add_branch(struct got_repository *repo, const char *branch_name,
done:
if (ref)
got_ref_close(ref);
- free(id);
free(base_refname);
free(refname);
return err;
@@ -3470,10 +3462,13 @@ cmd_branch(int argc, char *argv[])
struct got_worktree *worktree = NULL;
char *cwd = NULL, *repo_path = NULL;
int ch, do_list = 0, do_show = 0;
- const char *delref = NULL;
+ const char *delref = NULL, *commit_id_arg = NULL;
- while ((ch = getopt(argc, argv, "d:r:l")) != -1) {
+ while ((ch = getopt(argc, argv, "c:d:r:l")) != -1) {
switch (ch) {
+ case 'c':
+ commit_id_arg = optarg;
+ break;
case 'd':
delref = optarg;
break;
@@ -3502,10 +3497,13 @@ cmd_branch(int argc, char *argv[])
if (!do_list && !delref && argc == 0)
do_show = 1;
+ if ((do_list || delref || do_show) && commit_id_arg != NULL)
+ errx(1, "-c option can only be used when creating a branch");
+
if (do_list || delref) {
if (argc > 0)
usage_branch();
- } else if (!do_show && (argc < 1 || argc > 2))
+ } else if (!do_show && argc != 1)
usage_branch();
#ifndef PROFILE
@@ -3563,16 +3561,16 @@ cmd_branch(int argc, char *argv[])
else if (delref)
error = delete_branch(repo, worktree, delref);
else {
- const char *base_branch;
- if (argc == 1) {
- base_branch = worktree ?
+ struct got_object_id *commit_id;
+ if (commit_id_arg == NULL)
+ commit_id_arg = worktree ?
got_worktree_get_head_ref_name(worktree) :
GOT_REF_HEAD;
- if (strncmp(base_branch, "refs/heads/", 11) == 0)
- base_branch += 11;
- } else
- base_branch = argv[1];
- error = add_branch(repo, argv[0], base_branch);
+ error = resolve_commit_arg(&commit_id, commit_id_arg, repo);
+ if (error)
+ goto done;
+ error = add_branch(repo, argv[0], commit_id);
+ free(commit_id);
}
done:
if (repo)
diff --git a/regress/cmdline/branch.sh b/regress/cmdline/branch.sh
index 05f7d1c..2a7d11e 100755
--- a/regress/cmdline/branch.sh
+++ b/regress/cmdline/branch.sh
@@ -74,7 +74,7 @@ function test_branch_create {
fi
# Create a branch based on another specific branch
- (cd $testroot/wt && got branch yetanotherbranch master)
+ (cd $testroot/wt && got branch -c master yetanotherbranch)
ret="$?"
if [ "$ret" != "0" ]; then
test_done "$testroot" "$ret"
@@ -91,7 +91,7 @@ function test_branch_create {
# Create a branch based on a specific commit
local commit_id=`git_show_head $testroot/repo`
- got branch -r $testroot/repo commitbranch $commit_id
+ got branch -r $testroot/repo -c $commit_id commitbranch
ret="$?"
if [ "$ret" != "0" ]; then
echo "got branch command failed unexpectedly"