test and fix expected file status after 'got cherrypick'
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118
diff --git a/got/got.1 b/got/got.1
index b8cd1a3..c120894 100644
--- a/got/got.1
+++ b/got/got.1
@@ -389,7 +389,9 @@ Show the status of each affected file, using the following status codes:
.It C Ta file was merged and conflicts occurred during merge
.It ! Ta changes destined for a missing file were not merged
.It D Ta file was deleted
+.It d Ta file's deletion was obstructed by local modifications
.It A Ta new file was added
+.It ~ Ta changes destined for a non-regular file were not merged
.El
.Pp
The merged changes will appear as local changes in the work tree, which
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 1174e67..5dbd069 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -30,6 +30,7 @@ struct got_commitable;
#define GOT_STATUS_UNVERSIONED '?'
#define GOT_STATUS_OBSTRUCTED '~'
#define GOT_STATUS_REVERT 'R'
+#define GOT_STATUS_CANNOT_DELETE 'd'
/*
* Attempt to initialize a new work tree on disk.
diff --git a/lib/worktree.c b/lib/worktree.c
index bf46d7c..fdfbe63 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1730,8 +1730,44 @@ merge_file_cb(void *arg, struct got_blob_object *blob1,
path2);
return NULL;
}
- err = delete_blob(a->worktree, a->fileindex, ie, repo,
- a->progress_cb, a->progress_arg);
+
+ if (asprintf(&ondisk_path, "%s/%s", a->worktree->root_path,
+ path1) == -1)
+ return got_error_from_errno("asprintf");
+
+ err = get_file_status(&status, &sb, ie, ondisk_path, repo);
+ if (err)
+ goto done;
+
+ switch (status) {
+ case GOT_STATUS_NO_CHANGE:
+ (*a->progress_cb)(a->progress_arg, GOT_STATUS_DELETE,
+ path1);
+ err = remove_ondisk_file(a->worktree->root_path, path1);
+ if (err)
+ goto done;
+ if (ie)
+ got_fileindex_entry_mark_deleted_from_disk(ie);
+ break;
+ case GOT_STATUS_DELETE:
+ case GOT_STATUS_MISSING:
+ (*a->progress_cb)(a->progress_arg, GOT_STATUS_DELETE,
+ path1);
+ if (ie)
+ got_fileindex_entry_mark_deleted_from_disk(ie);
+ break;
+ case GOT_STATUS_ADD:
+ case GOT_STATUS_MODIFY:
+ case GOT_STATUS_CONFLICT:
+ (*a->progress_cb)(a->progress_arg,
+ GOT_STATUS_CANNOT_DELETE, path1);
+ break;
+ case GOT_STATUS_OBSTRUCTED:
+ (*a->progress_cb)(a->progress_arg, status, path1);
+ break;
+ default:
+ break;
+ }
} else if (blob2) {
if (asprintf(&ondisk_path, "%s/%s", a->worktree->root_path,
path2) == -1)
@@ -1769,11 +1805,15 @@ merge_file_cb(void *arg, struct got_blob_object *blob1,
a->progress_cb, a->progress_arg);
if (err)
goto done;
-
- err = update_blob_fileindex_entry(a->worktree,
- a->fileindex, NULL, ondisk_path, path2, blob2, 0);
+ err = got_fileindex_entry_alloc(&ie,
+ ondisk_path, path2, NULL, NULL);
if (err)
goto done;
+ err = got_fileindex_entry_add(a->fileindex, ie);
+ if (err) {
+ got_fileindex_entry_free(ie);
+ goto done;
+ }
}
}
done:
diff --git a/regress/cmdline/cherrypick.sh b/regress/cmdline/cherrypick.sh
index 8dca338..4aa318f 100755
--- a/regress/cmdline/cherrypick.sh
+++ b/regress/cmdline/cherrypick.sh
@@ -79,6 +79,17 @@ function test_cherrypick_basic {
return 1
fi
+ echo 'M alpha' > $testroot/stdout.expected
+ echo 'D beta' >> $testroot/stdout.expected
+ echo 'A epsilon/new' >> $testroot/stdout.expected
+
+ (cd $testroot/wt && got status > $testroot/stdout)
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
test_done "$testroot" "$ret"
}