All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] builtin/merge.c: drop a parameter that is never used
@ 2014-10-24 18:27 Junio C Hamano
  2014-10-24 19:37 ` Jonathan Nieder
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-24 18:27 UTC (permalink / raw)
  To: git; +Cc: Jonathan Nieder

Since the very beginning when we added the "renormalizing" parameter
to this function with 7610fa57 (merge-recursive --renormalize,
2010-08-05), nobody seems to have ever referenced it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * ... or is there any "renormalization" the said commit meant to
   but forgot to do?

 builtin/merge.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index 41fb66d..f6894c7 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -884,7 +884,7 @@ static int finish_automerge(struct commit *head,
 	return 0;
 }
 
-static int suggest_conflicts(int renormalizing)
+static int suggest_conflicts(void)
 {
 	const char *filename;
 	FILE *fp;
@@ -1557,7 +1557,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		fprintf(stderr, _("Automatic merge went well; "
 			"stopped before committing as requested\n"));
 	else
-		ret = suggest_conflicts(option_renormalize);
+		ret = suggest_conflicts();
 
 done:
 	free(branch_to_free);
-- 
2.1.2-595-g1568c45

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] builtin/merge.c: drop a parameter that is never used
  2014-10-24 18:27 [PATCH] builtin/merge.c: drop a parameter that is never used Junio C Hamano
@ 2014-10-24 19:37 ` Jonathan Nieder
  2014-10-24 21:22 ` [PATCH] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
  2 siblings, 0 replies; 16+ messages in thread
From: Jonathan Nieder @ 2014-10-24 19:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano wrote:

> Since the very beginning when we added the "renormalizing" parameter
> to this function with 7610fa57 (merge-recursive --renormalize,
> 2010-08-05), nobody seems to have ever referenced it.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

>  * ... or is there any "renormalization" the said commit meant to
>    but forgot to do?

I suspect it's related to this TODO from rerere.c::handle_cache:

	/*
	 * NEEDSWORK: handle conflicts from merges with
	 * merge.renormalize set, too
	 */
	ll_merge(&result, path, &mmfile[0], NULL,
		 &mmfile[1], "ours",
		 &mmfile[2], "theirs", NULL);

But if someone has time for it, rather than plumbing in a useless
parameter that goes nowhere, it would be better to add tests as a
reminder of what is unimplemented. :)

Thanks,
Jonathan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH] merge & sequencer: unify codepaths that write "Conflicts:" hint
  2014-10-24 18:27 [PATCH] builtin/merge.c: drop a parameter that is never used Junio C Hamano
  2014-10-24 19:37 ` Jonathan Nieder
