{"thread":{"id":"23641","subject":"[PATCH v3 1/5] pretty: add conditional %C?colorname placeholders","startedAt":"2010-04-30T19:35:23Z","lastAt":"2010-05-02T09:31:52Z","messageCount":21,"participants":["Will Palmer","Junio C Hamano","Jeff King","Jonathan Nieder"],"isPatch":true,"patchVersion":3,"patchTotal":5},"messages":[{"id":"140649","messageId":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":null,"subject":"[PATCH v3 0/5] pretty: format aliases","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:23Z","receivedAt":"2010-04-30T19:35:23Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"The following patch series adds the ability to configure aliases for\nuser-defined formats. The first two patches define new placeholders and\nmodify the output of existing placeholders to allow aliases to be more\nconsistent with the way built-in formats are handled. The third and\nfourth patches add infrastructure for the ease of adding additional\nformats, and infrastructure for defining format aliases, respectively.\nThe final patch adds support for defining format aliases via a config\noption.\n\nRegarding conditional colors:\nThere were a couple of places where I wasn't entirely sure about which\ncolor setting I should be following, but I've tried to be consistent\nthroughout. It may be that I could have simply followed diffopt's color\noption in all cases, in which case various modifications to show_log()\nwere entirely unnecessary. I'll await judgement at the hands of one who\ngroks those sections more than I do, but I think what I've done feels\ncorrect.\n\nRegarding pretty aliases:\nMy original goal was to make it possible to define all of the built-in\nformats as built-in aliases to format strings, but complications\nregarding how --parents and --decorate would be handled require further\nthought and discussion. For example, we could simply make\n\"--format=%H --decorate\" synonymous with \"--format=%H%d\", but I'm not\nsure if that feels clean enough.\n\nThis is the third version of the patch. In the second version of the\npatch, (Following feedback from Jeff King <peff@peff.net>), I realized\nthat the modification to the arguments of show_log() were unnecessary,\nas they only made a difference within show-branch.c, which does not\naccept a --format option in any case.\n\nThanks goes to Jeff King <peff@peff.net>,\nAlex Riesen <raa.lkml@gmail.com>, and especially to\nJonathan Nieder <jrnieder@gmail.com>, who took time to do a full review\non the original patch. Most of their concerns have been addressed\nthrough the new patches themselves, but of note:\n\n\t- Changes to %H need documentation/tests\n\tI disagree that a documentation change is needed, as it is my\n\topinion that the documentation as-is implies the behavior these\n\tpatches introduce. Tests have been added.\n\n\t- Documentation for %C?... needs clarification\n\tThere seemed to be some confusion as to how the new syntax\n\tactually worked. I've split the documentation lines into\n\tseparate entries for %C?... and %C?(...), to make it more\n\tclear that both %C?green and %C(white bold) are supported.\n\n\t- xstrdup is not necessary in config\n\ttested, and it seems that the strdup actually is needed. Ideally\n\twe would avoid an extra strdup of the format itself (which is\n\trather needlessly copied to the static global *user_format), but\n\tthe alternative would be adding an entirely separate codepath\n\tfor \"pre-specified\" formats. It was an awful long way to go to\n\tavoid one extra strdup, so I just left the call to\n\tsave_user_format in.\n\n\t- could the code which checks for format/tformat/etc be shared?\n\tprobably, but I can't see a good way to do so.\n\n\t- (various confusion regarding the alias code)\n\tThe alias code sucked. It's been ripped out and replaced with a\n\tmuch saner recursive model for find_commit_format. Thanks for\n\tsteering me away from that mess.\n\n\t- setup_commit_formats() should be in setup_revisions()?\n\tWhile it might make the call-graph shorter, and would make\n\tsome dependencies explicit, I think that keeping\n\tsetup_commit_formats() in get_commit_format() makes more sense,\n\tby keeping \"commit format\" things together in one place. It's\n\talso less of a deviation from the code it was based on.\n\n\t- a = nothing, one = a, two = a. one is alias, two is not, why?\n\tNot sure. By the time I got to this one, the alias code had been\n\tcompletely changed and I couldn't reproduce. I'll declare this\n\tfixed.\n\nFinally, after consensus among those discussing it, the config option\nis now pretty.<name>, rather than format.pretty.<name>\n\nChanges unrelated to any mailing-list discussion:\n\n\t- ignore aliases with the same name as built-in formats\n\t- fix a bug in the last patch where --pretty=full output fuller\n\t- fix a bug in the last patch where --abbrev-commit effected raw\n\t- be explicit that a redefined alias should overwrite the old\n\nLots of changes from v2 of the patchset, but overall I think a smaller\nand cleaner patch.\n\nWill Palmer (5):\n  pretty: add conditional %C?colorname placeholders\n  pretty: make %H/%h/etc respect --abbrev[-commit]\n  pretty: make it easier to add new formats\n  pretty: add infrastructure to allow format aliases\n  pretty: add aliases for pretty formats\n\n Documentation/config.txt         |    9 ++\n Documentation/pretty-formats.txt |    9 ++-\n builtin/log.c                    |    2 +-\n builtin/rev-list.c               |    2 +\n builtin/shortlog.c               |    7 +-\n commit.h                         |    4 +-\n log-tree.c                       |    7 +-\n pretty.c                         |  228 +++++++++++++++++++++++++++++---------\n shortlog.h                       |    2 +-\n t/t4205-log-pretty-formats.sh    |  116 +++++++++++++++++++\n 10 files changed, 327 insertions(+), 59 deletions(-)\n create mode 100755 t/t4205-log-pretty-formats.sh\n"},{"id":"140646","messageId":"1272656128-2002-2-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"[PATCH v3 1/5] pretty: add conditional %C?colorname placeholders","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:24Z","receivedAt":"2010-04-30T19:35:24Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"Many commands are able to colorize, or not, depending on a user's\nconfiguration and whether output is being sent to a terminal. However,\nif a user explicitly specifies a --pretty format, color will always be\noutput, regardless of the destination. This would generally be okay, in\na \"do what I tell you, whether or not I should tell you to\" sense, but\nthe assumption fell apart when an alias was defined which may be run in\nvarious contexts: there was no way to specify \"use this color, but only\nif you normally would display color at all\"\n\nHere we add the %C?colorname placeholders which act just as the\n%Ccolorname placeholders, with the exception that the pretty_context is\nchecked to see if color should be used according to configuration\n\nSigned-off-by: Will Palmer <wmpalmer@gmail.com>\n---\n Documentation/pretty-formats.txt |    2 +\n builtin/log.c                    |    2 +-\n builtin/rev-list.c               |    1 +\n builtin/shortlog.c               |    5 ++-\n commit.h                         |    1 +\n log-tree.c                       |    1 +\n pretty.c                         |   49 +++++++++++++++++++++++------------\n shortlog.h                       |    2 +-\n t/t4205-log-pretty-formats.sh    |   52 ++++++++++++++++++++++++++++++++++++++\n 9 files changed, 94 insertions(+), 21 deletions(-)\n create mode 100755 t/t4205-log-pretty-formats.sh\n\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 1686a54..5861256 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -132,6 +132,8 @@ The placeholders are:\n - '%Cblue': switch color to blue\n - '%Creset': reset color\n - '%C(...)': color specification, as described in color.branch.* config option\n+- '%C?...': switch to specified color, as in %Cred, %Creset, etc, if color output is enabled\n+- '%C?(...)': switch to specified color specification, as in %C(...), if color output is enabled\n - '%m': left, right or boundary mark\n - '%n': newline\n - '%%': a raw '%'\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 6208703..a9fc6ea 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -740,7 +740,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,\n \tlog.in1 = 2;\n \tlog.in2 = 4;\n \tfor (i = 0; i < nr; i++)\n-\t\tshortlog_add_commit(&log, list[i]);\n+\t\tshortlog_add_commit(&log, list[i], rev);\n \n \tshortlog_output(&log);\n \ndiff --git a/builtin/rev-list.c b/builtin/rev-list.c\nindex 51ceb19..5a53862 100644\n--- a/builtin/rev-list.c\n+++ b/builtin/rev-list.c\n@@ -99,6 +99,7 @@ static void show_commit(struct commit *commit, void *data)\n \t\tstruct pretty_print_context ctx = {0};\n \t\tctx.abbrev = revs->abbrev;\n \t\tctx.date_mode = revs->date_mode;\n+\t\tctx.use_color = DIFF_OPT_TST(&revs->diffopt, COLOR_DIFF);\n \t\tpretty_print_commit(revs->commit_format, commit, &buf, &ctx);\n \t\tif (revs->graph) {\n \t\t\tif (buf.len) {\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex 06320f5..7aee491 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -136,13 +136,14 @@ static void read_from_stdin(struct shortlog *log)\n \t}\n }\n \n-void shortlog_add_commit(struct shortlog *log, struct commit *commit)\n+void shortlog_add_commit(struct shortlog *log, struct commit *commit, struct rev_info *rev)\n {\n \tconst char *author = NULL, *buffer;\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct strbuf ufbuf = STRBUF_INIT;\n \tstruct pretty_print_context ctx = {0};\n \n+\tctx.use_color = DIFF_OPT_TST(&rev->diffopt, COLOR_DIFF);\n \tpretty_print_commit(CMIT_FMT_RAW, commit, &buf, &ctx);\n \tbuffer = buf.buf;\n \twhile (*buffer && *buffer != '\\n') {\n@@ -183,7 +184,7 @@ static void get_from_rev(struct rev_info *rev, struct shortlog *log)\n \tif (prepare_revision_walk(rev))\n \t\tdie(\"revision walk setup failed\");\n \twhile ((commit = get_revision(rev)) != NULL)\n-\t\tshortlog_add_commit(log, commit);\n+\t\tshortlog_add_commit(log, commit, rev);\n }\n \n static int parse_uint(char const **arg, int comma, int defval)\ndiff --git a/commit.h b/commit.h\nindex 26ec8c0..b6caf91 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -71,6 +71,7 @@ struct pretty_print_context\n \tenum date_mode date_mode;\n \tint need_8bit_cte;\n \tint show_notes;\n+\tint use_color;\n \tstruct reflog_walk_info *reflog_info;\n };\n \ndiff --git a/log-tree.c b/log-tree.c\nindex d3ae969..6bb4748 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -282,6 +282,7 @@ void show_log(struct rev_info *opt)\n \tint abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;\n \tconst char *extra_headers = opt->extra_headers;\n \tstruct pretty_print_context ctx = {0};\n+\tctx.use_color = DIFF_OPT_TST(&opt->diffopt, COLOR_DIFF);\n \n \topt->loginfo = NULL;\n \tctx.show_notes = opt->show_notes;\ndiff --git a/pretty.c b/pretty.c\nindex 7cb3a2a..fdb5e16 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -634,35 +634,50 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,\n \tstruct format_commit_context *c = context;\n \tconst struct commit *commit = c->commit;\n \tconst char *msg = commit->buffer;\n+\tconst char *color_start;\n \tstruct commit_list *p;\n+\tint use_color = c->pretty_ctx->use_color;\n+\tint conditional_color = 0;\n \tint h1, h2;\n \n \t/* these are independent of the commit */\n \tswitch (placeholder[0]) {\n \tcase 'C':\n-\t\tif (placeholder[1] == '(') {\n+\t\tcolor_start = placeholder;\n+\t\tif (placeholder[1] == '?') {\n+\t\t\tcolor_start++;\n+\t\t\tconditional_color = 1;\n+\t\t}\n+\t\tif (color_start[1] == '(') {\n \t\t\tconst char *end = strchr(placeholder + 2, ')');\n \t\t\tchar color[COLOR_MAXLEN];\n \t\t\tif (!end)\n \t\t\t\treturn 0;\n-\t\t\tcolor_parse_mem(placeholder + 2,\n-\t\t\t\t\tend - (placeholder + 2),\n-\t\t\t\t\t\"--pretty format\", color);\n-\t\t\tstrbuf_addstr(sb, color);\n+\t\t\tif ( !conditional_color || use_color ) {\n+\t\t\t\tcolor_parse_mem(color_start + 2,\n+\t\t\t\t\t\tend - (color_start + 2),\n+\t\t\t\t\t\t\"--pretty format\", color);\n+\t\t\t\tstrbuf_addstr(sb, color);\n+\t\t\t}\n \t\t\treturn end - placeholder + 1;\n \t\t}\n-\t\tif (!prefixcmp(placeholder + 1, \"red\")) {\n-\t\t\tstrbuf_addstr(sb, GIT_COLOR_RED);\n-\t\t\treturn 4;\n-\t\t} else if (!prefixcmp(placeholder + 1, \"green\")) {\n-\t\t\tstrbuf_addstr(sb, GIT_COLOR_GREEN);\n-\t\t\treturn 6;\n-\t\t} else if (!prefixcmp(placeholder + 1, \"blue\")) {\n-\t\t\tstrbuf_addstr(sb, GIT_COLOR_BLUE);\n-\t\t\treturn 5;\n-\t\t} else if (!prefixcmp(placeholder + 1, \"reset\")) {\n-\t\t\tstrbuf_addstr(sb, GIT_COLOR_RESET);\n-\t\t\treturn 6;\n+\n+\t\tif (!prefixcmp(color_start + 1, \"red\")) {\n+\t\t\tif ( !conditional_color || use_color )\n+\t\t\t\tstrbuf_addstr(sb, GIT_COLOR_RED);\n+\t\t\treturn 4 + (conditional_color ? 1 : 0);\n+\t\t} else if (!prefixcmp(color_start + 1, \"green\")) {\n+\t\t\tif ( !conditional_color || use_color )\n+\t\t\t\tstrbuf_addstr(sb, GIT_COLOR_GREEN);\n+\t\t\treturn 6 + (conditional_color ? 1 : 0);\n+\t\t} else if (!prefixcmp(color_start + 1, \"blue\")) {\n+\t\t\tif ( !conditional_color || use_color )\n+\t\t\t\tstrbuf_addstr(sb, GIT_COLOR_BLUE);\n+\t\t\treturn 5 + (conditional_color ? 1 : 0);\n+\t\t} else if (!prefixcmp(color_start + 1, \"reset\")) {\n+\t\t\tif ( !conditional_color || use_color )\n+\t\t\t\tstrbuf_addstr(sb, GIT_COLOR_RESET);\n+\t\t\treturn 6 + (conditional_color ? 1 : 0);\n \t\t} else\n \t\t\treturn 0;\n \tcase 'n':\t\t/* newline */\ndiff --git a/shortlog.h b/shortlog.h\nindex bc02cc2..43498a0 100644\n--- a/shortlog.h\n+++ b/shortlog.h\n@@ -20,7 +20,7 @@ struct shortlog {\n \n void shortlog_init(struct shortlog *log);\n \n-void shortlog_add_commit(struct shortlog *log, struct commit *commit);\n+void shortlog_add_commit(struct shortlog *log, struct commit *commit, struct rev_info *rev);\n \n void shortlog_output(struct shortlog *log);\n \ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nnew file mode 100755\nindex 0000000..b7ec943\n--- /dev/null\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -0,0 +1,52 @@\n+#!/bin/sh\n+#\n+# Released into Public Domain by Will Palmer 2010\n+#\n+\n+test_description='Test pretty formats'\n+. ./test-lib.sh\n+\n+test_expect_success \"set up basic repos\" \\\n+\t\">foo &&\n+\t>bar &&\n+\tgit add foo &&\n+\ttest_tick &&\n+\tgit commit -m initial &&\n+\tgit add bar &&\n+\ttest_tick &&\n+\tgit commit -m 'add bar'\"\n+\n+for flag in false true always; do\n+for color in red green blue reset; do\n+\n+\tmake_expected=\"git config --get-color no.such.slot $color >expected\"\n+\ttest_expect_success \"%C$color with color.ui $flag\" \\\n+\t\t\"$make_expected &&\n+\t\tgit config color.ui $flag &&\n+\t\tgit log -1 --pretty=format:'%C$color' > actual &&\n+\t\ttest_cmp expected actual\"\n+\n+\n+\ttest_expect_success \"%C($color) with color.ui $flag\" \\\n+\t\t\"$make_expected &&\n+\t\tgit config color.ui $flag &&\n+\t\tgit log -1 --pretty=format:'%C($color)' > actual &&\n+\t\ttest_cmp expected actual\"\n+\n+\t[ ! \"$flag\" = \"always\" ] && make_expected=\">expected\"\n+\ttest_expect_success \"%C?$color with color.ui $flag\" \\\n+\t\t\"$make_expected &&\n+\t\tgit config color.ui $flag &&\n+\t\tgit log -1 --pretty=format:'%C?$color' > actual &&\n+\t\ttest_cmp expected actual\"\n+\n+\ttest_expect_success \"%C?($color) with color.ui $flag\" \\\n+\t\t\"$make_expected &&\n+\t\tgit config color.ui $flag &&\n+\t\tgit log -1 --pretty=format:'%C?($color)' > actual &&\n+\t\ttest_cmp expected actual\"\n+\n+done\n+done\n+\n+test_done\n-- \n1.7.1.rc1.13.gbb0a0a.dirty\n"},{"id":"140652","messageId":"1272656128-2002-3-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"[PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:25Z","receivedAt":"2010-04-30T19:35:25Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"Prior to this, the output of %H was always 40 characters long, and the\noutput of %h always DEFAULT_ABBREV characters long, without regard to\nwhether --abbrev-commit or --abbrev had been passed.\n\nHere we make \"git log --pretty=%H --abbrev-commit\" synonymous with\n\"git log --pretty=%h\", and make %h/abbreviated-%H respect the length\nspecified for --abbrev.\n\nThe same is applied to other commit-placeholders %P and %p, and\n--abbrev is respected for %t, though %T is not changed.\n\nSigned-off-by: Will Palmer <wmpalmer@gmail.com>\n---\n builtin/rev-list.c            |    1 +\n builtin/shortlog.c            |    2 ++\n commit.h                      |    3 ++-\n log-tree.c                    |    6 ++++--\n pretty.c                      |   30 +++++++++++++++++++-----------\n t/t4205-log-pretty-formats.sh |   17 +++++++++++++++++\n 6 files changed, 45 insertions(+), 14 deletions(-)\n\ndiff --git a/builtin/rev-list.c b/builtin/rev-list.c\nindex 5a53862..1d1e59c 100644\n--- a/builtin/rev-list.c\n+++ b/builtin/rev-list.c\n@@ -98,6 +98,7 @@ static void show_commit(struct commit *commit, void *data)\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tstruct pretty_print_context ctx = {0};\n \t\tctx.abbrev = revs->abbrev;\n+\t\tctx.abbrev_commit = revs->abbrev_commit;\n \t\tctx.date_mode = revs->date_mode;\n \t\tctx.use_color = DIFF_OPT_TST(&revs->diffopt, COLOR_DIFF);\n \t\tpretty_print_commit(revs->commit_format, commit, &buf, &ctx);\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex 7aee491..5c0721c 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -143,6 +143,8 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit, struct rev\n \tstruct strbuf ufbuf = STRBUF_INIT;\n \tstruct pretty_print_context ctx = {0};\n \n+\tctx.abbrev = rev->abbrev;\n+\tctx.abbrev_commit = rev->abbrev_commit;\n \tctx.use_color = DIFF_OPT_TST(&rev->diffopt, COLOR_DIFF);\n \tpretty_print_commit(CMIT_FMT_RAW, commit, &buf, &ctx);\n \tbuffer = buf.buf;\ndiff --git a/commit.h b/commit.h\nindex b6caf91..4c52069 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -65,7 +65,8 @@ enum cmit_fmt {\n \n struct pretty_print_context\n {\n-\tint abbrev;\n+\tint abbrev; /* length of abbreviated hashes */\n+\tint abbrev_commit; /* whether or not to abbreviate commit hashes */\n \tconst char *subject;\n \tconst char *after_subject;\n \tenum date_mode date_mode;\ndiff --git a/log-tree.c b/log-tree.c\nindex 6bb4748..02233ed 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -279,10 +279,13 @@ void show_log(struct rev_info *opt)\n \tstruct strbuf msgbuf = STRBUF_INIT;\n \tstruct log_info *log = opt->loginfo;\n \tstruct commit *commit = log->commit, *parent = log->parent;\n-\tint abbrev_commit = opt->abbrev_commit ? opt->abbrev : 40;\n+\tint abbrev_commit;\n \tconst char *extra_headers = opt->extra_headers;\n \tstruct pretty_print_context ctx = {0};\n+\tctx.abbrev = opt->diffopt.abbrev;\n+\tctx.abbrev_commit = opt->abbrev_commit && opt->commit_format != CMIT_FMT_RAW;\n \tctx.use_color = DIFF_OPT_TST(&opt->diffopt, COLOR_DIFF);\n+\tabbrev_commit = ctx.abbrev_commit ? ctx.abbrev : 40;\n \n \topt->loginfo = NULL;\n \tctx.show_notes = opt->show_notes;\n@@ -411,7 +414,6 @@ void show_log(struct rev_info *opt)\n \tif (ctx.need_8bit_cte >= 0)\n \t\tctx.need_8bit_cte = has_non_ascii(opt->add_signoff);\n \tctx.date_mode = opt->date_mode;\n-\tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n \tctx.reflog_info = opt->reflog_info;\n \tpretty_print_commit(opt->commit_format, commit, &msgbuf, &ctx);\ndiff --git a/pretty.c b/pretty.c\nindex fdb5e16..60ed9f6 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -725,13 +725,16 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,\n \n \tswitch (placeholder[0]) {\n \tcase 'H':\t\t/* commit hash */\n-\t\tstrbuf_addstr(sb, sha1_to_hex(commit->object.sha1));\n-\t\treturn 1;\n \tcase 'h':\t\t/* abbreviated commit hash */\n+\t\tif (placeholder[0] != 'h' && !c->pretty_ctx->abbrev_commit) {\n+\t\t\tstrbuf_addstr(sb, sha1_to_hex(commit->object.sha1));\n+\t\t\treturn 1;\n+\t\t}\n+\n \t\tif (add_again(sb, &c->abbrev_commit_hash))\n \t\t\treturn 1;\n \t\tstrbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,\n-\t\t                                     DEFAULT_ABBREV));\n+\t\t\t\t\t\t     c->pretty_ctx->abbrev));\n \t\tc->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;\n \t\treturn 1;\n \tcase 'T':\t\t/* tree hash */\n@@ -741,24 +744,29 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,\n \t\tif (add_again(sb, &c->abbrev_tree_hash))\n \t\t\treturn 1;\n \t\tstrbuf_addstr(sb, find_unique_abbrev(commit->tree->object.sha1,\n-\t\t                                     DEFAULT_ABBREV));\n+\t\t\t\t\t\t     c->pretty_ctx->abbrev));\n \t\tc->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;\n \t\treturn 1;\n \tcase 'P':\t\t/* parent hashes */\n-\t\tfor (p = commit->parents; p; p = p->next) {\n-\t\t\tif (p != commit->parents)\n-\t\t\t\tstrbuf_addch(sb, ' ');\n-\t\t\tstrbuf_addstr(sb, sha1_to_hex(p->item->object.sha1));\n-\t\t}\n-\t\treturn 1;\n \tcase 'p':\t\t/* abbreviated parent hashes */\n+\t\tif (placeholder[0] != 'p' && !c->pretty_ctx->abbrev_commit) {\n+\t\t\tfor (p = commit->parents; p; p = p->next) {\n+\t\t\t\tif (p != commit->parents)\n+\t\t\t\t\tstrbuf_addch(sb, ' ');\n+\t\t\t\tstrbuf_addstr(sb,\n+\t\t\t\t\t      sha1_to_hex(p->item->object.sha1));\n+\t\t\t}\n+\t\t\treturn 1;\n+\t\t}\n+\n \t\tif (add_again(sb, &c->abbrev_parent_hashes))\n \t\t\treturn 1;\n \t\tfor (p = commit->parents; p; p = p->next) {\n \t\t\tif (p != commit->parents)\n \t\t\t\tstrbuf_addch(sb, ' ');\n \t\t\tstrbuf_addstr(sb, find_unique_abbrev(\n-\t\t\t\t\tp->item->object.sha1, DEFAULT_ABBREV));\n+\t\t\t\t\tp->item->object.sha1,\n+\t\t\t\t\tc->pretty_ctx->abbrev));\n \t\t}\n \t\tc->abbrev_parent_hashes.len = sb->len -\n \t\t                              c->abbrev_parent_hashes.off;\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex b7ec943..a33f157 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -48,5 +48,22 @@ for color in red green blue reset; do\n \n done\n done\n+test_expect_success \"reset color flags\" \"git config --unset color.ui\"\n+\n+test_expect_success \"%H with --abbrev-commit should be synonym for %h\" \\\n+\t\"git log -1 --pretty='format:%H' --abbrev-commit > expected &&\n+\tgit log -1 --pretty='format:%h' > actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_success \"%H with --abbrev-commit should respect --abbrev\" \\\n+\t'test 20 = $(git log -1 --pretty=\"format:%H\" --abbrev-commit --abbrev=20 | wc -c)'\n+\n+test_expect_success \"%h should respect --abbrev\" \\\n+\t'test 20 = $(git log -1 --pretty=\"format:%h\" --abbrev-commit --abbrev=20 | wc -c)'\n+\n+test_expect_success \"log --pretty=raw should NOT respect --abbrev-commit\" \\\n+\t'git log -1 --pretty=raw > expected &&\n+\tgit log -1 --pretty=raw --abbrev-commit > actual &&\n+\ttest_cmp expected actual'\n \n test_done\n-- \n1.7.1.rc1.13.gbb0a0a.dirty\n"},{"id":"140648","messageId":"1272656128-2002-4-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"[PATCH v3 3/5] pretty: make it easier to add new formats","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:26Z","receivedAt":"2010-04-30T19:35:26Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"As the first step towards creating aliases, we make it easier to add new\nformats to the list of builtin formats. To do this, we move the\ninitialization of the formats array into a new function,\nsetup_commit_formats(), which we can easily extend later. Then, rather\nthan looping through only the list of known formats, we make a more\ngeneric find_commit_format function, which will return the commit format\nwhose name is the shortest which is prefixed with the passed-in sought\nformat, the same rules which were more-or-less hard-coded in before.\n\nSigned-off-by: Will Palmer <wmpalmer@gmail.com>\n---\n pretty.c |   81 +++++++++++++++++++++++++++++++++++++++++++------------------\n 1 files changed, 57 insertions(+), 24 deletions(-)\n\ndiff --git a/pretty.c b/pretty.c\nindex 60ed9f6..55d5721 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -11,6 +11,13 @@\n #include \"reflog-walk.h\"\n \n static char *user_format;\n+static struct cmt_fmt_map {\n+\tconst char *name;\n+\tenum cmit_fmt format;\n+\tint is_tformat;\n+} *commit_formats = NULL;\n+static size_t commit_formats_len = 0;\n+static struct cmt_fmt_map *find_commit_format(const char *sought);\n \n static void save_user_format(struct rev_info *rev, const char *cp, int is_tformat)\n {\n@@ -21,22 +28,51 @@ static void save_user_format(struct rev_info *rev, const char *cp, int is_tforma\n \trev->commit_format = CMIT_FMT_USERFORMAT;\n }\n \n-void get_commit_format(const char *arg, struct rev_info *rev)\n+static void setup_commit_formats(void)\n {\n-\tint i;\n-\tstatic struct cmt_fmt_map {\n-\t\tconst char *n;\n-\t\tsize_t cmp_len;\n-\t\tenum cmit_fmt v;\n-\t} cmt_fmts[] = {\n-\t\t{ \"raw\",\t1,\tCMIT_FMT_RAW },\n-\t\t{ \"medium\",\t1,\tCMIT_FMT_MEDIUM },\n-\t\t{ \"short\",\t1,\tCMIT_FMT_SHORT },\n-\t\t{ \"email\",\t1,\tCMIT_FMT_EMAIL },\n-\t\t{ \"full\",\t5,\tCMIT_FMT_FULL },\n-\t\t{ \"fuller\",\t5,\tCMIT_FMT_FULLER },\n-\t\t{ \"oneline\",\t1,\tCMIT_FMT_ONELINE },\n+\tstruct cmt_fmt_map builtin_formats[] = {\n+\t\t{ \"raw\",\tCMIT_FMT_RAW,\t\t0 },\n+\t\t{ \"medium\",\tCMIT_FMT_MEDIUM,\t0 },\n+\t\t{ \"short\",\tCMIT_FMT_SHORT,\t\t0 },\n+\t\t{ \"email\",\tCMIT_FMT_EMAIL,\t\t0 },\n+\t\t{ \"fuller\",\tCMIT_FMT_FULLER,\t0 },\n+\t\t{ \"full\",\tCMIT_FMT_FULL,\t\t0 },\n+\t\t{ \"oneline\",\tCMIT_FMT_ONELINE,\t1 }\n \t};\n+\tcommit_formats_len = ARRAY_SIZE(builtin_formats);\n+\tcommit_formats = xcalloc(commit_formats_len,\n+\t\t\t\t sizeof(*builtin_formats));\n+\tmemcpy(commit_formats, builtin_formats,\n+\t       sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats));\n+}\n+\n+static struct cmt_fmt_map *find_commit_format(const char *sought)\n+{\n+\tstruct cmt_fmt_map *found = NULL;\n+\tsize_t found_match_len;\n+\tint i;\n+\n+\tif (!commit_formats)\n+\t\tsetup_commit_formats();\n+\n+\tfor (i = 0; i < commit_formats_len; i++) {\n+\t\tsize_t match_len;\n+\n+\t\tif( prefixcmp(commit_formats[i].name, sought) )\n+\t\t\tcontinue;\n+\n+\t\tmatch_len = strlen(commit_formats[i].name);\n+\t\tif( found == NULL || found_match_len > match_len ){\n+\t\t\tfound = &commit_formats[i];\n+\t\t\tfound_match_len = match_len;\n+\t\t}\n+\t}\n+\treturn found;\n+}\n+\n+void get_commit_format(const char *arg, struct rev_info *rev)\n+{\n+\tstruct cmt_fmt_map *commit_format;\n \n \trev->use_terminator = 0;\n \tif (!arg || !*arg) {\n@@ -47,21 +83,18 @@ void get_commit_format(const char *arg, struct rev_info *rev)\n \t\tsave_user_format(rev, strchr(arg, ':') + 1, arg[0] == 't');\n \t\treturn;\n \t}\n-\tfor (i = 0; i < ARRAY_SIZE(cmt_fmts); i++) {\n-\t\tif (!strncmp(arg, cmt_fmts[i].n, cmt_fmts[i].cmp_len) &&\n-\t\t    !strncmp(arg, cmt_fmts[i].n, strlen(arg))) {\n-\t\t\tif (cmt_fmts[i].v == CMIT_FMT_ONELINE)\n-\t\t\t\trev->use_terminator = 1;\n-\t\t\trev->commit_format = cmt_fmts[i].v;\n-\t\t\treturn;\n-\t\t}\n-\t}\n+\n \tif (strchr(arg, '%')) {\n \t\tsave_user_format(rev, arg, 1);\n \t\treturn;\n \t}\n \n-\tdie(\"invalid --pretty format: %s\", arg);\n+\tcommit_format = find_commit_format(arg);\n+\tif( !commit_format )\n+\t\tdie(\"invalid --pretty format: %s\", arg);\n+\n+\trev->commit_format = commit_format->format;\n+\trev->use_terminator = commit_format->is_tformat;\n }\n \n /*\n-- \n1.7.1.rc1.13.gbb0a0a.dirty\n"},{"id":"140650","messageId":"1272656128-2002-5-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"[PATCH v3 4/5] pretty: add infrastructure to allow format aliases","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:27Z","receivedAt":"2010-04-30T19:35:27Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"here we modify the find_commit_format function to make it recursively\ndereference aliases when they are specified. At this point, there are\nno aliases specified and there is no way to specify an alias, but the\nsupport is there for any which are added.\n\nSigned-off-by: Will Palmer <wmpalmer@gmail.com>\n---\n pretty.c |   23 ++++++++++++++++++++---\n 1 files changed, 20 insertions(+), 3 deletions(-)\n\ndiff --git a/pretty.c b/pretty.c\nindex 55d5721..3d1c4a9 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -15,6 +15,8 @@ static struct cmt_fmt_map {\n \tconst char *name;\n \tenum cmit_fmt format;\n \tint is_tformat;\n+\tint is_alias;\n+\tconst char *user_format;\n } *commit_formats = NULL;\n static size_t commit_formats_len = 0;\n static struct cmt_fmt_map *find_commit_format(const char *sought);\n@@ -46,14 +48,15 @@ static void setup_commit_formats(void)\n \t       sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats));\n }\n \n-static struct cmt_fmt_map *find_commit_format(const char *sought)\n+static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,\n+\t\t\t\t\t\t\tint num_redirections)\n {\n \tstruct cmt_fmt_map *found = NULL;\n \tsize_t found_match_len;\n \tint i;\n \n-\tif (!commit_formats)\n-\t\tsetup_commit_formats();\n+\tif (num_redirections >= commit_formats_len)\n+\t\treturn NULL;\n \n \tfor (i = 0; i < commit_formats_len; i++) {\n \t\tsize_t match_len;\n@@ -67,9 +70,23 @@ static struct cmt_fmt_map *find_commit_format(const char *sought)\n \t\t\tfound_match_len = match_len;\n \t\t}\n \t}\n+\n+\tif (found && found->is_alias) {\n+\t\tfound = find_commit_format_recursive(found->user_format,\n+\t\t\t\t\t\t     num_redirections+1);\n+\t}\n+\n \treturn found;\n }\n \n+static struct cmt_fmt_map *find_commit_format(const char *sought)\n+{\n+\tif (!commit_formats)\n+\t\tsetup_commit_formats();\n+\n+\treturn find_commit_format_recursive(sought, 0);\n+}\n+\n void get_commit_format(const char *arg, struct rev_info *rev)\n {\n \tstruct cmt_fmt_map *commit_format;\n-- \n1.7.1.rc1.13.gbb0a0a.dirty\n"},{"id":"140651","messageId":"1272656128-2002-6-git-send-email-wmpalmer@gmail.com","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"[PATCH v3 5/5] pretty: add aliases for pretty formats","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-04-30T19:35:28Z","receivedAt":"2010-04-30T19:35:28Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"previously the only ways to alias a --pretty format within git were\neither to set the format as your default format (via the format.pretty\nconfiguration variable), or by using a regular git alias. This left the\ndefinition of more complicated formats to the realm of \"builtin or\nnothing\", with user-defined formats usually being reserved for quick\none-offs.\n\nHere we allow user-defined formats to enjoy more or less the same\nbenefits of builtins. By defining pretty.myalias, \"myalias\" can be\nused in place of whatever would normally come after --pretty=. This\ncan be a format:, tformat:, raw (ie, defaulting to tformat), or the name\nof another builtin or user-defined pretty format.\n\nSigned-off-by: Will Palmer <wmpalmer@gmail.com>\n---\n Documentation/config.txt         |    9 ++++++\n Documentation/pretty-formats.txt |    7 ++++-\n pretty.c                         |   57 ++++++++++++++++++++++++++++++++++++-\n t/t4205-log-pretty-formats.sh    |   47 +++++++++++++++++++++++++++++++\n 4 files changed, 117 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 92f851e..3987b2d 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -1466,6 +1466,15 @@ pager.<cmd>::\n \tit takes precedence over this option.  To disable pagination for\n \tall commands, set `core.pager` or `GIT_PAGER` to `cat`.\n \n+pretty.<name>::\n+\tAlias for a --pretty= format string, as specified in\n+\tlinkgit:git-log[1]. Any aliases defined here can be used just\n+\tas the built-in pretty formats could. For example, defining\n+\t\"format.pretty.hash = format:%H\" would cause the invocation\n+\t\"git log --pretty=hash\" to be equivalent to running\n+\t\"git log --pretty=format:%H\". Note that an alias with the same\n+\tname as a built-in format will be silently ignored.\n+\n pull.octopus::\n \tThe default merge strategy to use when pulling multiple branches\n \tat once.\ndiff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt\nindex 5861256..bb0f0d2 100644\n--- a/Documentation/pretty-formats.txt\n+++ b/Documentation/pretty-formats.txt\n@@ -11,7 +11,12 @@ have limited your view of history: for example, if you are\n only interested in changes related to a certain directory or\n file.\n \n-Here are some additional details for each format:\n+There are several built-in formats, and you can define\n+additional formats by setting a pretty.<name>\n+config option to either another format name, or a\n+'format:' string, as described below (see\n+linkgit:git-config[1]). Here are the details of the\n+built-in formats:\n \n * 'oneline'\n \ndiff --git a/pretty.c b/pretty.c\nindex 3d1c4a9..9780e32 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -18,7 +18,9 @@ static struct cmt_fmt_map {\n \tint is_alias;\n \tconst char *user_format;\n } *commit_formats = NULL;\n+static size_t builtin_formats_len = 0;\n static size_t commit_formats_len = 0;\n+static size_t commit_formats_alloc = 0;\n static struct cmt_fmt_map *find_commit_format(const char *sought);\n \n static void save_user_format(struct rev_info *rev, const char *cp, int is_tformat)\n@@ -30,6 +32,51 @@ static void save_user_format(struct rev_info *rev, const char *cp, int is_tforma\n \trev->commit_format = CMIT_FMT_USERFORMAT;\n }\n \n+static int git_pretty_formats_config(const char *var, const char *value, void *cb)\n+{\n+\tstruct cmt_fmt_map *commit_format = NULL;\n+\tconst char *name;\n+\tconst char *fmt;\n+\tint i;\n+\n+\tif (prefixcmp(var, \"pretty.\"))\n+\t\treturn 0;\n+\n+\tname = &var[7];\n+\tfor (i=0; i<builtin_formats_len; i++) {\n+\t\tif (!strcmp(commit_formats[i].name, name))\n+\t\t\treturn 0;\n+\t}\n+\n+\tfor (i=builtin_formats_len; i<commit_formats_len; i++) {\n+\t\tif (!strcmp(commit_formats[i].name, name)) {\n+\t\t\tcommit_format = &commit_formats[i];\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (!commit_format) {\n+\t\tALLOC_GROW(commit_formats, commit_formats_len+1,\n+\t\t\t   commit_formats_alloc);\n+\t\tcommit_format = &commit_formats[commit_formats_len];\n+\t\tcommit_formats_len++;\n+\t}\n+\n+\tcommit_format->name = xstrdup(name);\n+\tcommit_format->format = CMIT_FMT_USERFORMAT;\n+\tgit_config_string(&fmt, var, value);\n+\tif (!prefixcmp(fmt, \"format:\") || !prefixcmp(fmt, \"tformat:\")) {\n+\t\tcommit_format->is_tformat = fmt[0] == 't';\n+\t\tfmt = strchr(fmt, ':') + 1;\n+\t} else if (strchr(fmt, '%'))\n+\t\tcommit_format->is_tformat = 1;\n+\telse\n+\t\tcommit_format->is_alias = 1;\n+\tcommit_format->user_format = fmt;\n+\n+\treturn 0;\n+}\n+\n static void setup_commit_formats(void)\n {\n \tstruct cmt_fmt_map builtin_formats[] = {\n@@ -42,10 +89,12 @@ static void setup_commit_formats(void)\n \t\t{ \"oneline\",\tCMIT_FMT_ONELINE,\t1 }\n \t};\n \tcommit_formats_len = ARRAY_SIZE(builtin_formats);\n-\tcommit_formats = xcalloc(commit_formats_len,\n-\t\t\t\t sizeof(*builtin_formats));\n+\tbuiltin_formats_len = commit_formats_len;\n+\tALLOC_GROW(commit_formats, commit_formats_len, commit_formats_alloc);\n \tmemcpy(commit_formats, builtin_formats,\n \t       sizeof(*builtin_formats)*ARRAY_SIZE(builtin_formats));\n+\n+\tgit_config(git_pretty_formats_config, NULL);\n }\n \n static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,\n@@ -112,6 +161,10 @@ void get_commit_format(const char *arg, struct rev_info *rev)\n \n \trev->commit_format = commit_format->format;\n \trev->use_terminator = commit_format->is_tformat;\n+\tif( commit_format->format == CMIT_FMT_USERFORMAT ){\n+\t\tsave_user_format(rev, commit_format->user_format,\n+\t\t\t\t commit_format->is_tformat);\n+\t}\n }\n \n /*\ndiff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\nindex a33f157..d8673fb 100755\n--- a/t/t4205-log-pretty-formats.sh\n+++ b/t/t4205-log-pretty-formats.sh\n@@ -66,4 +66,51 @@ test_expect_success \"log --pretty=raw should NOT respect --abbrev-commit\" \\\n \tgit log -1 --pretty=raw --abbrev-commit > actual &&\n \ttest_cmp expected actual'\n \n+test_expect_success \"alias builtin format\" \\\n+\t\"git log --pretty=oneline >expected &&\n+\tgit config pretty.test-alias oneline &&\n+\tgit log --pretty=test-alias >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_success \"alias masking builtin format\" \\\n+\t\"git log --pretty=oneline >expected &&\n+\tgit config pretty.oneline '%H' &&\n+\tgit log --pretty=oneline >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_success \"alias user-defined format\" \\\n+\t\"git log --pretty='format:%h' >expected &&\n+\tgit config pretty.test-alias 'format:%h' &&\n+\tgit log --pretty=test-alias >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_success \"alias user-defined tformat\" \\\n+\t\"git log --pretty='tformat:%h' >expected &&\n+\tgit config pretty.test-alias 'tformat:%h' &&\n+\tgit log --pretty=test-alias >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_code 128 \"alias non-existant format\" \\\n+\t\"git config pretty.test-alias format-that-will-never-exist &&\n+\tgit log --pretty=test-alias\"\n+\n+test_expect_success \"alias of an alias\" \\\n+\t\"git log --pretty='tformat:%h' >expected &&\n+\tgit config pretty.test-foo 'tformat:%h' &&\n+\tgit config pretty.test-bar test-foo &&\n+\tgit log --pretty=test-bar >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_success \"alias masking an alias\" \\\n+\t\"git log --pretty=format:'Two %H' >expected &&\n+\tgit config pretty.duplicate 'format:One %H' &&\n+\tgit config --add pretty.duplicate 'format:Two %H' &&\n+\tgit log --pretty=duplicate >actual &&\n+\ttest_cmp expected actual\"\n+\n+test_expect_code 128 \"alias loop\" \\\n+\t\"git config pretty.test-foo test-bar &&\n+\tgit config pretty.test-bar test-foo &&\n+\tgit log --pretty=test-foo\"\n+\n test_done\n-- \n1.7.1.rc1.13.gbb0a0a.dirty\n"},{"id":"140720","messageId":"7v39yb0zfh.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272656128-2002-1-git-send-email-wmpalmer@gmail.com","subject":"Re: [PATCH v3 0/5] pretty: format aliases","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T03:12:34Z","receivedAt":"2010-05-02T03:12:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thanks.  Overall I like the direction this is going.\n\nThere however are too many style violations that I prefer not to fix\nmyself.\n\n * Format if/while/switch etc. like this:\n\n\tif (expression) {\n        \tstatement;\n                ...\n\t}\n\n   not like this:\n\n\tif( expression ){\n        \t...\n\n   - Have one SP between syntactic keyword and an open parenthesis;\n   - Do not have extra SP before or after the expression inside\n     parentheses;\n   - Have one SP between a close parenthesis and an open brace.\n\n * do not initialise statics to 0 or NULL; e.g. not like\n    \n\tstatic size_t commit_formats_len = 0;\n\n   but like\n\n\tstatic size_t commit_formats_len;\n\n * Do not omit SP around operators.\n\n\tfor (i = 0; i < builtin_formats_len; i++) {\n        \t...\n\n   I.e. not like this:\n\n\tfor (i=0; i<builtin_formats_len; i++) {\n"},{"id":"140722","messageId":"7vvdb7yp1u.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272656128-2002-2-git-send-email-wmpalmer@gmail.com","subject":"Re: [PATCH v3 1/5] pretty: add conditional %C?colorname placeholders","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T03:12:45Z","receivedAt":"2010-05-02T03:12:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Will Palmer <wmpalmer@gmail.com> writes:\n\n> diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh\n> new file mode 100755\n> index 0000000..b7ec943\n> --- /dev/null\n> +++ b/t/t4205-log-pretty-formats.sh\n> @@ -0,0 +1,52 @@\n> +#!/bin/sh\n> +#\n> +# Released into Public Domain by Will Palmer 2010\n> +#\n\nHmm...\n\n> +test_description='Test pretty formats'\n> +. ./test-lib.sh\n> +\n> +test_expect_success \"set up basic repos\" \\\n> +\t\">foo &&\n> +\t>bar &&\n> +\tgit add foo &&\n> +\ttest_tick &&\n> +\tgit commit -m initial &&\n> +\tgit add bar &&\n> +\ttest_tick &&\n> +\tgit commit -m 'add bar'\"\n\nJust a style thing, but it is easier to read to write:\n\n        test_expect_success 'set up basic repos' '\n                >foo &&\n                >bar &&\n                ...\n        '\n\n> +for flag in false true always; do\n> +for color in red green blue reset; do\n> +\n> +\tmake_expected=\"git config --get-color no.such.slot $color >expected\"\n> +\ttest_expect_success \"%C$color with color.ui $flag\" \\\n> +\t\t\"$make_expected &&\n> +\t\tgit config color.ui $flag &&\n> +\t\tgit log -1 --pretty=format:'%C$color' > actual &&\n> +\t\ttest_cmp expected actual\"\n\nI would really prefer to see a test that checks output with real contents,\nnot just \"switch to color\".  E.g. --format=\"Title: %C${color}%s%C(normal)\"\nor something like that.\n\nAlso you probably would want to make this one round into a shell function\ne.g.\n\n\tmake_expected ()\n        {\n        \tgit config --get-color no.such.slot \"$1\"\n\t}\n\n\trun_format_test ()\n        {\n\t\tflag=$1 color=$2\n                test_expect_success \"%C$color with ...\" '\n\t\t\tmake_expected $color >expected\n                        git config color.ui $flag &&\n                        git log -1 --pretty=format:'%C($color)' >actual &&\n                        test_cmp expected actual\"\n                '\n                ...\n\t}\n\nand then run this loop:\n\n\tfor flag in flase true always\n        do\n        \tfor color in red green blue reset\n                do\n                \trun_format_test $flag $color\n\t\tdone\n\tdone\n"},{"id":"140721","messageId":"7vocgzyp1f.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272656128-2002-3-git-send-email-wmpalmer@gmail.com","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T03:13:00Z","receivedAt":"2010-05-02T03:13:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Will Palmer <wmpalmer@gmail.com> writes:\n\n> Prior to this, the output of %H was always 40 characters long, and the\n> output of %h always DEFAULT_ABBREV characters long, without regard to\n> whether --abbrev-commit or --abbrev had been passed.\n>\n> Here we make \"git log --pretty=%H --abbrev-commit\" synonymous with\n> \"git log --pretty=%h\", and make %h/abbreviated-%H respect the length\n> specified for --abbrev.\n\nI think it is a good change to make %h follow --abbrev, but %H should stay\nthe full length no matter what (otherwise why would anybody use %H not %h?).\n"},{"id":"140723","messageId":"7vhbmryp10.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272656128-2002-5-git-send-email-wmpalmer@gmail.com","subject":"Re: [PATCH v3 4/5] pretty: add infrastructure to allow format aliases","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T03:13:15Z","receivedAt":"2010-05-02T03:13:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Will Palmer <wmpalmer@gmail.com> writes:\n\n> -static struct cmt_fmt_map *find_commit_format(const char *sought)\n> +static struct cmt_fmt_map *find_commit_format_recursive(const char *sought,\n> +\t\t\t\t\t\t\tint num_redirections)\n>  {\n>  \tstruct cmt_fmt_map *found = NULL;\n>  \tsize_t found_match_len;\n>  \tint i;\n>  \n> -\tif (!commit_formats)\n> -\t\tsetup_commit_formats();\n> +\tif (num_redirections >= commit_formats_len)\n> +\t\treturn NULL;\n\nNice trick to avoid a loopy definition chain.\n\nI however wonder if we would want to be more helpful to the users to\ndiagnose this error by saying something here with error(), instead of just\nletting the caller say \"invalid --pretty format: %s\".\n"},{"id":"140724","messageId":"7vaasjyozt.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272656128-2002-6-git-send-email-wmpalmer@gmail.com","subject":"Re: [PATCH v3 5/5] pretty: add aliases for pretty formats","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T03:13:58Z","receivedAt":"2010-05-02T03:13:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This looks sensible.\n\nI didn't follow the config namespace discussions, though.  Is everybody\nhappy with the naming used in this patch?\n"},{"id":"140725","messageId":"20100502044506.GA14776@coredump.intra.peff.net","threadId":"23641","inReplyTo":"7vocgzyp1f.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-02T04:45:06Z","receivedAt":"2010-05-02T04:45:06Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 01, 2010 at 08:13:00PM -0700, Junio C Hamano wrote:\n\n> Will Palmer <wmpalmer@gmail.com> writes:\n> \n> > Prior to this, the output of %H was always 40 characters long, and the\n> > output of %h always DEFAULT_ABBREV characters long, without regard to\n> > whether --abbrev-commit or --abbrev had been passed.\n> >\n> > Here we make \"git log --pretty=%H --abbrev-commit\" synonymous with\n> > \"git log --pretty=%h\", and make %h/abbreviated-%H respect the length\n> > specified for --abbrev.\n> \n> I think it is a good change to make %h follow --abbrev, but %H should stay\n> the full length no matter what (otherwise why would anybody use %H not %h?).\n\nBut I thought the point of %h was to be abbreviated? If it follows\n--abbrev, then \"git log --format=%h\" would show the full sha1, no?\n\n-Peff\n"},{"id":"140726","messageId":"20100502044726.GB14776@coredump.intra.peff.net","threadId":"23641","inReplyTo":"7vaasjyozt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 5/5] pretty: add aliases for pretty formats","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-02T04:47:26Z","receivedAt":"2010-05-02T04:47:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 01, 2010 at 08:13:58PM -0700, Junio C Hamano wrote:\n\n> I didn't follow the config namespace discussions, though.  Is everybody\n> happy with the naming used in this patch?\n\nYes, I am happy with pretty.*. But:\n\nOn Fri, Apr 30, 2010 at 08:35:28PM +0100, Will Palmer wrote:\n\n> +pretty.<name>::\n> +\tAlias for a --pretty= format string, as specified in\n> +\tlinkgit:git-log[1]. Any aliases defined here can be used just\n> +\tas the built-in pretty formats could. For example, defining\n> +\t\"format.pretty.hash = format:%H\" would cause the invocation\n> +\t\"git log --pretty=hash\" to be equivalent to running\n> +\t\"git log --pretty=format:%H\". Note that an alias with the same\n> +\tname as a built-in format will be silently ignored.\n\nThe descriptive text mentions the old \"format.pretty.hash\".\n\n-Peff\n"},{"id":"140731","messageId":"7v39yazx4i.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"20100502044506.GA14776@coredump.intra.peff.net","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T05:33:01Z","receivedAt":"2010-05-02T05:33:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Sat, May 01, 2010 at 08:13:00PM -0700, Junio C Hamano wrote:\n>\n>> Will Palmer <wmpalmer@gmail.com> writes:\n>> ... \n>> > Here we make \"git log --pretty=%H --abbrev-commit\" synonymous with\n>> > \"git log --pretty=%h\", and make %h/abbreviated-%H respect the length\n>> > specified for --abbrev.\n>> \n>> I think it is a good change to make %h follow --abbrev, but %H should stay\n>> the full length no matter what (otherwise why would anybody use %H not %h?).\n>\n> But I thought the point of %h was to be abbreviated? If it follows\n> --abbrev, then \"git log --format=%h\" would show the full sha1, no?\n\nSorry, but I meant that the point of %h was to be abbreviated and the\npoint of %H was not to be abbreviated.  So no matter whaqt --abbrev-commit\nsays on the command line, --format=%H should show the full commit object\nname.\n\nBy the way, we should update Documentation/pretty-format.txt to use the\nproper terminology.  Colloquial use \"commit hash\", \"tree hash\", etc. are\nOk but in a formal documentation we should consistently say \"object name\".\n"},{"id":"140732","messageId":"20100502054004.GA19267@coredump.intra.peff.net","threadId":"23641","inReplyTo":"7v39yazx4i.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-05-02T05:40:04Z","receivedAt":"2010-05-02T05:40:04Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, May 01, 2010 at 10:33:01PM -0700, Junio C Hamano wrote:\n\n> >> > Here we make \"git log --pretty=%H --abbrev-commit\" synonymous with\n> >> > \"git log --pretty=%h\", and make %h/abbreviated-%H respect the length\n> >> > specified for --abbrev.\n> >> \n> >> I think it is a good change to make %h follow --abbrev, but %H should stay\n> >> the full length no matter what (otherwise why would anybody use %H not %h?).\n> >\n> > But I thought the point of %h was to be abbreviated? If it follows\n> > --abbrev, then \"git log --format=%h\" would show the full sha1, no?\n> \n> Sorry, but I meant that the point of %h was to be abbreviated and the\n> point of %H was not to be abbreviated.  So no matter whaqt --abbrev-commit\n> says on the command line, --format=%H should show the full commit object\n> name.\n\nAh, I see. So the change you called \"good\" above was that %h should\nrespect --abbrev=10, but keep the same default?\n\nI do think that's an improvement, but it discards what Will was trying\nto accomplish (a placeholder that behaves different depending on whether\nabbreviation has been requested). I guess we would need a new syntax for\nthat.\n\n-Peff\n"},{"id":"140734","messageId":"1272786771.4194.13.camel@walleee","threadId":"23641","inReplyTo":"7v39yazx4i.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-05-02T07:52:51Z","receivedAt":"2010-05-02T07:52:51Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"On Sat, 2010-05-01 at 22:33 -0700, Junio C Hamano wrote:\n> Jeff King <peff@peff.net> writes:\n> \n> > On Sat, May 01, 2010 at 08:13:00PM -0700, Junio C Hamano wrote:\n> >\n\nSounds like this one remains controversial. I'll pull the format changes\nout of the next pretty-alias series, and submit them as separate patches\nlater on. I still think the documentation implies that %H should be\nabbreviated when --abbrev-commit is passed, but for now I'm going to\nfocus on cleaning up the pretty.alias code.\nThe eventual solution, I suspect, will involve a more-generic syntax as\nwas brought up in the previous discussion. Something like\n%(abbrev-commit?%H), which would also be able to play with something\nlike [but, for obvious reasons, not exactly] %(is-merge?Merge: %p %p)\n\nThe %?C syntax seems to be generating less comment this time, and is the\none that I would find the most important to extending the usefulness of\nformat-aliases (ie: so that I can view a custom log with color in a\nterminal, then output it to a text file and have it \"do the right\nthing\"). Still, it would be lonely without %H/%h, so I'll stick it in\nits own patch as well (once I fix it up a bit more, as mentioned in the\nother thread).\n\n-- \n-- Will\n"},{"id":"140738","messageId":"1272790255.4258.11.camel@walleee","threadId":"23641","inReplyTo":"7vocgzyp1f.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-05-02T08:50:55Z","receivedAt":"2010-05-02T08:50:55Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"On Sat, 2010-05-01 at 20:13 -0700, Junio C Hamano wrote:\n> I think it is a good change to make %h follow --abbrev, but %H should stay\n> the full length no matter what (otherwise why would anybody use %H not %h?).\n\nI could just as easily say \"why would anyone pass --abbrev-commit unless\nthey actually wanted an abbreviated commit?\". Synonyms are confusing,\nbut ignored parameters sound more confusing to me.\n\nWhile I disagree that --abbrev-commit should have no effect whatsoever\nwhen %H is involved, I agree that the link between %h and --abbrev is\nmore solid, so I will split %h respecting --abbrev into a separate\npatch.\n\nIf the current behaviour is actually intentional, we should at least\nupdate the documentation to say that %H is the \"full commit hash\",\nrather than just the \"commit hash\".\n\n-- \n-- Will\n"},{"id":"140742","messageId":"1272790910.4258.16.camel@walleee","threadId":"23641","inReplyTo":"7vhbmryp10.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 4/5] pretty: add infrastructure to allow format aliases","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-05-02T09:01:50Z","receivedAt":"2010-05-02T09:01:50Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"On Sat, 2010-05-01 at 20:13 -0700, Junio C Hamano wrote:\n> I however wonder if we would want to be more helpful to the users to\n> diagnose this error by saying something here with error(), instead of just\n> letting the caller say \"invalid --pretty format: %s\".\n\nI suppose there's not really any sane reason why we wouldn't be able to\ndie then and there. If we pass the original name into the recursive\nfunction, then the message could be:\n\n\"invalid --pretty format: %s references an alias which points to itself\"\n\nsound like okay wording?\n\n-- \n-- Will\n"},{"id":"140743","messageId":"7vaasiwtvt.fsf@alter.siamese.dyndns.org","threadId":"23641","inReplyTo":"1272790255.4258.11.camel@walleee","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-05-02T09:11:18Z","receivedAt":"2010-05-02T09:11:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Will Palmer <wmpalmer@gmail.com> writes:\n\n> If the current behaviour is actually intentional, we should at least\n> update the documentation to say that %H is the \"full commit hash\",\n> rather than just the \"commit hash\".\n\nI think it was obvious from the context that lists %H and %h next to each\nother, with description without \"abbreviated\" and with \"abbreviated\" to\nthem.  The description for %H should be rewritten as \"commit object name\"\nand %h \"abbreviated commit object name\".\n"},{"id":"140746","messageId":"20100502091720.GB1854@progeny.tock","threadId":"23641","inReplyTo":"7vaasiwtvt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 2/5] pretty: make %H/%h/etc respect --abbrev[-commit]","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-05-02T09:17:20Z","receivedAt":"2010-05-02T09:17:20Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n> Will Palmer <wmpalmer@gmail.com> writes:\n\n>> If the current behaviour is actually intentional, we should at least\n>> update the documentation to say that %H is the \"full commit hash\",\n>> rather than just the \"commit hash\".\n>\n> I think it was obvious from the context that lists %H and %h next to each\n> other, with description without \"abbreviated\" and with \"abbreviated\" to\n> them.  The description for %H should be rewritten as \"commit object name\"\n> and %h \"abbreviated commit object name\".\n\nFWIW, this is why I suggested updating the documentation.  I think the\n“%H becomes %h in the presence of --abbrev-commit” behavior would be\nmore useful in practice.\n\nBut I am not fanatical about it.  Maybe this functionality should get\nsome other letter and I would just not use %H.\n\nJonathan\n"},{"id":"140748","messageId":"1272792712.4258.20.camel@walleee","threadId":"23641","inReplyTo":"7vvdb7yp1u.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 1/5] pretty: add conditional %C?colorname placeholders","fromName":"Will Palmer","fromEmail":"wmpalmer@gmail.com","sentAt":"2010-05-02T09:31:52Z","receivedAt":"2010-05-02T09:31:52Z","isPatch":true,"sender":{"key":"wmpalmer@gmail.com","avatar":"https://avatars.githubusercontent.com/u/357044?v=4"},"body":"On Sat, 2010-05-01 at 20:12 -0700, Junio C Hamano wrote:\n> Will Palmer <wmpalmer@gmail.com> writes:\n> > +# Released into Public Domain by Will Palmer 2010\n> > +#\n> \n> Hmm...\n\nI saw the note that a copyright notice should be included at the top of\neach test. Personally, while I like the GPL for code for example,\nclaiming copyright protection on a test script seems counter-productive.\nIf it could cause problems / make it harder to accept other\ncontributions, though, I'll change it to the standard boilerplate.\n\n-- \n-- Will\n"}]}