[PATCH 15/16] cherry-pick: add a label for ancestor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



git cherry-pick and git revert will write conflict hunks something
like what ‘diff3 -m’ produces if the merge.conflictstyle configuration
option is set to diff3.  Unlike ‘diff3 -m’, though, the output lacks a
label for the merge base on the ||||||| line of the output.

Some tools can misparse the conflict hunks without such a label.
Especially in a cherry-pick, humans parsing the conflict hunks by hand
might want to know what the common ancestor represents, too.  Add a
label.

Example:

	<<<<<<< HEAD
	Something old.
	Something new.
	Something rotten.
	Something blue.
	||||||| parent of 387924c... Remove something rotten
	Something old.
	Something rotten.
	Something blue.
	=======
	Something old.
	something blue.
	>>>>>>> 387924c... Remove something rotten

git rerere does not have trouble parsing the new output, and its
preimage ids are unchanged since it includes its own code for
recreating conflict hunks.  No other code in git parses conflict
hunks.

Requested-by: Stefan Monnier <monnier@xxxxxxxxxxxxxxxx>
Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx>
---
Hopefully the new labels clearer, especially when reverting a commit.
Thoughts?

 builtin/revert.c                |   27 ++++++++++++++++-----------
 t/t3507-cherry-pick-conflict.sh |    4 ++--
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/builtin/revert.c b/builtin/revert.c
index 56f2947..7a39b52 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -73,11 +73,11 @@ static void parse_args(int argc, const char **argv)
 		exit(1);
 }
 
-static char *get_oneline(const char *message, int revert, char **body)
+static char *get_oneline(const char *message, char **body, char **parent)
 {
 	char *result, *q;
-	const char *p = message, *prefix, *abbrev, *eol;
-	int prefix_len, abbrev_len, oneline_len;
+	const char *p = message, *abbrev, *eol;
+	int abbrev_len, oneline_len;
 
 	if (!p)
 		die ("Could not read commit message of %s",
@@ -91,14 +91,12 @@ static char *get_oneline(const char *message, int revert, char **body)
 			; /* do nothing */
 	} else
 		eol = p;
-	prefix = revert ? "parent of " : "";
-	prefix_len = revert ? strlen("parent of ") : 0;
 	abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
 	abbrev_len = strlen(abbrev);
 	oneline_len = eol - p;
-	q = result = xmalloc(prefix_len + abbrev_len +
-			     strlen("... ") + oneline_len + 1);
-	q = mempcpy(q, prefix, prefix_len);
+	*parent = q = xmalloc(strlen("parent of ") + abbrev_len +
+			      strlen("... ") + oneline_len + 1);
+	result = q = mempcpy(q, "parent of ", strlen("parent of "));
 	q = mempcpy(q, abbrev, abbrev_len);
 	*body = q = mempcpy(q, "... ", strlen("... "));
 	q = mempcpy(q, p, oneline_len);
@@ -252,8 +250,10 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 {
 	unsigned char head[20];
 	struct commit *base, *next, *parent;
+	const char *base_label, *next_label;
 	int i, index_fd, clean;
-	char *oneline, *oneline_body, *reencoded_message = NULL;
+	char *oneline, *oneline_body, *parent_label;
+	char *reencoded_message = NULL;
 	const char *message, *encoding;
 	char *defmsg = git_pathdup("MERGE_MSG");
 	struct merge_options o;
@@ -345,11 +345,13 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 					git_commit_encoding, encoding)))
 		message = reencoded_message;
 
-	oneline = get_oneline(message, action == REVERT, &oneline_body);
+	oneline = get_oneline(message, &oneline_body, &parent_label);
 
 	if (action == REVERT) {
 		base = commit;
+		base_label = oneline;
 		next = parent;
+		next_label = parent_label;
 		add_to_msg("Revert \"");
 		add_to_msg(oneline_body);
 		add_to_msg("\"\n\nThis reverts commit ");
@@ -362,7 +364,9 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 		add_to_msg(".\n");
 	} else {
 		base = parent;
+		base_label = parent_label;
 		next = commit;
+		next_label = oneline;
 		set_author_ident_env(message);
 		add_message_to_msg(message);
 		if (no_replay) {
@@ -374,8 +378,9 @@ static int revert_or_cherry_pick(int argc, const char **argv)
 
 	read_cache();
 	init_merge_options(&o);
+	o.ancestor = base ? base_label : "(empty tree)";
 	o.branch1 = "HEAD";
-	o.branch2 = oneline;
+	o.branch2 = next ? next_label : "(empty tree)";
 
 	head_tree = parse_tree_indirect(head);
 	next_tree = next ? next->tree : empty_tree();
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 6a20817..e25cf80 100644
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -112,7 +112,7 @@ test_expect_success 'diff3 -m style' '
 	cat <<-EOF > expected &&
 	<<<<<<< HEAD
 	a
-	|||||||
+	||||||| parent of objid picked
 	b
 	=======
 	c
@@ -179,7 +179,7 @@ test_expect_success 'revert conflict, diff3 -m style' '
 	cat <<-EOF > expected &&
 	<<<<<<< HEAD
 	a
-	|||||||
+	||||||| objid picked
 	c
 	=======
 	b
-- 
1.7.0

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]