Thread (23 messages) 23 messages, 3 authors, 2016-06-15
STALE3759d

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

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:48:26
Subsystem: the rest · Maintainer: Linus Torvalds

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 [off-list ref]
Signed-off-by: Jonathan Nieder <redacted>
---
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help