"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
make 'got branch -d' consistent with 'got branch -l"
To:
gameoftrees@openbsd.org
Date:
Fri, 26 Feb 2021 19:36:43 +0100

Download raw body.

Thread
  • Stefan Sperling:

    make 'got branch -d' consistent with 'got branch -l"

Since got 0.49 'got branch -l' lists copies of remote branches which exist
under "refs/remotes/". This was done to make it easier for users to identify
valid arguments for 'got update -b'.

But 'got branch -d' still operates on "refs/heads" only.

My original idea was to rely on 'got ref -d' to delete copies of remote
branches. Attempting to delete a remote branch via 'got branch -d' gives
a 'reference not found' error which is now inconsistent with 'got branch -l'
since this command displays the remote branch.

So I'd like to allow deletion of remote branches via 'got branch -d'.

ok?

diff bc62ede807f0ad3a920fa1e8b05dd90cc8f5f289 /home/stsp/src/got
blob - 22cc9a1eba46d729c6f6890233b894a7d846f716
file + got/got.1
--- got/got.1
+++ got/got.1
@@ -983,7 +983,7 @@ Local branches are managed via references which live i
 reference namespace.
 The
 .Cm got branch
-command creates or deletes references in this namespace only.
+command will create 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.
@@ -1042,7 +1042,14 @@ with one the following annotations:
 .It \(a~ Ta work tree's base commit is out-of-date
 .El
 .It Fl d Ar name
-Delete the branch with the specified name from the repository.
+Delete the branch with the specified
+.Ar name
+from the repository.
+If this branch does not exist in the
+.Dq refs/heads/
+reference namespace, attempt to delete it from the
+.Dq refs/remotes/
+reference namespace instead.
 Only the branch reference is deleted.
 Any commit, tree, and blob objects belonging to the branch
 remain in the repository and may be removed separately with
blob - 9bcd279e5446ef8a890025dd5e3e16b3206fc66a
file + got/got.c
--- got/got.c
+++ got/got.c
@@ -5642,8 +5642,23 @@ delete_branch(struct got_repository *repo, struct got_
 		return got_error_from_errno("asprintf");
 
 	err = got_ref_open(&ref, repo, refname, 0);
-	if (err)
-		goto done;
+	if (err) {
+		if (err->code != GOT_ERR_NOT_REF)
+			goto done;
+		free(refname);
+		refname = NULL;
+		if (asprintf(&refname, "refs/remotes/%s", branch_name) == -1)
+			return got_error_from_errno("asprintf");
+		err = got_ref_open(&ref, repo, refname, 0);
+		if (err) {
+			if (err->code == GOT_ERR_NOT_REF) {
+				err = got_error_fmt(GOT_ERR_NOT_REF,
+				    "refs/heads/%s or refs/remotes/%s",
+				    branch_name, branch_name);
+			}
+			goto done;
+		}
+	}
 
 	if (worktree &&
 	    strcmp(got_worktree_get_head_ref_name(worktree),
blob - a766241048c3ca1094a34b2c4977c80ec15d69e5
file + regress/cmdline/branch.sh
--- regress/cmdline/branch.sh
+++ regress/cmdline/branch.sh
@@ -289,8 +289,11 @@ test_branch_delete() {
 		return 1
 	fi
 
-	echo "got: reference refs/heads/bogus_branch_name not found" \
-		> $testroot/stderr.expected
+	echo -n "got: refs/heads/bogus_branch_name " \
+		>> $testroot/stderr.expected
+	echo -n "or refs/remotes/bogus_branch_name: " \
+		>> $testroot/stderr.expected
+	echo "no such reference found" >> $testroot/stderr.expected
 	cmp -s $testroot/stderr $testroot/stderr.expected
 	ret="$?"
 	if [ "$ret" != "0" ]; then
@@ -382,8 +385,11 @@ test_branch_delete_packed() {
 		return 1
 	fi
 
-	echo "got: reference refs/heads/bogus_branch_name not found" \
-		> $testroot/stderr.expected
+	echo -n "got: refs/heads/bogus_branch_name " \
+		>> $testroot/stderr.expected
+	echo -n "or refs/remotes/bogus_branch_name: " \
+		>> $testroot/stderr.expected
+	echo "no such reference found" >> $testroot/stderr.expected
 	cmp -s $testroot/stderr $testroot/stderr.expected
 	ret="$?"
 	if [ "$ret" != "0" ]; then