Commit Diff


commit - cb3903e15309ab902714d7e03c1c04dabb8b28a0
commit + 2a104ff6e79d3ac7369f542553c609d2b15f1a55
blob - 3c1a9f793f1eb8b28119371b7fa20185f44b8316
blob + 1e9c2329c7868b58ee5e319672ef807b8c84c77e
--- lib/reference.c
+++ lib/reference.c
@@ -1333,17 +1333,14 @@ done:
 	return err ? err : unlock_err;
 }
 
-const struct got_error *
-got_ref_delete(struct got_reference *ref, struct got_repository *repo)
+static const struct got_error *
+delete_loose_ref(struct got_reference *ref, struct got_repository *repo)
 {
 	const struct got_error *err = NULL, *unlock_err = NULL;
 	const char *name = got_ref_get_name(ref);
 	char *path_refs = NULL, *path = NULL;
 	struct got_lockfile *lf = NULL;
 
-	if (ref->flags & GOT_REF_IS_PACKED)
-		return delete_packed_ref(ref, repo);
-
 	path_refs = get_refs_dir_path(repo, name);
 	if (path_refs == NULL) {
 		err = got_error_from_errno2("get_refs_dir_path", name);
@@ -1372,6 +1369,45 @@ done:
 	free(path_refs);
 	free(path);
 	return err ? err : unlock_err;
+}
+
+const struct got_error *
+got_ref_delete(struct got_reference *ref, struct got_repository *repo)
+{
+	const struct got_error *err = NULL;
+	struct got_reference *ref2;
+
+	if (ref->flags & GOT_REF_IS_PACKED) {
+		err = delete_packed_ref(ref, repo);
+		if (err)
+			return err;
+
+		err = got_ref_open(&ref2, repo, got_ref_get_name(ref), 1);
+		if (err) {
+			if (err->code == GOT_ERR_NOT_REF)
+				return NULL;
+			return err;
+		}
+
+		err = delete_loose_ref(ref2, repo);
+		got_ref_close(ref2);
+		return err;
+	} else {
+		err = delete_loose_ref(ref, repo);
+		if (err)
+			return err;
+
+		err = got_ref_open(&ref2, repo, got_ref_get_name(ref), 1);
+		if (err) {
+			if (err->code == GOT_ERR_NOT_REF)
+				return NULL;
+			return err;
+		}
+
+		err = delete_packed_ref(ref2, repo);
+		got_ref_close(ref2);
+		return err;
+	}
 }
 
 const struct got_error *
blob - 62f1dd6e5f84d9b1600f2331d03b9654474d14e1
blob + 5a2b0f63e102cbd3386aaf8e158af7b55f76e5f9
--- regress/cmdline/ref.sh
+++ regress/cmdline/ref.sh
@@ -238,7 +238,41 @@ test_ref_delete() {
 	ret="$?"
 	if [ "$ret" != "0" ]; then
 		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/repo && git pack-refs --all)
+
+	echo "modified alpha" > $testroot/repo/alpha
+	git_commit $testroot/repo -m "modified alpha"
+	local commit_id2=`git_show_head $testroot/repo`
+
+	# ref 'master' now exists in both packed and loose forms
+
+	got ref -l -r $testroot/repo > $testroot/stdout
+	echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+	echo "refs/heads/master: $commit_id2" >> $testroot/stdout.expected
+	echo "refs/heads/ref1: $commit_id" >> $testroot/stdout.expected
+	echo "refs/heads/ref3: $commit_id" >> $testroot/stdout.expected
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
 	fi
+
+	got ref -r $testroot/repo -d master
+
+	got ref -l -r $testroot/repo > $testroot/stdout
+	echo "refs/heads/ref1: $commit_id" > $testroot/stdout.expected
+	echo "refs/heads/ref3: $commit_id" >> $testroot/stdout.expected
+	cmp -s $testroot/stdout $testroot/stdout.expected
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
 	test_done "$testroot" "$ret"
 }