got patch: create missing directories when adding files ok stsp@
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
diff --git a/lib/patch.c b/lib/patch.c
index 8fc9edf..58d4125 100644
--- a/lib/patch.c
+++ b/lib/patch.c
@@ -595,7 +595,7 @@ apply_patch(struct got_worktree *worktree, struct got_repository *repo,
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_repository *repo,
}
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_repository *repo,
done:
if (err != NULL && newpath != NULL && (file_renamed || p->old == NULL))
unlink(newpath);
+ free(parent);
free(template);
if (tmppath != NULL)
unlink(tmppath);
diff --git a/regress/cmdline/patch.sh b/regress/cmdline/patch.sh
index 6d468d0..92f950f 100755
--- a/regress/cmdline/patch.sh
+++ b/regress/cmdline/patch.sh
@@ -1008,6 +1008,47 @@ EOF
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 <<EOF > $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
+}
+
test_parseargs "$@"
run_test test_patch_simple_add_file
run_test test_patch_simple_rm_file
@@ -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