Commit d219f183308acdda359bff4261e6ff7cd249670f

Stefan Sperling 2020-07-23T14:22:34

test_cherrypick_symlink_conflicts forgot to run 'got add' on a file; fix this

diff --git a/lib/worktree.c b/lib/worktree.c
index 7468ff6..c1f8b7e 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -917,6 +917,13 @@ done:
 	return err;
 }
 
+/* forward declaration */
+static const struct got_error *
+merge_blob(int *, struct got_worktree *, struct got_blob_object *,
+    const char *, const char *, uint16_t, const char *,
+    struct got_blob_object *, struct got_object_id *,
+    struct got_repository *, got_worktree_checkout_cb, void *);
+
 /*
  * Merge a symlink into the work tree, where blob_orig acts as the common
  * ancestor, blob_deriv acts as the first derived version, and the symlink
@@ -943,6 +950,19 @@ merge_symlink(struct got_worktree *worktree,
 		return got_error_from_errno2("lstat", ondisk_path);
 
 	if (!S_ISLNK(sb.st_mode)) {
+		/*
+		 * If there is a regular file on disk, merge the symlink
+		 * target path into this file, which will usually cause
+		 * a merge conflict.
+		 */
+		if (S_ISREG(sb.st_mode)) {
+			int local_changes_subsumed;
+			return merge_blob(&local_changes_subsumed, worktree,
+			    NULL, ondisk_path, path, sb.st_mode, label_orig,
+			    blob_deriv, deriv_base_commit_id,
+			    repo, progress_cb, progress_arg);
+		}
+
 		/* TODO symlink is obstructed; do something */
 		return got_error_path(ondisk_path, GOT_ERR_FILE_OBSTRUCTED);
 	}
diff --git a/regress/cmdline/cherrypick.sh b/regress/cmdline/cherrypick.sh
index 2866695..0c33fc4 100755
--- a/regress/cmdline/cherrypick.sh
+++ b/regress/cmdline/cherrypick.sh
@@ -496,6 +496,7 @@ function test_cherrypick_symlink_conflicts {
 	(cd $testroot/wt && ln -sf .got/bar dotgotfoo.link)
 	# added bad symlink to file A vs added regular file A
 	echo 'this is regular file bar' > $testroot/wt/dotgotbar.link
+	(cd $testroot/wt && got add dotgotbar.link > /dev/null)
 	# removed symlink to non-existent file A vs modified symlink
 	# to nonexistent file B
 	(cd $testroot/wt && ln -sf nonexistent2 nonexistent.link)
@@ -513,14 +514,14 @@ function test_cherrypick_symlink_conflicts {
 	echo -n > $testroot/stdout.expected
 	echo "C  alpha.link" >> $testroot/stdout.expected
 	echo "C  epsilon/beta.link" >> $testroot/stdout.expected
-	echo "U  dotgotbar.link" >> $testroot/stdout.expected
+	echo "C  dotgotbar.link" >> $testroot/stdout.expected
 	echo "C  epsilon.link" >> $testroot/stdout.expected
 	echo "U  dotgotfoo.link" >> $testroot/stdout.expected
 	echo "D  nonexistent.link" >> $testroot/stdout.expected
 	echo "!  zeta.link" >> $testroot/stdout.expected
 	echo "C  new.link" >> $testroot/stdout.expected
 	echo "Merged commit $commit_id2" >> $testroot/stdout.expected
-	echo "Files with new merge conflicts: 4" >> $testroot/stdout.expected
+	echo "Files with new merge conflicts: 5" >> $testroot/stdout.expected
 	cmp -s $testroot/stdout.expected $testroot/stdout
 	ret="$?"
 	if [ "$ret" != "0" ]; then
@@ -662,7 +663,13 @@ EOF
 		test_done "$testroot" "1"
 		return 1
 	fi
-	echo -n ".got/bar" > $testroot/content.expected
+	echo "<<<<<<< merged change: commit $commit_id2" \
+		> $testroot/content.expected
+	echo -n ".got/bar" >> $testroot/content.expected
+	echo "=======" >> $testroot/content.expected
+	echo "this is regular file bar" >> $testroot/content.expected
+	echo '>>>>>>>' >> $testroot/content.expected
+	echo -n "" >> $testroot/content.expected
 	cp $testroot/wt/dotgotbar.link $testroot/content
 	cmp -s $testroot/content.expected $testroot/content
 	ret="$?"