Commit Diff


commit - ad18dfab1c13f15a03638c10db626a4f39827d95
commit + da165977d65c74af18c41b44f93df986324a66fe
blob - 2a5a6702d514b6a921362edba623fc8a3d056f46
blob + 0573efa2859ab011ad5cbc1139a11601aac58bf2
--- lib/reference.c
+++ lib/reference.c
@@ -1205,6 +1205,12 @@ got_ref_write(struct got_reference *ref, struct got_re
 	err = got_opentemp_named(&tmppath, &f, path, "");
 	if (err) {
 		char *parent;
+		if (err->code == GOT_ERR_ERRNO && errno == ENOTDIR) {
+			err = got_error_fmt(GOT_ERR_BAD_REF_NAME,
+			    "collision with an existing reference: %s",
+			    got_ref_get_name(ref));
+			goto done;
+		}
 		if (!(err->code == GOT_ERR_ERRNO && errno == ENOENT))
 			goto done;
 		err = got_path_dirname(&parent, path);
blob - 12ee9f0325d237ae1d8a5a962b5aa23fb7261605
blob + 64e5549700453bd0afc70a70e8b3e31c3cde21db
--- regress/cmdline/ref.sh
+++ regress/cmdline/ref.sh
@@ -170,12 +170,45 @@ test_ref_create() {
 		test_done "$testroot" "$ret"
 		return 1
 	fi
+
+	# Create a ref with a / in its name
+	got ref -r $testroot/repo -c $commit_id refs/heads/commit/ref
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		echo "got ref command failed unexpectedly"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	# Create a ref with a name that collides with a file
+	got ref -r $testroot/repo -c $commit_id refs/heads/commitref/new \
+		2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "got ref command succeeded unexpectedly"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n "got: collision with an existing reference: " \
+		> $testroot/stderr.expected
+	echo "refs/heads/commitref/new: bad reference name" \
+		>> $testroot/stderr.expected
+	cmp -s $testroot/stderr $testroot/stderr.expected
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	
 	got ref -r $testroot/repo -l > $testroot/stdout
 	echo "HEAD: refs/heads/newref" > $testroot/stdout.expected
 	echo -n "refs/got/worktree/base-" >> $testroot/stdout.expected
 	cat $testroot/wt/.got/uuid | tr -d '\n' >> $testroot/stdout.expected
 	echo ": $commit_id" >> $testroot/stdout.expected
 	echo "refs/heads/anotherref: $commit_id" >> $testroot/stdout.expected
+	echo "refs/heads/commit/ref: $commit_id" >> $testroot/stdout.expected
 	echo "refs/heads/commitref: $commit_id" >> $testroot/stdout.expected
 	echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
 	echo "refs/heads/newref: $commit_id" >> $testroot/stdout.expected