commit c7d20a3f8da31a213c3830e6ca9de6d3b0c728bb from: Stefan Sperling date: Tue Jul 30 15:46:15 2019 UTC forbid editing the history of branches outside of "refs/heads" 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