git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Mar 17, 2010, 12:23 UTC
Message-ID
<20100317122314.GO25641@progeny.tock>
In-Reply-To
<20100317113655.GA25470@progeny.tock>

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@iro.umontreal.ca>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
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
Previous: Jonathan NiederNext: Jonathan Nieder
Message 22 of 23 in “Add label for common ancestor to conflictstyle=diff3”
  1. 0/16 Add label for common ancestor to conflictstyle=diff3Jonathan Nieder, Mar 17, 2010
  2. 01/16 xdl_merge(): add optional ancestor label to diff3-style outputJonathan Nieder, Mar 17, 2010
  3. Bert WesargMar 17, 2010
  4. Jonathan NiederMar 20, 2010
  5. 02/16 xdl_merge(): move file1 and file2 labels to xmparam structureJonathan Nieder, Mar 17, 2010
  6. 03/16 merge-file --diff3: add a label for ancestorJonathan Nieder, Mar 17, 2010
  7. 04/16 ll_merge(): add ancestor label parameter for diff3-style outputJonathan Nieder, Mar 17, 2010
  8. 05/16 checkout --conflict=diff3: add a label for ancestorJonathan Nieder, Mar 17, 2010
  9. 06/16 merge_file(): add comment explaining behavior wrt conflict styleJonathan Nieder, Mar 17, 2010
  10. 07/16 merge_trees(): add ancestor label parameter for diff3-style outputJonathan Nieder, Mar 17, 2010
  11. 08/16 tests: document format of conflicts from checkout -mJonathan Nieder, Mar 17, 2010
  12. 09/16 checkout -m --conflict=diff3: add a label for ancestorJonathan Nieder, Mar 17, 2010
  13. 10/16 tests: document cherry-pick behavior in face of conflictsJonathan Nieder, Mar 17, 2010
  14. 11/16 revert_or_cherry_pick(): get oneline_body from get_oneline()Jonathan Nieder, Mar 17, 2010
  15. Stephen BoydMar 17, 2010
  16. Jonathan NiederMar 18, 2010
  17. revert: clarify label on conflict hunksJonathan Nieder, Mar 18, 2010
  18. 15/16 cherry-pick, revert: add a label for ancestorJonathan Nieder, Mar 18, 2010
  19. 12/16 compat: add mempcpy()Jonathan Nieder, Mar 17, 2010
  20. 13/16 revert: simplify get_oneline() using mempcpyJonathan Nieder, Mar 17, 2010
  21. 14/16 revert: clarify label on conflict hunksJonathan Nieder, Mar 17, 2010
  22. 15/16 cherry-pick: add a label for ancestorJonathan Nieder, Mar 17, 2010
  23. 16/16 merge-recursive: add a label for ancestorJonathan Nieder, Mar 17, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.