commit 484d974bd6540464db217df140323b4aab4086c3 from: Stefan Sperling via: Thomas Adam date: Tue Aug 29 16:20:40 2023 UTC prevent overlapping repo and work tree in 'got checkout' Some people are eager to try to make Got work just like Git by overlaying the repository and work tree. This causes problems with unveil conflicts at run-time. Fail as early as possible during 'got checkout' when users attempt this. cosmetic tweaks + ok op@ commit - ce775af4ec5a9b9c2ef8353bcc5a14f5ebc29658 commit + 484d974bd6540464db217df140323b4aab4086c3 blob - 881527d776040fc59c1fa690c545e87532dd42dd blob + 229b63afc1986fd42d2a2308bdf52502085a43f1 --- got/got.c +++ got/got.c @@ -3076,6 +3076,15 @@ cmd_checkout(int argc, char *argv[]) got_path_strip_trailing_slashes(repo_path); got_path_strip_trailing_slashes(worktree_path); + if (got_path_is_child(worktree_path, repo_path, strlen(repo_path)) || + got_path_is_child(repo_path, worktree_path, + strlen(worktree_path))) { + error = got_error_fmt(GOT_ERR_BAD_PATH, + "work tree and repository paths may not overlap: %s", + worktree_path); + goto done; + } + error = got_repo_pack_fds_open(&pack_fds); if (error != NULL) goto done; blob - 993c64afcbd5f4598770774738e513c4afb9387c blob + 642aa7ff0a7ff201dae5e22b59ce99b7e725eced --- regress/cmdline/checkout.sh +++ regress/cmdline/checkout.sh @@ -141,9 +141,77 @@ test_checkout_dir_not_empty() { ret=$? if [ $ret -ne 0 ]; then diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" + +} + +test_checkout_into_repo() { + local testroot=`test_init checkout_into_repo` + local commit_id=`git_show_head $testroot/repo` + + got checkout $testroot/repo $testroot/repo/wt \ + > $testroot/stdout 2> $testroot/stderr + ret=$? + if [ $ret -eq 0 ]; then + echo "checkout succeeded unexpectedly" >&2 + test_done "$testroot" "1" + return 1 + fi + + echo -n > $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo -n "got: work tree and repository paths may not overlap: " \ + > $testroot/stderr.expected + echo "$testroot/repo/wt: bad path" >> $testroot/stderr.expected + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr fi test_done "$testroot" "$ret" +} +test_checkout_overlap_repo() { + local testroot=`test_init checkout_into_repo` + local commit_id=`git_show_head $testroot/repo` + + got checkout $testroot/repo $testroot \ + > $testroot/stdout 2> $testroot/stderr + ret=$? + if [ $ret -eq 0 ]; then + echo "checkout succeeded unexpectedly" >&2 + test_done "$testroot" "1" + return 1 + fi + + echo -n > $testroot/stdout.expected + + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo -n "got: work tree and repository paths may not overlap: " \ + > $testroot/stderr.expected + echo "$testroot: bad path" >> $testroot/stderr.expected + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr + fi + test_done "$testroot" "$ret" } test_checkout_sets_xbit() { @@ -1010,6 +1078,8 @@ test_parseargs "$@" run_test test_checkout_basic run_test test_checkout_dir_exists run_test test_checkout_dir_not_empty +run_test test_checkout_into_repo +run_test test_checkout_overlap_repo run_test test_checkout_sets_xbit run_test test_checkout_commit_from_wrong_branch run_test test_checkout_tag