@ 2014-10-24 21:22 ` Junio C Hamano
  2014-10-24 21:24   ` [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
  2 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2014-10-24 21:22 UTC (permalink / raw)
  To: git

Two identical loops in suggest_conflicts() in merge, and
do_recursive_merge() in sequencer, can use a single helper function
extracted from the latter that prepares the "Conflicts:" hint that
is meant to remind the user the paths for which merge conflicts had
to be resolved to write a better commit log message.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 builtin/merge.c | 18 +++++-------------
 sequencer.c     | 35 ++++++++++++++++++++---------------
 sequencer.h     |  1 +
 3 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index f6894c7..d30cb60 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -28,6 +28,7 @@
 #include "remote.h"
 #include "fmt-merge-msg.h"
 #include "gpg-interface.h"
+#include "sequencer.h"
 
 #define DEFAULT_TWOHEAD (1<<0)
 #define DEFAULT_OCTOPUS (1<<1)
@@ -888,24 +889,15 @@ static int suggest_conflicts(void)
 {
 	const char *filename;
 	FILE *fp;
-	int pos;
+	struct strbuf msgbuf = STRBUF_INIT;
 
 	filename = git_path("MERGE_MSG");
 	fp = fopen(filename, "a");
 	if (!fp)
 		die_errno(_("Could not open '%s' for writing"), filename);
-	fprintf(fp, "\nConflicts:\n");
-	for (pos = 0; pos < active_nr; pos++) {
-		const struct cache_entry *ce = active_cache[pos];
-
-		if (ce_stage(ce)) {
-			fprintf(fp, "\t%s\n", ce->name);
-			while (pos + 1 < active_nr &&
-					!strcmp(ce->name,
-						active_cache[pos + 1]->name))
-				pos++;
-		}
-	}
+
+	append_conflicts_hint(&msgbuf);
+	fputs(msgbuf.buf, fp);
 	fclose(fp);
 	rerere(allow_rerere_auto);
 	printf(_("Automatic merge failed; "
diff --git a/sequencer.c b/sequencer.c
index 06e52b4..0f84bbe 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -287,6 +287,24 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from,
 	return ret;
 }
 
+void append_conflicts_hint(struct strbuf *msgbuf)
+{
+	int i;
+
+	strbuf_addstr(msgbuf, "\nConflicts:\n");
+	for (i = 0; i < active_nr;) {
+		const struct cache_entry *ce = active_cache[i++];
+		if (ce_stage(ce)) {
+			strbuf_addch(msgbuf, '\t');
+			strbuf_addstr(msgbuf, ce->name);
+			strbuf_addch(msgbuf, '\n');
+			while (i < active_nr && !strcmp(ce->name,
+							active_cache[i]->name))
+				i++;
+		}
+	}
+}
+
 static int do_recursive_merge(struct commit *base, struct commit *next,
 			      const char *base_label, const char *next_label,
 			      unsigned char *head, struct strbuf *msgbuf,
@@ -328,21 +346,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
 	if (opts->signoff)
 		append_signoff(msgbuf, 0, 0);
 
-	if (!clean) {
-		int i;
-		strbuf_addstr(msgbuf, "\nConflicts:\n");
-		for (i = 0; i < active_nr;) {
-			const struct cache_entry *ce = active_cache[i++];
-			if (ce_stage(ce)) {
-				strbuf_addch(msgbuf, '\t');
-				strbuf_addstr(msgbuf, ce->name);
-				strbuf_addch(msgbuf, '\n');
-				while (i < active_nr && !strcmp(ce->name,
-						active_cache[i]->name))
-					i++;
-			}
-		}
-	}
+	if (!clean)
+		append_conflicts_hint(msgbuf);
 
 	return !clean;
 }
diff --git a/sequencer.h b/sequencer.h
index 1fc22dc..c53519d 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -51,5 +51,6 @@ int sequencer_pick_revisions(struct replay_opts *opts);
 extern const char sign_off_header[];
 
 void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
+void append_conflicts_hint(struct strbuf *msgbuf);
 
 #endif
-- 
2.1.2-595-g1568c45

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-24 21:22 ` [PATCH] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
@ 2014-10-24 21:24   ` Junio C Hamano
  2014-10-26 18:59     ` Jeff King
  0 siblings, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2014-10-24 21:24 UTC (permalink / raw)
  To: git

Just like other hints such as "Change to be committed" we show in
the editor to remind the committer what paths were involved in the
resulting commit to improve their log message, this section is
merely a reminder.  Traditionally, it was not made into comments
primarily because it has to be generated outside wt-status
infrastructure, and secondary it was meant as a bit stronger
reminder than the rest (i.e. explaining how you resolved conflicts
is much more important than mentioning what you did to every paths
involved in the commit), but that still does not make this hint a
hint, which should be commented out by default.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/commit.c                | 42 ++++++++++++++++++++---------------------
 sequencer.c                     |  7 +++----
 t/t3507-cherry-pick-conflict.sh | 22 +++++++++++++--------
 3 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index fedb45a..3a1d1a8 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -719,30 +719,30 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 		stripspace(&sb, 0);
 
 	if (signoff) {
-		/*
-		 * See if we have a Conflicts: block at the end. If yes, count
-		 * its size, so we can ignore it.
-		 */
-		int ignore_footer = 0;
-		int i, eol, previous = 0;
-		const char *nl;
-
-		for (i = 0; i < sb.len; i++) {
-			nl = memchr(sb.buf + i, '\n', sb.len - i);
-			if (nl)
-				eol = nl - sb.buf;
+		/* Ignore comments and blanks after the trailer */
+		int boc = 0;
+		int bol = 0;
+
+		while (bol < sb.len) {
+			char *next_line;
+
+			if (!(next_line = memchr(sb.buf + bol, '\n', sb.len - bol)))
+				next_line = sb.buf + sb.len;
 			else
-				eol = sb.len;
-			if (!prefixcmp(sb.buf + previous, "\nConflicts:\n")) {
-				ignore_footer = sb.len - previous;
-				break;
+				next_line++;
+
+			if (sb.buf[bol] == comment_line_char || sb.buf[bol] == '\n') {
+				/* is this the first of the run of comments? */
+				if (!boc)
+					boc = bol;
+				/* otherwise, it is just continuing */
+			} else if (boc) {
+				/* the previous was not trailing comment */
+				boc = 0;
 			}
-			while (i < eol)
-				i++;
-			previous = eol;
+			bol = next_line - sb.buf;
 		}
-
-		append_signoff(&sb, ignore_footer, 0);
+		append_signoff(&sb, boc ? sb.len - boc : 0, 0);
 	}
 
 	if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
diff --git a/sequencer.c b/sequencer.c
index 0f84bbe..1d97da3 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -291,13 +291,12 @@ void append_conflicts_hint(struct strbuf *msgbuf)
 {
 	int i;
 
-	strbuf_addstr(msgbuf, "\nConflicts:\n");
+	strbuf_addch(msgbuf, '\n');
+	strbuf_commented_addf(msgbuf, "Conflicts:\n");
 	for (i = 0; i < active_nr;) {
 		const struct cache_entry *ce = active_cache[i++];
 		if (ce_stage(ce)) {
-			strbuf_addch(msgbuf, '\t');
-			strbuf_addstr(msgbuf, ce->name);
-			strbuf_addch(msgbuf, '\n');
+			strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);
 			while (i < active_nr && !strcmp(ce->name,
 							active_cache[i]->name))
 				i++;
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 223b984..fa04226 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -351,18 +351,24 @@ test_expect_success 'commit after failed cherry-pick does not add duplicated -s'
 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
 	pristine_detach initial &&
 	test_must_fail git cherry-pick picked &&
+
 	git commit -a -s &&
-	pwd &&
-	cat <<EOF > expected &&
-picked
 
-Signed-off-by: C O Mitter <committer@example.com>
+	# Do S-o-b and Conflicts appear in the right order?
+	cat <<-\EOF >expect &&
+	Signed-off-by: C O Mitter <committer@example.com>
+	# Conflicts:
+	EOF
+	grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
+	test_cmp expect actual &&
+
+	cat <<-\EOF >expected &&
+	picked
 
-Conflicts:
-	foo
-EOF
+	Signed-off-by: C O Mitter <committer@example.com>
+	EOF
 
-	git show -s --pretty=format:%B > actual &&
+	git show -s --pretty=format:%B >actual &&
 	test_cmp expected actual
 '
 
-- 
2.1.2-595-g1568c45

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-24 21:24   ` [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano
@ 2014-10-26 18:59     ` Jeff King
  2014-10-27 17:32       ` Junio C Hamano
  2014-10-27 21:14       ` Jonathan Nieder
  0 siblings, 2 replies; 16+ messages in thread
From: Jeff King @ 2014-10-26 18:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Oct 24, 2014 at 02:24:37PM -0700, Junio C Hamano wrote:

> Just like other hints such as "Change to be committed" we show in
> the editor to remind the committer what paths were involved in the
> resulting commit to improve their log message, this section is
> merely a reminder.  Traditionally, it was not made into comments
> primarily because it has to be generated outside wt-status
> infrastructure, and secondary it was meant as a bit stronger
> reminder than the rest (i.e. explaining how you resolved conflicts
> is much more important than mentioning what you did to every paths
> involved in the commit), but that still does not make this hint a
> hint, which should be commented out by default.

Yay. I like this new behavior much better.

Just to play devil's advocate for a moment, though, are we hurting
people who find it useful to record that information in the commit
message?

For the most part, combined-diff (and --cc) will show the interesting
cases anyway. But if you take a whole file from one side of the merge,
then there is nothing interesting for diff to show. Do people still want
to get that more complete list of potentially interesting files? And if
so, how do they do it?  I think there really isn't a great way besides
repeating the merge.

If that is the only casualty, I think it is probably a net-win. We may
want better tooling around viewing the merge later, but that can wait
until somebody steps up with a real use case (because even that conflict
list may not be completely what they want; they may also want the list
of files that were auto-merged successfully, for example). And I think
there was work recently on a diff view for merge commits that involved
recreating the merge (I do not remember the details, though).

> diff --git a/sequencer.c b/sequencer.c
> index 0f84bbe..1d97da3 100644
> --- a/sequencer.c
> +++ b/sequencer.c
> @@ -291,13 +291,12 @@ void append_conflicts_hint(struct strbuf *msgbuf)
>  {
>  	int i;
>  
> -	strbuf_addstr(msgbuf, "\nConflicts:\n");
> +	strbuf_addch(msgbuf, '\n');
> +	strbuf_commented_addf(msgbuf, "Conflicts:\n");
>  	for (i = 0; i < active_nr;) {
>  		const struct cache_entry *ce = active_cache[i++];
>  		if (ce_stage(ce)) {
> -			strbuf_addch(msgbuf, '\t');
> -			strbuf_addstr(msgbuf, ce->name);
> -			strbuf_addch(msgbuf, '\n');
> +			strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);

This ends up adding a space followed by a tab. Besides being redundant,
it makes my editor highlight it as a whitespace error. I realize this is
a pretty minor nit, though.

-Peff

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-26 18:59     ` Jeff King
@ 2014-10-27 17:32       ` Junio C Hamano
  2014-10-27 20:59         ` Junio C Hamano
  2014-10-28  6:51         ` Christian Couder
  2014-10-27 21:14       ` Jonathan Nieder
  1 sibling, 2 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-27 17:32 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Christian Couder

Jeff King <peff@peff.net> writes:

> Just to play devil's advocate for a moment, though, are we hurting
> people who find it useful to record that information in the commit
> message?

I thought about it, but ultimately, they are using it wrong if they
did depend on them.  As you said, the paths themselves are not that
interesting, unless they are accompanied by description in the log
message explaining what caused conflicts and how they were resolved
at the semantic level.  The hints are to remind them what conflicts
in which paths to describe.

I do not mind "merge.commentConflictsHint = no" as a backward
compatibility toggle, if somebody cares deeply about it, though.

> If that is the only casualty, I think it is probably a net-win. We may
> want better tooling around viewing the merge later, but that can wait
> until somebody steps up with a real use case (because even that conflict
> list may not be completely what they want; they may also want the list
> of files that were auto-merged successfully, for example).

Yup.

Also Christian's "trailer" series may want to learn the same trick
we did to builtin/commit.c in this series, if it does not already
know about possible trailing comment and blank lines.

>> diff --git a/sequencer.c b/sequencer.c
>> index 0f84bbe..1d97da3 100644
>> --- a/sequencer.c
>> +++ b/sequencer.c
>> @@ -291,13 +291,12 @@ void append_conflicts_hint(struct strbuf *msgbuf)
>>  {
>>  	int i;
>>  
>> -	strbuf_addstr(msgbuf, "\nConflicts:\n");
>> +	strbuf_addch(msgbuf, '\n');
>> +	strbuf_commented_addf(msgbuf, "Conflicts:\n");
>>  	for (i = 0; i < active_nr;) {
>>  		const struct cache_entry *ce = active_cache[i++];
>>  		if (ce_stage(ce)) {
>> -			strbuf_addch(msgbuf, '\t');
>> -			strbuf_addstr(msgbuf, ce->name);
>> -			strbuf_addch(msgbuf, '\n');
>> +			strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);
>
> This ends up adding a space followed by a tab. Besides being redundant,
> it makes my editor highlight it as a whitespace error. I realize this is
> a pretty minor nit, though.

Interesting ;-)

I do not think it is too hard to teach strbuf_commented_addf() about
the leading HT, but that would be a separate topic; if squashing the
SP-HT to HT is worth doing for this codepath, doing it at that helper
would benefit all callers.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-27 17:32       ` Junio C Hamano
@ 2014-10-27 20:59         ` Junio C Hamano
  2014-10-28 22:21           ` Jeff King
  2014-10-28  6:51         ` Christian Couder
  1 sibling, 1 reply; 16+ messages in thread
From: Junio C Hamano @ 2014-10-27 20:59 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Christian Couder

Junio C Hamano <gitster@pobox.com> writes:

>>> diff --git a/sequencer.c b/sequencer.c
>>> index 0f84bbe..1d97da3 100644
>>> --- a/sequencer.c
>>> +++ b/sequencer.c
>>> @@ -291,13 +291,12 @@ void append_conflicts_hint(struct strbuf *msgbuf)
>>>  {
>>>  	int i;
>>>  
>>> -	strbuf_addstr(msgbuf, "\nConflicts:\n");
>>> +	strbuf_addch(msgbuf, '\n');
>>> +	strbuf_commented_addf(msgbuf, "Conflicts:\n");
>>>  	for (i = 0; i < active_nr;) {
>>>  		const struct cache_entry *ce = active_cache[i++];
>>>  		if (ce_stage(ce)) {
>>> -			strbuf_addch(msgbuf, '\t');
>>> -			strbuf_addstr(msgbuf, ce->name);
>>> -			strbuf_addch(msgbuf, '\n');
>>> +			strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);
>>
>> This ends up adding a space followed by a tab. Besides being redundant,
>> it makes my editor highlight it as a whitespace error. I realize this is
>> a pretty minor nit, though.
>
> Interesting ;-)
>
> I do not think it is too hard to teach strbuf_commented_addf() about
> the leading HT, but that would be a separate topic; if squashing the
> SP-HT to HT is worth doing for this codepath, doing it at that helper
> would benefit all callers.

-- >8 --
Subject: [PATCH] strbuf_add_lines(): avoid SP-HT sequence

The strbuf_add_commented_lines() function passes a pair of prefixes,
one for a line that has some meat on it, and the other for an empty
line.  The former is set to a comment char followed by a SP, while
the latter is set to just the comment char.  This is to give a SP
after the comment character, e.g. "# <user text>\n" and to avoid
emitting an unsightly "# \n" in its output.

Teach the machinery to also use the latter space-less prefix when
the payload line begins with a tab; otherwise we will end up showing
"# \t<user text>\n" which is similarly unsightly.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 strbuf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/strbuf.c b/strbuf.c
index 0346e74..88cafd4 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -229,7 +229,8 @@ static void add_lines(struct strbuf *out,
 		const char *next = memchr(buf, '\n', size);
 		next = next ? (next + 1) : (buf + size);
 
-		prefix = (prefix2 && buf[0] == '\n') ? prefix2 : prefix1;
+		prefix = ((prefix2 && (buf[0] == '\n' || buf[0] == '\t'))
+			  ? prefix2 : prefix1);
 		strbuf_addstr(out, prefix);
 		strbuf_add(out, buf, next - buf);
 		size -= next - buf;

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-26 18:59     ` Jeff King
  2014-10-27 17:32       ` Junio C Hamano
@ 2014-10-27 21:14       ` Jonathan Nieder
  2014-10-28 22:22         ` Jeff King
  1 sibling, 1 reply; 16+ messages in thread
From: Jonathan Nieder @ 2014-10-27 21:14 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git

Jeff King wrote:

> For the most part, combined-diff (and --cc) will show the interesting
> cases anyway. But if you take a whole file from one side of the merge,
> then there is nothing interesting for diff to show. Do people still want
> to get that more complete list of potentially interesting files? And if
> so, how do they do it?  I think there really isn't a great way besides
> repeating the merge.

If you have time to experiment with tr/remerge-diff from pu[1], that
would be welcome.

Maybe some day it can be the default behavior for 'log -p'.

> If that is the only casualty, I think it is probably a net-win.

Yes.

Thanks,
Jonathan

[1] http://thread.gmane.org/gmane.comp.version-control.git/256591

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-27 17:32       ` Junio C Hamano
  2014-10-27 20:59         ` Junio C Hamano
@ 2014-10-28  6:51         ` Christian Couder
  1 sibling, 0 replies; 16+ messages in thread
From: Christian Couder @ 2014-10-28  6:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, git, Christian Couder

On Mon, Oct 27, 2014 at 6:32 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jeff King <peff@peff.net> writes:
>
>> If that is the only casualty, I think it is probably a net-win. We may
>> want better tooling around viewing the merge later, but that can wait
>> until somebody steps up with a real use case (because even that conflict
>> list may not be completely what they want; they may also want the list
>> of files that were auto-merged successfully, for example).
>
> Yup.
>
> Also Christian's "trailer" series may want to learn the same trick
> we did to builtin/commit.c in this series, if it does not already
> know about possible trailing comment and blank lines.

The trailer series already tries to ignore comments and blank lines.
This is the relevant function:

/*
 * Return the (0 based) index of the first trailer line or count if
 * there are no trailers. Trailers are searched only in the lines from
 * index (count - 1) down to index 0.
 */
static int find_trailer_start(struct strbuf **lines, int count)
{
    int start, only_spaces = 1;

    /*
     * Get the start of the trailers by looking starting from the end
     * for a line with only spaces before lines with one separator.
     */
    for (start = count - 1; start >= 0; start--) {
        if (lines[start]->buf[0] == comment_line_char)
            continue;
        if (contains_only_spaces(lines[start]->buf)) {
            if (only_spaces)
                continue;
            return start + 1;
        }
        if (strcspn(lines[start]->buf, separators) < lines[start]->len) {
            if (only_spaces)
                only_spaces = 0;
            continue;
        }
        return count;
    }

    return only_spaces ? count : 0;
}

But I am not sure sure that it does all of what you do to
builtin/commit.c in the above patch. I will have a look.
Anyway I would be happy to use an existing function or to refactor
some existing code into a shared function if possible.

Thanks,
Christian.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 0/4] Turning Conflicts: hint into comment
  2014-10-24 18:27 [PATCH] builtin/merge.c: drop a parameter that is never used Junio C Hamano
  2014-10-24 19:37 ` Jonathan Nieder
  2014-10-24 21:22 ` [PATCH] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
@ 2014-10-28 21:36 ` Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 1/4] builtin/merge.c: drop a parameter that is never used Junio C Hamano
                     ` (3 more replies)
  2 siblings, 4 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-28 21:36 UTC (permalink / raw)
  To: git

So here is a reroll to hopefully bring this topic closer to
perfection.

The first two patches haven't changed, except that they are now part
of a numbered series.

The third patch is a refactoring that helps clarify what happens in
the last step, which is new.

The endgame is similar to what was posted before, except that we pay
attention to "Conflicts:" and HT indented pathnames in addition to
comments and blanks when determining the true end of the log
message.  This is so that running "git commit --amend -s" on a
commit that was created with older versions of Git by a careless
user who left the old conflicts hint around will insert the new
sign-off at the right place.

The series is designed to apply on v1.8.5.x series, even though I do
not anticpiate that we would need to backport this to maintenance
branches.  !prefixcmp() will need to turn into starts_with() when
merging to newer codebase, which I can let rerere take care of.

Junio C Hamano (4):
  builtin/merge.c: drop a parameter that is never used
  merge & sequencer: unify codepaths that write "Conflicts:" hint
  builtin/commit.c: extract ignore_non_trailer() helper function
  merge & sequencer: turn "Conflicts:" hint into a comment

 builtin/commit.c                | 74 ++++++++++++++++++++++++++---------------
 builtin/merge.c                 | 22 ++++--------
 sequencer.c                     | 34 ++++++++++---------
 sequencer.h                     |  1 +
 t/t3507-cherry-pick-conflict.sh | 42 ++++++++++++++++++-----
 5 files changed, 109 insertions(+), 64 deletions(-)

-- 
2.1.2-620-g33c52cb

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2 1/4] builtin/merge.c: drop a parameter that is never used
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
@ 2014-10-28 21:36   ` Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 2/4] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-28 21:36 UTC (permalink / raw)
  To: git

Since the very beginning when we added the "renormalizing" parameter
to this function with 7610fa57 (merge-recursive --renormalize,
2010-08-05), nobody seems to have ever referenced it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/merge.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index 41fb66d..f6894c7 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -884,7 +884,7 @@ static int finish_automerge(struct commit *head,
 	return 0;
 }
 
-static int suggest_conflicts(int renormalizing)
+static int suggest_conflicts(void)
 {
 	const char *filename;
 	FILE *fp;
@@ -1557,7 +1557,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		fprintf(stderr, _("Automatic merge went well; "
 			"stopped before committing as requested\n"));
 	else
-		ret = suggest_conflicts(option_renormalize);
+		ret = suggest_conflicts();
 
 done:
 	free(branch_to_free);
-- 
2.1.2-620-g33c52cb

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 2/4] merge & sequencer: unify codepaths that write "Conflicts:" hint
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 1/4] builtin/merge.c: drop a parameter that is never used Junio C Hamano
@ 2014-10-28 21:36   ` Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 3/4] builtin/commit.c: extract ignore_non_trailer() helper function Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 4/4] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano
  3 siblings, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-28 21:36 UTC (permalink / raw)
  To: git

Two identical loops in suggest_conflicts() in merge, and
do_recursive_merge() in sequencer, can use a single helper function
extracted from the latter that prepares the "Conflicts:" hint that
is meant to remind the user the paths for which merge conflicts had
to be resolved to write a better commit log message.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/merge.c | 18 +++++-------------
 sequencer.c     | 35 ++++++++++++++++++++---------------
 sequencer.h     |  1 +
 3 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/builtin/merge.c b/builtin/merge.c
index f6894c7..d30cb60 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -28,6 +28,7 @@
 #include "remote.h"
 #include "fmt-merge-msg.h"
 #include "gpg-interface.h"
+#include "sequencer.h"
 
 #define DEFAULT_TWOHEAD (1<<0)
 #define DEFAULT_OCTOPUS (1<<1)
@@ -888,24 +889,15 @@ static int suggest_conflicts(void)
 {
 	const char *filename;
 	FILE *fp;
-	int pos;
+	struct strbuf msgbuf = STRBUF_INIT;
 
 	filename = git_path("MERGE_MSG");
 	fp = fopen(filename, "a");
 	if (!fp)
 		die_errno(_("Could not open '%s' for writing"), filename);
-	fprintf(fp, "\nConflicts:\n");
-	for (pos = 0; pos < active_nr; pos++) {
-		const struct cache_entry *ce = active_cache[pos];
-
-		if (ce_stage(ce)) {
-			fprintf(fp, "\t%s\n", ce->name);
-			while (pos + 1 < active_nr &&
-					!strcmp(ce->name,
-						active_cache[pos + 1]->name))
-				pos++;
-		}
-	}
+
+	append_conflicts_hint(&msgbuf);
+	fputs(msgbuf.buf, fp);
 	fclose(fp);
 	rerere(allow_rerere_auto);
 	printf(_("Automatic merge failed; "
diff --git a/sequencer.c b/sequencer.c
index 06e52b4..0f84bbe 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -287,6 +287,24 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from,
 	return ret;
 }
 
+void append_conflicts_hint(struct strbuf *msgbuf)
+{
+	int i;
+
+	strbuf_addstr(msgbuf, "\nConflicts:\n");
+	for (i = 0; i < active_nr;) {
+		const struct cache_entry *ce = active_cache[i++];
+		if (ce_stage(ce)) {
+			strbuf_addch(msgbuf, '\t');
+			strbuf_addstr(msgbuf, ce->name);
+			strbuf_addch(msgbuf, '\n');
+			while (i < active_nr && !strcmp(ce->name,
+							active_cache[i]->name))
+				i++;
+		}
+	}
+}
+
 static int do_recursive_merge(struct commit *base, struct commit *next,
 			      const char *base_label, const char *next_label,
 			      unsigned char *head, struct strbuf *msgbuf,
@@ -328,21 +346,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
 	if (opts->signoff)
 		append_signoff(msgbuf, 0, 0);
 
-	if (!clean) {
-		int i;
-		strbuf_addstr(msgbuf, "\nConflicts:\n");
-		for (i = 0; i < active_nr;) {
-			const struct cache_entry *ce = active_cache[i++];
-			if (ce_stage(ce)) {
-				strbuf_addch(msgbuf, '\t');
-				strbuf_addstr(msgbuf, ce->name);
-				strbuf_addch(msgbuf, '\n');
-				while (i < active_nr && !strcmp(ce->name,
-						active_cache[i]->name))
-					i++;
-			}
-		}
-	}
+	if (!clean)
+		append_conflicts_hint(msgbuf);
 
 	return !clean;
 }
diff --git a/sequencer.h b/sequencer.h
index 1fc22dc..c53519d 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -51,5 +51,6 @@ int sequencer_pick_revisions(struct replay_opts *opts);
 extern const char sign_off_header[];
 
 void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);
+void append_conflicts_hint(struct strbuf *msgbuf);
 
 #endif
-- 
2.1.2-620-g33c52cb

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 3/4] builtin/commit.c: extract ignore_non_trailer() helper function
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 1/4] builtin/merge.c: drop a parameter that is never used Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 2/4] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
@ 2014-10-28 21:36   ` Junio C Hamano
  2014-10-28 21:36   ` [PATCH v2 4/4] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano
  3 siblings, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-28 21:36 UTC (permalink / raw)
  To: git

Extract a helper function from prepare_to_commit() to determine
where to place a new Signed-off-by: line, which is essentially the
true "end" of the log message, ignoring the trailing "Conflicts:"
line and everything below it.

The detection _should_ make sure the "Conflicts:" line it finds is
truly the conflict hint block by checking everything that follows is
a HT indented pathname to avoid false positive, but this logic will
be revamped in a later patch to ignore comments and blanks anyway,
so it is left as-is in this step.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/commit.c | 59 +++++++++++++++++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index fedb45a..cd455aa 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -593,6 +593,37 @@ static char *cut_ident_timestamp_part(char *string)
 	return ket;
 }
 
+/*
+ * Inspect sb and determine the true "end" of the log message, in
+ * order to find where to put a new Signed-off-by: line.  Ignored are
+ * trailing "Conflict:" block.
+ *
+ * Returns the number of bytes from the tail to ignore, to be fed as
+ * the second parameter to append_signoff().
+ */
+static int ignore_non_trailer(struct strbuf *sb)
+{
+	int ignore_footer = 0;
+	int i, eol, previous = 0;
+	const char *nl;
+
+	for (i = 0; i < sb->len; i++) {
+		nl = memchr(sb->buf + i, '\n', sb->len - i);
+		if (nl)
+			eol = nl - sb->buf;
+		else
+			eol = sb->len;
+		if (!prefixcmp(sb->buf + previous, "\nConflicts:\n")) {
+			ignore_footer = sb->len - previous;
+			break;
+		}
+		while (i < eol)
+			i++;
+		previous = eol;
+	}
+	return ignore_footer;
+}
+
 static int prepare_to_commit(const char *index_file, const char *prefix,
 			     struct commit *current_head,
 			     struct wt_status *s,
@@ -718,32 +749,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 	if (clean_message_contents)
 		stripspace(&sb, 0);
 
-	if (signoff) {
-		/*
-		 * See if we have a Conflicts: block at the end. If yes, count
-		 * its size, so we can ignore it.
-		 */
-		int ignore_footer = 0;
-		int i, eol, previous = 0;
-		const char *nl;
-
-		for (i = 0; i < sb.len; i++) {
-			nl = memchr(sb.buf + i, '\n', sb.len - i);
-			if (nl)
-				eol = nl - sb.buf;
-			else
-				eol = sb.len;
-			if (!prefixcmp(sb.buf + previous, "\nConflicts:\n")) {
-				ignore_footer = sb.len - previous;
-				break;
-			}
-			while (i < eol)
-				i++;
-			previous = eol;
-		}
-
-		append_signoff(&sb, ignore_footer, 0);
-	}
+	if (signoff)
+		append_signoff(&sb, ignore_non_trailer(&sb), 0);
 
 	if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
 		die_errno(_("could not write commit template"));
-- 
2.1.2-620-g33c52cb

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH v2 4/4] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
                     ` (2 preceding siblings ...)
  2014-10-28 21:36   ` [PATCH v2 3/4] builtin/commit.c: extract ignore_non_trailer() helper function Junio C Hamano
@ 2014-10-28 21:36   ` Junio C Hamano
  3 siblings, 0 replies; 16+ messages in thread
From: Junio C Hamano @ 2014-10-28 21:36 UTC (permalink / raw)
  To: git

Just like other hints such as "Changes to be committed" we show in
the editor to remind the committer what paths were involved in the
resulting commit to help improving their log message, this section
is merely a reminder.

Traditionally, it was not made into comments primarily because it
has to be generated outside the wt-status infrastructure, and also
because it was meant as a bit stronger reminder than the others
(i.e. explaining how you resolved conflicts is much more important
than mentioning what you did to every paths involved in the commit).

But that still does not make this hint a part of the log message
proper, and not showing it as a comment is inviting mistakes.

Note that we still notice "Conflicts:" followed by list of indented
pathnames as an old-style cruft and insert a new Signed-off-by:
before it.  This is so that "commit --amend -s" adds the new S-o-b
at the right place when used on an older commit.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/commit.c                | 47 +++++++++++++++++++++++++++--------------
 sequencer.c                     |  7 +++---
 t/t3507-cherry-pick-conflict.sh | 42 +++++++++++++++++++++++++++++-------
 3 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index cd455aa..0a78e76 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -596,32 +596,47 @@ static char *cut_ident_timestamp_part(char *string)
 /*
  * Inspect sb and determine the true "end" of the log message, in
  * order to find where to put a new Signed-off-by: line.  Ignored are
- * trailing "Conflict:" block.
+ * trailing comment lines and blank lines, and also the traditional
+ * "Conflicts:" block that is not commented out, so that we can use
+ * "git commit -s --amend" on an existing commit that forgot to remove
+ * it.
  *
  * Returns the number of bytes from the tail to ignore, to be fed as
  * the second parameter to append_signoff().
  */
 static int ignore_non_trailer(struct strbuf *sb)
 {
-	int ignore_footer = 0;
-	int i, eol, previous = 0;
-	const char *nl;
+	int boc = 0;
+	int bol = 0;
+	int in_old_conflicts_block = 0;
 
-	for (i = 0; i < sb->len; i++) {
-		nl = memchr(sb->buf + i, '\n', sb->len - i);
-		if (nl)
-			eol = nl - sb->buf;
+	while (bol < sb->len) {
+		char *next_line;
+
+		if (!(next_line = memchr(sb->buf + bol, '\n', sb->len - bol)))
+			next_line = sb->buf + sb->len;
 		else
-			eol = sb->len;
-		if (!prefixcmp(sb->buf + previous, "\nConflicts:\n")) {
-			ignore_footer = sb->len - previous;
-			break;
+			next_line++;
+
+		if (sb->buf[bol] == comment_line_char || sb->buf[bol] == '\n') {
+			/* is this the first of the run of comments? */
+			if (!boc)
+				boc = bol;
+			/* otherwise, it is just continuing */
+		} else if (!prefixcmp(sb->buf + bol, "Conflicts:\n")) {
+			in_old_conflicts_block = 1;
+			if (!boc)
+				boc = bol;
+		} else if (in_old_conflicts_block && sb->buf[bol] == '\t') {
+			; /* a pathname in the conflicts block */
+		} else if (boc) {
+			/* the previous was not trailing comment */
+			boc = 0;
+			in_old_conflicts_block = 0;
 		}
-		while (i < eol)
-			i++;
-		previous = eol;
+		bol = next_line - sb->buf;
 	}
-	return ignore_footer;
+	return boc ? sb->len - boc : 0;
 }
 
 static int prepare_to_commit(const char *index_file, const char *prefix,
diff --git a/sequencer.c b/sequencer.c
index 0f84bbe..1d97da3 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -291,13 +291,12 @@ void append_conflicts_hint(struct strbuf *msgbuf)
 {
 	int i;
 
-	strbuf_addstr(msgbuf, "\nConflicts:\n");
+	strbuf_addch(msgbuf, '\n');
+	strbuf_commented_addf(msgbuf, "Conflicts:\n");
 	for (i = 0; i < active_nr;) {
 		const struct cache_entry *ce = active_cache[i++];
 		if (ce_stage(ce)) {
-			strbuf_addch(msgbuf, '\t');
-			strbuf_addstr(msgbuf, ce->name);
-			strbuf_addch(msgbuf, '\n');
+			strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);
 			while (i < active_nr && !strcmp(ce->name,
 							active_cache[i]->name))
 				i++;
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 223b984..7c5ad08 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -351,19 +351,45 @@ test_expect_success 'commit after failed cherry-pick does not add duplicated -s'
 test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
 	pristine_detach initial &&
 	test_must_fail git cherry-pick picked &&
+
 	git commit -a -s &&
-	pwd &&
-	cat <<EOF > expected &&
-picked
 
-Signed-off-by: C O Mitter <committer@example.com>
+	# Do S-o-b and Conflicts appear in the right order?
+	cat <<-\EOF >expect &&
+	Signed-off-by: C O Mitter <committer@example.com>
+	# Conflicts:
+	EOF
+	grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
+	test_cmp expect actual &&
+
+	cat <<-\EOF >expected &&
+	picked
 
-Conflicts:
-	foo
-EOF
+	Signed-off-by: C O Mitter <committer@example.com>
+	EOF
 
-	git show -s --pretty=format:%B > actual &&
+	git show -s --pretty=format:%B >actual &&
 	test_cmp expected actual
 '
 
+test_expect_success 'commit --amend -s places the sign-off at the right place' '
+	pristine_detach initial &&
+	test_must_fail git cherry-pick picked &&
+
+	# emulate old-style conflicts block
+	mv .git/MERGE_MSG .git/MERGE_MSG+ &&
+	sed -e "/^# Conflicts:/,\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG &&
+
+	git commit -a &&
+	git commit --amend -s &&
+
+	# Do S-o-b and Conflicts appear in the right order?
+	cat <<-\EOF >expect &&
+	Signed-off-by: C O Mitter <committer@example.com>
+	Conflicts:
+	EOF
+	grep -e "^Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
2.1.2-620-g33c52cb

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-27 20:59         ` Junio C Hamano
@ 2014-10-28 22:21           ` Jeff King
  0 siblings, 0 replies; 16+ messages in thread
From: Jeff King @ 2014-10-28 22:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Christian Couder

On Mon, Oct 27, 2014 at 01:59:18PM -0700, Junio C Hamano wrote:

> > I do not think it is too hard to teach strbuf_commented_addf() about
> > the leading HT, but that would be a separate topic; if squashing the
> > SP-HT to HT is worth doing for this codepath, doing it at that helper
> > would benefit all callers.
> 
> -- >8 --
> Subject: [PATCH] strbuf_add_lines(): avoid SP-HT sequence
> [...]

Thanks for doing this. I agree that this is the right place to put the
magic, and the patch looks obviously correct. I also double-checked it
with the "# Conflicts" patches and it addresses the problem I saw.

-Peff

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment
  2014-10-27 21:14       ` Jonathan Nieder
@ 2014-10-28 22:22         ` Jeff King
  0 siblings, 0 replies; 16+ messages in thread
From: Jeff King @ 2014-10-28 22:22 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, git

On Mon, Oct 27, 2014 at 02:14:42PM -0700, Jonathan Nieder wrote:

> Jeff King wrote:
> 
> > For the most part, combined-diff (and --cc) will show the interesting
> > cases anyway. But if you take a whole file from one side of the merge,
> > then there is nothing interesting for diff to show. Do people still want
> > to get that more complete list of potentially interesting files? And if
> > so, how do they do it?  I think there really isn't a great way besides
> > repeating the merge.
> 
> If you have time to experiment with tr/remerge-diff from pu[1], that
> would be welcome.

Thanks, that was the topic I was thinking of.

It's not very often that I want to carefully investigate merge commits
(usually it is when I am trying to help somebody track the addition or
deletion of content that came as part of an evil merge), but I'll give
it a try next time it comes up.

-Peff

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2014-10-28 22:22 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-24 18:27 [PATCH] builtin/merge.c: drop a parameter that is never used Junio C Hamano
2014-10-24 19:37 ` Jonathan Nieder
2014-10-24 21:22 ` [PATCH] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
2014-10-24 21:24   ` [PATCH] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano
2014-10-26 18:59     ` Jeff King
2014-10-27 17:32       ` Junio C Hamano
2014-10-27 20:59         ` Junio C Hamano
2014-10-28 22:21           ` Jeff King
2014-10-28  6:51         ` Christian Couder
2014-10-27 21:14       ` Jonathan Nieder
2014-10-28 22:22         ` Jeff King
2014-10-28 21:36 ` [PATCH v2 0/4] Turning Conflicts: hint into comment Junio C Hamano
2014-10-28 21:36   ` [PATCH v2 1/4] builtin/merge.c: drop a parameter that is never used Junio C Hamano
2014-10-28 21:36   ` [PATCH v2 2/4] merge & sequencer: unify codepaths that write "Conflicts:" hint Junio C Hamano
2014-10-28 21:36   ` [PATCH v2 3/4] builtin/commit.c: extract ignore_non_trailer() helper function Junio C Hamano
2014-10-28 21:36   ` [PATCH v2 4/4] merge & sequencer: turn "Conflicts:" hint into a comment Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.