# [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.

5 messages from 2007-11-22 to 2007-11-26. Participants: Kristian Høgsberg, Johannes Schindelin, Jeff King, Junio C Hamano.
Thread: https://gitlist.dev/t/10972

## Kristian Høgsberg, 2007-11-22 02:54

Subject: [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.
Message-ID: <1195700089-8326-1-git-send-email-krh@redhat.com>
URL: https://gitlist.dev/e/1195700089-8326-1-git-send-email-krh%40redhat.com

```
run_diff_index() and the entire diff machinery is hard coded to output
to stdout, so just redirect that and restore it when done.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---

Thinking about this, the dup-dance really belongs in wt-status.c since
that interface promises that it can redirect to a FILE *.  Also the
fflush()'es in the earlier patch could go wrong if stdout ends up flushing
during run_diff_index() and fp has unflushed data.

 builtin-commit.c |    8 +++++++-
 wt-status.c      |   16 ++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index e8893f8..39764ae 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -662,7 +662,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	int header_len;
 	struct strbuf sb;
 	const char *index_file, *reflog_msg;
-	char *nl;
+	char *nl, *p;
 	unsigned char commit_sha1[20];
 	struct ref_lock *ref_lock;
 
@@ -758,6 +758,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		rollback_index_files();
 		exit(1);
 	}
+
+	/* Truncate the message just before the diff, if any. */
+	p = strstr(sb.buf, "\ndiff --git a/");
+	if (p != NULL)
+		strbuf_setlen(&sb, p - sb.buf);
+
 	stripspace(&sb, 1);
 	if (sb.len < header_len || message_is_empty(&sb, header_len)) {
 		rollback_index_files();
diff --git a/wt-status.c b/wt-status.c
index d3c10b8..0e0439f 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -315,12 +315,28 @@ static void wt_status_print_untracked(struct wt_status *s)
 static void wt_status_print_verbose(struct wt_status *s)
 {
 	struct rev_info rev;
+	int saved_stdout;
+
+	fflush(s->fp);
+
+	/* Sigh, the entire diff machinery is hardcoded to output to
+	 * stdout.  Do the dup-dance...*/
+	saved_stdout = dup(STDOUT_FILENO);
+	if (saved_stdout < 0 ||dup2(fileno(s->fp), STDOUT_FILENO) < 0)
+		die("couldn't redirect stdout\n");
+
 	init_revisions(&rev, NULL);
 	setup_revisions(0, NULL, &rev, s->reference);
 	rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
 	rev.diffopt.detect_rename = 1;
 	wt_read_cache(s);
 	run_diff_index(&rev, 1);
+
+	fflush(stdout);
+
+	if (dup2(saved_stdout, STDOUT_FILENO) < 0)
+		die("couldn't restore stdout\n");
+	close(saved_stdout);
 }
 
 void wt_status_print(struct wt_status *s)
-- 
1.5.3.4

```

## Johannes Schindelin, 2007-11-22 10:52

Subject: Re: [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.
Message-ID: <Pine.LNX.4.64.0711221049350.27959@racer.site>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0711221049350.27959%40racer.site
In-Reply-To: <1195700089-8326-1-git-send-email-krh@redhat.com>

```
Hi,

On Wed, 21 Nov 2007, Kristian Høgsberg wrote:

> @@ -758,6 +758,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>  		rollback_index_files();
>  		exit(1);
>  	}
> +
> +	/* Truncate the message just before the diff, if any. */
> +	p = strstr(sb.buf, "\ndiff --git a/");
> +	if (p != NULL)
> +		strbuf_setlen(&sb, p - sb.buf);
> +

Is this related to the change in wt_status?  If so, wouldn't we want to 
suppress the diff, instead of generating it, and then killing it later?

Besides, you'd want to leave the \n there: strbuf_setlen(&sb, p + 1 - 
sb.buf);

> +	/* Sigh, the entire diff machinery is hardcoded to output to
> +	 * stdout.  Do the dup-dance...*/

I wonder how much effort it would be to change that.  Not that it would 
help too much, since we want the output in a strbuf anyway.

Ciao,
Dscho
```

## Jeff King, 2007-11-22 11:13

Subject: Re: [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.
Message-ID: <20071122111314.GE10389@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20071122111314.GE10389%40sigill.intra.peff.net
In-Reply-To: <Pine.LNX.4.64.0711221049350.27959@racer.site>

```
On Thu, Nov 22, 2007 at 10:52:04AM +0000, Johannes Schindelin wrote:

> > +	/* Sigh, the entire diff machinery is hardcoded to output to
> > +	 * stdout.  Do the dup-dance...*/
> 
> I wonder how much effort it would be to change that.  Not that it would 
> help too much, since we want the output in a strbuf anyway.

An "emit"-type callback would be nice and elegant. The biggest trick is
that there are a lot of formatting calls, so you'd need your callback
signature to be a variadic function. But it's probably do-able.

-Peff

```

## Junio C Hamano, 2007-11-22 19:14

Subject: Re: [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.
Message-ID: <7vzlx63xey.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vzlx63xey.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <Pine.LNX.4.64.0711221049350.27959@racer.site>

```
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Wed, 21 Nov 2007, Kristian Høgsberg wrote:
>
>> +
>> +	/* Truncate the message just before the diff, if any. */
>> +	p = strstr(sb.buf, "\ndiff --git a/");
>> +	if (p != NULL)
>> +		strbuf_setlen(&sb, p - sb.buf);
>> +
>
> Is this related to the change in wt_status?  If so, wouldn't we want to 
> suppress the diff, instead of generating it, and then killing it later?

This corresponds to the sed script near l.545 in git-commit.sh.

I've been wondering if it would be better not to have this logic
but instead "git commit -v" to show the diff text prefixed with
'# ' to make it a proper comment, by the way.

> Besides, you'd want to leave the \n there: strbuf_setlen(&sb, p + 1 - 
> sb.buf);

Yup.

>> +	/* Sigh, the entire diff machinery is hardcoded to output to
>> +	 * stdout.  Do the dup-dance...*/
>
> I wonder how much effort it would be to change that.  Not that it would 
> help too much, since we want the output in a strbuf anyway.

The codepath is preparing COMMIT_EDITMSG file for the user to
edit (or to the standard output, if this is "git status -v").

I do not know about "strbuf" part; resulting patch text could be
large and in most cases the callers would rather flush it to
outside (either pipe or file) as soon as possible than having to
keep it all in core.

I was trying to do the stdout -> FILE *fp conversion of diff.c
last night but dropped it halfway, after finding one puts()
misconversion and fixing it.  The changes should mostly be
straightforward but the result felt ugly.

```

## Kristian Høgsberg, 2007-11-26 15:21

Subject: Re: [PATCH v2] builtin-commit: Include the diff in the commit message when verbose.
Message-ID: <1196090475.2875.10.camel@hinata.boston.redhat.com>
URL: https://gitlist.dev/e/1196090475.2875.10.camel%40hinata.boston.redhat.com
In-Reply-To: <7vzlx63xey.fsf@gitster.siamese.dyndns.org>

```

On Thu, 2007-11-22 at 11:14 -0800, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > On Wed, 21 Nov 2007, Kristian Høgsberg wrote:
> >
> >> +
> >> +	/* Truncate the message just before the diff, if any. */
> >> +	p = strstr(sb.buf, "\ndiff --git a/");
> >> +	if (p != NULL)
> >> +		strbuf_setlen(&sb, p - sb.buf);
> >> +
> >
> > Is this related to the change in wt_status?  If so, wouldn't we want to 
> > suppress the diff, instead of generating it, and then killing it later?
> 
> This corresponds to the sed script near l.545 in git-commit.sh.
> 
> I've been wondering if it would be better not to have this logic
> but instead "git commit -v" to show the diff text prefixed with
> '# ' to make it a proper comment, by the way.

Yeah, that would be nicer... I think the best way to do this is to do a
formatting callback for the diff machinery as Jeff suggests, which can
then prefix '# ' and write it to a FILE *.

> > Besides, you'd want to leave the \n there: strbuf_setlen(&sb, p + 1 - 
> > sb.buf);
> 
> Yup.

Right, off-by-one.  Effectively it doesn't make a difference, since
there will always be a comment line above the diff,  When stripspace
removes the comments it fixes up the end-of-line problem.  Patch below.

cheers,
Kristian


>From 58eac54a00d3eb6a311c6fb4faa67eb831c60e01 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
Date: Mon, 26 Nov 2007 10:16:08 -0500
Subject: [PATCH] Fix off-by-one error when truncating the diff out of the commit message.
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
---
 builtin-commit.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/builtin-commit.c b/builtin-commit.c
index 45e51b1..330f778 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -762,7 +762,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	/* Truncate the message just before the diff, if any. */
 	p = strstr(sb.buf, "\ndiff --git a/");
 	if (p != NULL)
-		strbuf_setlen(&sb, p - sb.buf);
+		strbuf_setlen(&sb, p - sb.buf + 1);
 
 	stripspace(&sb, 1);
 	if (sb.len < header_len || message_is_empty(&sb, header_len)) {
-- 
1.5.3.4.206.g58ba4

```
