Subject: Re: [irq/urgent]: created 3786fc7: "irq: make variable static"

From: René Scharfe <[email-masked]>
Date: Sun, 26 Oct 2008 17:04:19 +0100

Ingo Molnar schrieb:
> The most useful angle would be if git log --format had a way to print 
> the reverse name. Then i could do a git-log-line script like:
> 
>   git log --pretty=format:"%h: %20N %s" $@
> 
> where %N prints the reverse name.
> 
> While at it: it would be nice if git log had a way to crop string 
> output. For example i'd love to use:
> 
>   git log --pretty=format:"%h: %60s" $@
> 
> which would print out at most 60 characters from the first commit line.
> 
> That way i can see it properly on an 80 width terminal and can paste it 
> into email without linewraps, etc. But --pretty=format does not seem to 
> know width restrictions.

You don't need support for format string cropping in git for the latter
example, you can use cut instead:

   git log --pretty=format:%h:\ %s $@ | cut -b-70

But I only realized that after I had written the following patch. :)
Would this feature still be useful?

Thanks,
René

---
 Documentation/pretty-formats.txt |    5 +++++
 pretty.c                         |   30 ++++++++++++++++++++++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index f18d33e..cc76c45 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -128,6 +128,11 @@ The placeholders are:
 - '%n': newline
 - '%x00': print a byte from a hex code
 
++
+You can also specify a maximum width for each field after the '%', e.g.
+'%60s' will show the first sixty characters of the subject (or less if
+it's shorter).
+
 * 'tformat:'
 +
 The 'tformat:' format works exactly like 'format:', except that it
diff --git a/pretty.c b/pretty.c
index 1e79943..74e8932 100644
--- a/pretty.c
+++ b/pretty.c
@@ -498,8 +498,8 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
 		strbuf_addch(sb, ')');
 }
 
-static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
-                               void *context)
+static size_t do_format_commit_item(struct strbuf *sb, const char *placeholder,
+		void *context)
 {
 	struct format_commit_context *c = context;
 	const struct commit *commit = c->commit;
@@ -621,6 +621,32 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 	return 0;	/* unknown placeholder */
 }
 
+static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
+		void *context)
+{
+	size_t digits = 0;
+	size_t maxlen = 0;
+	size_t consumed;
+
+	if (isdigit(placeholder[0])) {
+		do {
+			digits++;
+			maxlen *= 10;
+			maxlen += placeholder[0] - '0';
+			placeholder++;
+		} while (isdigit(placeholder[0]));
+		maxlen += sb->len;
+	}
+
+	consumed = do_format_commit_item(sb, placeholder, context);
+	if (!consumed)
+		return 0;
+
+	if (digits && sb->len > maxlen)
+		strbuf_setlen(sb, maxlen);
+	return digits + consumed;
+}
+
 void format_commit_message(const struct commit *commit,
 			   const void *format, struct strbuf *sb,
 			   enum date_mode dmode)
-- 
1.6.0.3.514.g2f91b