Commit Diff


commit - dc5351b4fbeb55371ddf6f812d68c69bc0d478a7
commit + c7d20a3f8da31a213c3830e6ca9de6d3b0c728bb
blob - a51741ea3cbb45eb1054f40cd523bc9424f65c71
blob + ee870b09516306986d2a13d443fcf472fc660796
--- got/got.1
+++ got/got.1
@@ -769,6 +769,9 @@ when the histedit operation continues.
 .Pp
 .Cm got histedit
 will refuse to run if certain preconditions are not met.
+If the work tree's current branch is not in the
+.Dq refs/heads/
+reference namespace, the history of the branch may not be edited.
 If the work tree contains multiple base commits it must first be updated
 to a single base commit with
 .Cm got update .
blob - e2cf6617507de8f326679a36e7832faa921be073
blob + 5356c711e7abf7966e72e3a0a0103d74754fdaf0
--- got/got.c
+++ got/got.c
@@ -4956,6 +4956,13 @@ cmd_histedit(int argc, char *argv[])
 		if (error != NULL)
 			goto done;
 
+		if (strncmp(got_ref_get_name(branch), "refs/heads/", 11) != 0) {
+			error = got_error_msg(GOT_ERR_COMMIT_BRANCH,
+			    "will not edit commit history of a branch outside "
+			    "the \"refs/heads/\" reference namespace");
+			goto done;
+		}
+
 		error = got_ref_resolve(&head_commit_id, repo, branch);
 		got_ref_close(branch);
 		branch = NULL;
blob - 4c729979b61fca24ee6cdbb560160e5bb7b2a289
blob + a859ac4534eef54f7e371c66660a85d84e6dca9c
--- regress/cmdline/histedit.sh
+++ regress/cmdline/histedit.sh
@@ -1038,7 +1038,63 @@ function test_histedit_path_prefix_edit {
 	fi
 	test_done "$testroot" "$ret"
 }
+
+function test_histedit_outside_refs_heads {
+	local testroot=`test_init histedit_outside_refs_heads`
+	local commit1=`git_show_head $testroot/repo`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got checkout failed unexpectedly"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo "modified alpha" > $testroot/wt/alpha
+
+	(cd $testroot/wt && got commit -m 'change alpha' \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got commit failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+	local commit2=`git_show_head $testroot/repo`
 
+	got ref -r $testroot/repo refs/remotes/origin/master master
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got ref failed unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	(cd $testroot/wt && got update -b origin/master -c $commit1 >/dev/null)
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		echo "got update failed unexpectedly"
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo "edit $commit2" > $testroot/histedit-script
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		2> $testroot/stderr)
+
+	echo -n "got: will not edit commit history of a branch outside the " \
+		> $testroot/stderr.expected
+	echo '"refs/heads/" reference namespace' \
+		>> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+	fi
+	test_done "$testroot" "$ret"
+}
+
 run_test test_histedit_no_op
 run_test test_histedit_swap
 run_test test_histedit_drop
@@ -1049,3 +1105,4 @@ run_test test_histedit_missing_commit
 run_test test_histedit_abort
 run_test test_histedit_path_prefix_drop
 run_test test_histedit_path_prefix_edit
+run_test test_histedit_outside_refs_heads