commit 95d683408adee5188de396567e8e9746b703d7dd from: Omar Polo date: Wed Mar 16 18:23:03 2022 UTC got patch: create missing directories when adding files ok stsp@ commit - 2be5e1a234aeec2c4e8d6b84f0405034ed8664fa commit + 95d683408adee5188de396567e8e9746b703d7dd blob - 8fc9edf2163e5db80ebfc2641f66fd8d288fa8bd blob + 58d4125553be6fd56d2408805b9c001d9c08c698 --- lib/patch.c +++ lib/patch.c @@ -595,7 +595,7 @@ apply_patch(struct got_worktree *worktree, struct got_ const struct got_error *err = NULL; struct got_pathlist_head oldpaths, newpaths; int file_renamed = 0; - char *oldpath = NULL, *newpath = NULL; + char *oldpath = NULL, *newpath = NULL, *parent = NULL; char *tmppath = NULL, *template = NULL; FILE *tmp = NULL; mode_t mode = GOT_DEFAULT_FILE_MODE; @@ -650,8 +650,23 @@ apply_patch(struct got_worktree *worktree, struct got_ } if (rename(tmppath, newpath) == -1) { - err = got_error_from_errno3("rename", tmppath, newpath); - goto done; + if (errno != ENOENT) { + err = got_error_from_errno3("rename", tmppath, + newpath); + goto done; + } + + err = got_path_dirname(&parent, newpath); + if (err != NULL) + goto done; + err = got_path_mkdir(parent); + if (err != NULL) + goto done; + if (rename(tmppath, newpath) == -1) { + err = got_error_from_errno3("rename", tmppath, + newpath); + goto done; + } } if (file_renamed) { @@ -670,6 +685,7 @@ apply_patch(struct got_worktree *worktree, struct got_ done: if (err != NULL && newpath != NULL && (file_renamed || p->old == NULL)) unlink(newpath); + free(parent); free(template); if (tmppath != NULL) unlink(tmppath); blob - 6d468d0334318dc22a5552f720bf777276c909d8 blob + 92f950fb6b4fb18338a3b9edcd4318445564b3e7 --- regress/cmdline/patch.sh +++ regress/cmdline/patch.sh @@ -1003,8 +1003,49 @@ EOF if [ ! -x $testroot/wt/alpha ]; then echo "alpha is no more executable!" >&2 test_done $testroot 1 + return 1 + fi + test_done $testroot 0 +} + +test_patch_create_dirs() { + local testroot=`test_init patch_create_dirs` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret + return 1 + fi + + cat < $testroot/wt/patch +--- /dev/null ++++ iota/kappa/lambda +@@ -0,0 +1 @@ ++lambda +EOF + + (cd $testroot/wt && got patch patch) > $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + test_done $testroot $ret return 1 fi + + echo 'A iota/kappa/lambda' >> $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 + + if [ ! -f $testroot/wt/iota/kappa/lambda ]; then + echo "file not created!" >&2 + test_done $testroot $ret + return 1 + fi test_done $testroot 0 } @@ -1024,3 +1065,4 @@ run_test test_patch_rename run_test test_patch_illegal_status run_test test_patch_nop run_test test_patch_preserve_perm +run_test test_patch_create_dirs