Commit Diff


commit - 9c6338c4052d0127c812ecc3bd4a5ddde55ba2f0
commit + 2b92fad7804791e1a20f46acf637ff4c40470e50
blob - b8cd1a35b2873cdfc9028574e37bfc42cb5eb67a
blob + c120894f1b10c13a0d054b4f168f3adbb37416f9
--- got/got.1
+++ got/got.1
@@ -389,7 +389,9 @@ Show the status of each affected file, using the follo
 .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
blob - 1174e671c3ad58acfbc94422a2a09de5b3e23229
blob + 5dbd06969f53eeda039f83786a72a2a24d10e5bf
--- include/got_worktree.h
+++ 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.
blob - bf46d7caa36ff6b6f886316e5eb111732546b6d5
blob + fdfbe63d3229efeafcbb07acd0ca22befe78d0cb
--- lib/worktree.c
+++ 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:
blob - 8dca3386160a47f20341cf47880b79c3f8c2692c
blob + 4aa318fad89c144214430910ededa9950ba25d64
--- regress/cmdline/cherrypick.sh
+++ 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"
 }