commit e31abbf21f99a7312bdfd392f33ace285feadfe5 from: Stefan Sperling date: Sun Mar 22 14:21:06 2020 UTC add -c option to 'got ref' which now expects just one argument after options commit - 255c4055a2c4c323dace71509df44c6b59ddd819 commit + e31abbf21f99a7312bdfd392f33ace285feadfe5 blob - 62fe17b1245763f96d147bf56f10249beae43dc3 blob + 59cc0bc74ca2f04ba3df6a2dc55756f8e29edde5 --- got/got.1 +++ got/got.1 @@ -821,20 +821,15 @@ Recurse into sub-directories in the repository. .It Cm tr Short alias for .Cm tree . -.It Cm ref Oo Fl r Ar repository-path Oc Oo Fl l Oc Oo Fl d Ar name Oc Oo Fl s Oc Op Ar name Ar target +.It Cm ref Oo Fl r Ar repository-path Oc Oo Fl l Oc Oo Fl c Ar object Oc Oo Fl s Ar reference Oc Oo Fl d Oc Op Ar name Manage references in a repository. .Pp -If no options are passed, expect two arguments and attempt to create, -or update, the reference with the given -.Ar name , -and make it point at the given -.Ar target . -The name must be an absolute reference name, i.e. it must begin with +References may be listed, created, deleted, and changed. +When creating, deleting, or changing a reference the specified +.Ar name +must be an absolute reference name, i.e. it must begin with .Dq refs/ . -The target may be an object ID SHA1 hash or an existing reference which -will be resolved to an object ID. -An abbreviated hash argument will be expanded to a full SHA1 hash -automatically, provided the abbreviation is unique. +.Pp .Pp The options for .Cm got ref @@ -849,14 +844,37 @@ If this directory is a work tree, use the repository path associated with this work tree. .It Fl l List all existing references in the repository. -.It Fl d Ar name -Delete the reference with the specified name from the repository. -.It Fl s -Create a symbolic reference pointing at the specified -.Ar target , -which must be an existing reference. +Cannot be used together with any other options except +.Fl r . +.It Fl c Ar object +Create a reference or change an existing reference. +The reference with the specified +.Ar name +will point at the specified +.Ar object. +The expected +.Ar object +argument is a ID SHA1 hash or an existing reference or tag name which will +be resolved to the ID of a corresponding commit, tree, tag, or blob object. +Cannot be used together with any other options except +.Fl r . +.It Fl s Ar reference +Create a symbolic reference, or change an existing symbolic reference. +The symbolic reference with the specified +.Ar name +will point at the specified +.Ar reference +which must already exist in the repository. Care should be taken not to create loops between references when this option is used. +Cannot be used together with any other options except +.Fl r . +.It Fl d +Delete the reference with the specified +.Ar name +from the repository. +Cannot be used together with any other options except +.Fl r . .El .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 Oo Fl n Oc Op Ar name Create, list, or delete branches. blob - cebadef7f168d056f60bdde3f2eae62abb1e79b6 blob + b27ba046f77b825e22827ab64329341daa4b767b --- got/got.c +++ got/got.c @@ -4175,7 +4175,8 @@ __dead static void usage_ref(void) { fprintf(stderr, - "usage: %s ref [-r repository] -l | -d name | [-s] name target\n", + "usage: %s ref [-r repository] [-l] [-c object] [-s reference] " + "[-d] [name]\n", getprogname()); exit(1); } @@ -4302,14 +4303,16 @@ cmd_ref(int argc, char *argv[]) struct got_repository *repo = NULL; struct got_worktree *worktree = NULL; char *cwd = NULL, *repo_path = NULL; - int ch, do_list = 0, create_symref = 0; - const char *delref = NULL; + int ch, do_list = 0, do_delete = 0; + const char *refname = NULL, *obj_arg = NULL, *symref_target= NULL; - /* TODO: Add -s option for adding symbolic references. */ - while ((ch = getopt(argc, argv, "d:r:ls")) != -1) { + while ((ch = getopt(argc, argv, "c:dr:ls:")) != -1) { switch (ch) { + case 'c': + obj_arg = optarg; + break; case 'd': - delref = optarg; + do_delete = 1; break; case 'r': repo_path = realpath(optarg, NULL); @@ -4322,7 +4325,7 @@ cmd_ref(int argc, char *argv[]) do_list = 1; break; case 's': - create_symref = 1; + symref_target = optarg; break; default: usage_ref(); @@ -4330,20 +4333,30 @@ cmd_ref(int argc, char *argv[]) } } - if (do_list && delref) - errx(1, "-l and -d options are mutually exclusive\n"); + if (obj_arg && do_list) + errx(1, "-c and -l options are mutually exclusive\n"); + if (obj_arg && do_delete) + errx(1, "-c and -d options are mutually exclusive\n"); + if (obj_arg && symref_target) + errx(1, "-c and -s options are mutually exclusive\n"); + if (symref_target && do_delete) + errx(1, "-s and -d options are mutually exclusive\n"); + if (symref_target && do_list) + errx(1, "-s and -l options are mutually exclusive\n"); + if (do_delete && do_list) + errx(1, "-d and -l options are mutually exclusive\n"); argc -= optind; argv += optind; - if (do_list || delref) { - if (create_symref) - errx(1, "-s option cannot be used together with the " - "-l or -d options"); + if (do_list) { if (argc > 0) usage_ref(); - } else if (argc != 2) - usage_ref(); + } else { + if (argc != 1) + usage_ref(); + refname = argv[0]; + } #ifndef PROFILE if (do_list) { @@ -4395,12 +4408,15 @@ cmd_ref(int argc, char *argv[]) if (do_list) error = list_refs(repo); - else if (delref) - error = delete_ref(repo, delref); - else if (create_symref) - error = add_symref(repo, argv[0], argv[1]); - else - error = add_ref(repo, argv[0], argv[1]); + else if (do_delete) + error = delete_ref(repo, refname); + else if (symref_target) + error = add_symref(repo, refname, symref_target); + else { + if (obj_arg == NULL) + usage_ref(); + error = add_ref(repo, refname, obj_arg); + } done: if (repo) got_repo_close(repo); blob - f3a8329ac8336d70b30d8bb5d62f5fa383572eba blob + 446d7b73e9428139a538555e3c55ae5786cb6eb8 --- regress/cmdline/clone.sh +++ regress/cmdline/clone.sh @@ -93,7 +93,7 @@ function test_clone_list { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null got clone -l $testurl/repo > $testroot/stdout 2>$testroot/stderr @@ -121,7 +121,7 @@ function test_clone_branch { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -157,7 +157,7 @@ function test_clone_all { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -195,7 +195,7 @@ function test_clone_mirror { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -230,7 +230,7 @@ function test_clone_mirror_all { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -265,7 +265,7 @@ function test_clone_reference { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -302,7 +302,7 @@ function test_clone_branch_and_reference { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -339,7 +339,7 @@ function test_clone_reference_mirror { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` blob - fbf48ee5570790ff88f8e64e0c4f1a1aab82289f blob + a131681c03b7c5c023fa5603baf9b704a0bc4779 --- regress/cmdline/commit.sh +++ regress/cmdline/commit.sh @@ -499,7 +499,7 @@ function test_commit_selected_paths { function test_commit_outside_refs_heads { local testroot=`test_init commit_outside_refs_heads` - got ref -r $testroot/repo refs/remotes/origin/master master + got ref -r $testroot/repo -c master refs/remotes/origin/master got checkout -b refs/remotes/origin/master \ $testroot/repo $testroot/wt > /dev/null blob - b59b39ef20a710f192c51ed6560b8c1b58bb3e67 blob + fb811d10678197846f753b9591a2ea121483ebc1 --- regress/cmdline/fetch.sh +++ regress/cmdline/fetch.sh @@ -123,7 +123,7 @@ function test_fetch_list { local commit_id=`git_show_head $testroot/repo` got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null got clone -q $testurl/repo $testroot/repo-clone @@ -168,7 +168,7 @@ function test_fetch_branch { fi got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -271,7 +271,7 @@ function test_fetch_all { fi got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -337,7 +337,7 @@ function test_fetch_empty_packfile { fi got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got ref -l -r $testroot/repo-clone > $testroot/stdout @@ -390,7 +390,7 @@ function test_fetch_delete_branch { got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -497,7 +497,7 @@ function test_fetch_update_tag { got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -656,7 +656,7 @@ function test_fetch_reference { fi got branch -r $testroot/repo -c $commit_id foo - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null local tag_id=`got ref -r $testroot/repo -l \ | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` @@ -741,8 +741,8 @@ function test_fetch_replace_symref { return 1 fi - got ref -r $testroot/repo refs/hoo/boo/zoo $commit_id - got ref -r $testroot/repo-clone -s refs/hoo/boo/zoo refs/heads/master + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo + got ref -r $testroot/repo-clone -s refs/heads/master refs/hoo/boo/zoo got ref -l -r $testroot/repo-clone > $testroot/stdout blob - d85840618184c07990545e7fc5f807ff54e29b6b blob + a2bae29b0a70794309a14b5440419d30c4ff9cc0 --- regress/cmdline/histedit.sh +++ regress/cmdline/histedit.sh @@ -1086,7 +1086,7 @@ function test_histedit_outside_refs_heads { fi local commit2=`git_show_head $testroot/repo` - got ref -r $testroot/repo refs/remotes/origin/master master + got ref -r $testroot/repo -c master refs/remotes/origin/master ret="$?" if [ "$ret" != "0" ]; then echo "got ref failed unexpectedly" >&2 blob - 262922a8781a97382dedbb832e92a3f68736454d blob + 7423d96b389d81dc4599fdcc9579c42cf945db16 --- regress/cmdline/rebase.sh +++ regress/cmdline/rebase.sh @@ -819,9 +819,8 @@ function test_rebase_forward { # commit ffcffcd102cf1af6572fbdbb4cf07a0f1fd2d840 (master) # commit 87a6a8a2263a15b61c016ff1720b24741d455eb5 (cd $testroot/repo && got ref -d master) - (cd $testroot/repo && got ref refs/heads/master $commit1) - (cd $testroot/repo && got ref refs/remotes/origin/master $commit2) - + (cd $testroot/repo && got ref -c $commit1 refs/heads/master) + (cd $testroot/repo && got ref -c $commit2 refs/remotes/origin/master) (cd $testroot/wt && got up -b origin/master > /dev/null) blob - 50b3132f130ff87c2a04152bb8ed0a243a817079 blob + 94736443ecd38ab37cc59e7464129a48092a6a72 --- regress/cmdline/ref.sh +++ regress/cmdline/ref.sh @@ -20,8 +20,8 @@ function test_ref_create { local testroot=`test_init ref_create` local commit_id=`git_show_head $testroot/repo` - # Create a ref based on a commit ID - got ref -r $testroot/repo refs/heads/commitref $commit_id + # Create a ref pointing at a commit ID + got ref -r $testroot/repo -c $commit_id refs/heads/commitref ret="$?" if [ "$ret" != "0" ]; then echo "got ref command failed unexpectedly" @@ -30,7 +30,7 @@ function test_ref_create { fi # Create a ref based on repository's HEAD reference - got ref -r $testroot/repo refs/heads/newref HEAD + got ref -r $testroot/repo -c HEAD refs/heads/newref ret="$?" if [ "$ret" != "0" ]; then echo "got ref command failed unexpectedly" @@ -57,7 +57,7 @@ function test_ref_create { fi # Create a head ref based on another specific ref - (cd $testroot/wt && got ref refs/heads/anotherref refs/heads/master) + (cd $testroot/wt && got ref -c refs/heads/master refs/heads/anotherref) ret="$?" if [ "$ret" != "0" ]; then test_done "$testroot" "$ret" @@ -72,7 +72,7 @@ function test_ref_create { fi # Create a symbolic ref - (cd $testroot/wt && got ref -s refs/heads/symbolicref refs/heads/master) + (cd $testroot/wt && got ref -s refs/heads/master refs/heads/symbolicref) ret="$?" if [ "$ret" != "0" ]; then test_done "$testroot" "$ret" @@ -88,7 +88,7 @@ function test_ref_create { fi # Attempt to create a symbolic ref pointing at a non-reference - (cd $testroot/wt && got ref -s refs/heads/symbolicref $commit_id \ + (cd $testroot/wt && got ref -s $commit_id refs/heads/symbolicref \ 2> $testroot/stderr) ret="$?" if [ "$ret" == "0" ]; then @@ -106,8 +106,45 @@ function test_ref_create { return 1 fi + # Attempt to create a reference without specifying a name + (cd $testroot/wt && got ref -c $commit_id 2> $testroot/stderr) + ret="$?" + if [ "$ret" == "0" ]; then + echo "git ref command succeeded unexpectedly" + test_done "$testroot" "1" + return 1 + fi + + grep -q '^usage: got ref' $testroot/stderr + ret="$?" + if [ "$ret" != "0" ]; then + echo "unexpected usage error message: " >&2 + cat $testroot/stderr >&2 + test_done "$testroot" "$ret" + return 1 + fi + + # Attempt to create a symbolic reference without specifying a name + (cd $testroot/wt && got ref -s refs/heads/symbolicref \ + 2> $testroot/stderr) + ret="$?" + if [ "$ret" == "0" ]; then + echo "git ref command succeeded unexpectedly" + test_done "$testroot" "1" + return 1 + fi + + grep -q '^usage: got ref' $testroot/stderr + ret="$?" + if [ "$ret" != "0" ]; then + echo "unexpected usage error message: " >&2 + cat $testroot/stderr >&2 + test_done "$testroot" "$ret" + return 1 + fi + # Change HEAD - got ref -r $testroot/repo -s HEAD refs/heads/newref + got ref -r $testroot/repo -s refs/heads/newref HEAD ret="$?" if [ "$ret" != "0" ]; then echo "got ref command failed unexpectedly" @@ -156,7 +193,7 @@ function test_ref_delete { local commit_id=`git_show_head $testroot/repo` for b in ref1 ref2 ref3; do - got ref -r $testroot/repo refs/heads/$b refs/heads/master + got ref -r $testroot/repo -c refs/heads/master refs/heads/$b ret="$?" if [ "$ret" != "0" ]; then echo "got ref command failed unexpectedly" @@ -165,7 +202,7 @@ function test_ref_delete { fi done - got ref -d refs/heads/ref2 -r $testroot/repo > $testroot/stdout + got ref -d -r $testroot/repo refs/heads/ref2 > $testroot/stdout ret="$?" if [ "$ret" != "0" ]; then echo "got ref command failed unexpectedly" @@ -186,7 +223,7 @@ function test_ref_delete { return 1 fi - got ref -d refs/heads/bogus_ref_name -r $testroot/repo \ + got ref -r $testroot/repo -d refs/heads/bogus_ref_name \ > $testroot/stdout 2> $testroot/stderr ret="$?" if [ "$ret" == "0" ]; then