Commit Diff


commit - 55e9459f41acc72438ed2c9f75fdaeae8f5c41d8
commit + d8b5af438b16bcea5568b1d4bfc127567e35e2f6
blob - 8b9f4c059435abf6b351d2c9f180dd9926969528
blob + 8e99bbe74f6769ad1550cbcbe10d5ff1368d116d
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -613,6 +613,7 @@ struct got_imsg_patch {
 	int	git;
 	char	old[PATH_MAX];
 	char	new[PATH_MAX];
+	char	cid[41];
 	char	blob[41];
 };
 
blob - 9fbe2170f84b59a8c01710ada69f683bbfc91f38
blob + 9209e54ce7111b54b69980a44a48a92a333e5888
--- lib/patch.c
+++ lib/patch.c
@@ -73,6 +73,7 @@ STAILQ_HEAD(got_patch_hunk_head, got_patch_hunk);
 struct got_patch {
 	char	*old;
 	char	*new;
+	char	 cid[41];
 	char	 blob[41];
 	struct got_patch_hunk_head head;
 };
@@ -185,12 +186,16 @@ recv_patch(struct imsgbuf *ibuf, int *done, struct got
 
 	if (patch.old[sizeof(patch.old)-1] != '\0' ||
 	    patch.new[sizeof(patch.new)-1] != '\0' ||
+	    patch.cid[sizeof(patch.cid)-1] != '\0' ||
 	    patch.blob[sizeof(patch.blob)-1] != '\0') {
 		err = got_error(GOT_ERR_PRIVSEP_LEN);
 		goto done;
 	}
 
-	strlcpy(p->blob, patch.blob, sizeof(p->blob));
+	if (*patch.cid != '\0' && *patch.blob != '\0') {
+		strlcpy(p->cid, patch.cid, sizeof(p->cid));
+		strlcpy(p->blob, patch.blob, sizeof(p->blob));
+	}
 
 	/* automatically set strip=1 for git-style diffs */
 	if (strip == -1 && patch.git &&
@@ -624,7 +629,7 @@ apply_patch(int *overlapcnt, struct got_worktree *work
 {
 	const struct got_error *err = NULL;
 	int do_merge = 0, file_renamed = 0;
-	char *oldlabel = NULL, *newlabel = NULL;
+	char *oldlabel = NULL, *newlabel = NULL, *anclabel = NULL;
 	char *oldpath = NULL, *newpath = NULL;
 	char *tmppath = NULL, *template = NULL, *parent = NULL;
 	char *apath = NULL, *mergepath = NULL;
@@ -699,6 +704,12 @@ apply_patch(int *overlapcnt, struct got_worktree *work
 			goto done;
 		}
 
+		if (asprintf(&anclabel, "commit %s", p->cid) == -1) {
+			err = got_error_from_errno("asprintf");
+			anclabel = NULL;
+			goto done;
+		}
+
 		err = got_opentemp_named(&mergepath, &mergefile, template);
 		if (err)
 			goto done;
@@ -706,7 +717,7 @@ apply_patch(int *overlapcnt, struct got_worktree *work
 		outfd = fileno(mergefile);
 
 		err = got_merge_diff3(overlapcnt, outfd, tmpfile, afile,
-		    oldfile, oldlabel, p->blob, newlabel,
+		    oldfile, oldlabel, anclabel, newlabel,
 		    GOT_DIFF_ALGORITHM_PATIENCE);
 		if (err)
 			goto done;
@@ -794,6 +805,7 @@ done:
 	free(newpath);
 	free(oldlabel);
 	free(newlabel);
+	free(anclabel);
 	return err;
 }
 
blob - ba9f841f31f227976e27fe6dbd4cd56b5ae30699
blob + 5f1a2842034c7b2f4296aa5b45ca262a927c4a7a
--- libexec/got-read-patch/got-read-patch.c
+++ libexec/got-read-patch/got-read-patch.c
@@ -61,7 +61,8 @@
 struct imsgbuf ibuf;
 
 static const struct got_error *
-send_patch(const char *oldname, const char *newname, const char *blob, int git)
+send_patch(const char *oldname, const char *newname, const char *commitid,
+    const char *blob, int git)
 {
 	struct got_imsg_patch p;
 
@@ -73,8 +74,10 @@ send_patch(const char *oldname, const char *newname, c
 	if (newname != NULL)
 		strlcpy(p.new, newname, sizeof(p.new));
 
-	if (blob != NULL)
+	if (commitid != NULL && blob != NULL) {
+		strlcpy(p.cid, commitid, sizeof(p.cid));
 		strlcpy(p.blob, blob, sizeof(p.blob));
+	}
 
 	p.git = git;
 	if (imsg_compose(&ibuf, GOT_IMSG_PATCH, 0, 0, -1, &p, sizeof(p)) == -1)
@@ -150,7 +153,7 @@ find_patch(int *done, FILE *fp)
 {
 	const struct got_error *err = NULL;
 	char	*old = NULL, *new = NULL;
-	char	*blob = NULL;
+	char	*commitid = NULL, *blob = NULL;
 	char	*line = NULL;
 	size_t	 linesize = 0;
 	ssize_t	 linelen;
@@ -181,8 +184,13 @@ find_patch(int *done, FILE *fp)
 			rename = 1;
 		else if (!strncmp(line, "diff --git a/", 13)) {
 			git = 1;
+			free(commitid);
+			commitid = NULL;
 			free(blob);
 			blob = NULL;
+		} else if (!git && !strncmp(line, "diff ", 5)) {
+			free(commitid);
+			err = blobid(line + 5, &commitid);
 		}
 
 		if (err)
@@ -195,7 +203,8 @@ find_patch(int *done, FILE *fp)
 		 */
 		if (rename && old != NULL && new != NULL) {
 			*done = 1;
-			err = send_patch(old, new, blob, git);
+			err = send_patch(old, new, commitid,
+			    blob, git);
 			break;
 		}
 
@@ -205,7 +214,8 @@ find_patch(int *done, FILE *fp)
 			    (!create && old == NULL))
 				err = got_error(GOT_ERR_PATCH_MALFORMED);
 			else
-				err = send_patch(old, new, blob, git);
+				err = send_patch(old, new, commitid,
+				    blob, git);
 
 			if (err)
 				break;
@@ -219,6 +229,7 @@ find_patch(int *done, FILE *fp)
 
 	free(old);
 	free(new);
+	free(commitid);
 	free(blob);
 	free(line);
 	if (ferror(fp) && err == NULL)
blob - 6c9ee03971f22c84e0e5a023a0b18209a73bbdd8
blob + 20e899eab3a352dc9e8636b15e894c186595d20a
--- regress/cmdline/patch.sh
+++ regress/cmdline/patch.sh
@@ -1516,6 +1516,8 @@ test_patch_merge_conflict() {
 		test_done $testroot $ret
 		return 1
 	fi
+
+	local commit_id=`git_show_head $testroot/repo`
 
 	jot 10 | sed 's/6/six/g' > $testroot/wt/numbers
 
@@ -1555,7 +1557,7 @@ test_patch_merge_conflict() {
 	5
 	<<<<<<< --- numbers
 	six
-	||||||| f00c965d8307308469e537302baa73048488f162
+	||||||| commit $commit_id
 	6
 	=======
 	3+3