commit a74f7e836f1414f6c06fca610a6231e37c1e68fd from: Stefan Sperling date: Sun Nov 10 11:33:13 2019 UTC add -c option to 'got branch', replacing the optional second argument commit - 6dd1ece69a673273a872d5fb39eb97fc593a6f47 commit + a74f7e836f1414f6c06fca610a6231e37c1e68fd blob - 84fbdf46212019d1180049f41ff6f024f3848b6d blob + 9320a0971ee4f04fb9c3ff5cda31e6ceae91d2ea --- got/got.1 +++ 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 blob - 3a3fb516b76cb9ed59e3a1cd223e1f0d2b0fdd9c blob + 3b8935895b310dbf4148cef5f6f4b5722e0369ba --- got/got.c +++ 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; @@ -3430,11 +3428,6 @@ add_branch(struct got_repository *repo, const char *br */ 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"); @@ -3448,7 +3441,7 @@ add_branch(struct got_repository *repo, const char *br } 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 *br 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) blob - 05f7d1c68bc1b11636a716791ffe719b6799e6b7 blob + 2a7d11efbed29670e6e1ba9db1450f174a74d399 --- regress/cmdline/branch.sh +++ 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"