{"thread":{"id":"50322","subject":"Add author and committer configuration settings","startedAt":"2019-01-25T22:00:47Z","lastAt":"2019-01-29T22:42:15Z","messageCount":15,"participants":["William Hubbs","Ævar Arnfjörð Bjarmason","Eric Sunshine","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"367686","messageId":"20190125215955.30032-1-williamh@gentoo.org","threadId":"50322","inReplyTo":null,"subject":"Add author and committer configuration settings","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-25T21:59:53Z","receivedAt":"2019-01-25T22:00:47Z","isPatch":false,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"All,\n\nthis is a re-roll of my previous patch to add separate author and\ncommitter settings.:s/committer/committer configuration/\nA\n\nI attempted to encorporate everything from the last iteration, and all\ntests still pass.\n\nThis applies to master. Please review.\n\n[PATCH v2 1/2] config: allow giving separate author and committer\n[PATCH v2 2/2] tests: add test for separate author and committer\n\nThanks,\n\nWilliam\n\n\n"},{"id":"367687","messageId":"20190125215955.30032-2-williamh@gentoo.org","threadId":"50322","inReplyTo":"20190125215955.30032-1-williamh@gentoo.org","subject":"[PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-25T21:59:54Z","receivedAt":"2019-01-25T22:01:00Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"The author.email, author.name, committer.email and committer.name\nsettings are analogous to the GIT_AUTHOR_* and GIT_COMMITTER_*\nenvironment variables, but for the git config system. This allows them\nto be set separately for each repository.\n\nGit supports setting different authorship and committer\ninformation with environment variables. However, environment variables\nare set in the shell, so if different authorship and committer\ninformation is needed for different repositories an external tool is\nrequired.\n\nThis adds support to git config for author.email, author.name,\ncommitter.email and committer.name  settings so this information\ncan be set per repository.\n\nAlso, it generalizes the fmt_ident function so it can handle author vs\ncommitter identification.\n\nSigned-off-by: William Hubbs <williamh@gentoo.org>\n---\n Documentation/config/user.txt | 31 +++++++++++++-\n blame.c                       |  3 +-\n builtin/am.c                  |  2 +-\n builtin/commit.c              |  3 +-\n cache.h                       | 13 +++++-\n config.c                      |  6 +++\n ident.c                       | 81 +++++++++++++++++++++++++++++++++--\n log-tree.c                    |  3 +-\n sequencer.c                   |  5 +--\n 9 files changed, 132 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\nindex b5b2ba1199..18e1ec3c1b 100644\n--- a/Documentation/config/user.txt\n+++ b/Documentation/config/user.txt\n@@ -1,12 +1,39 @@\n+author.email::\n+\tThe email address used for the author of newly\n+\tcreated commits.  Defaults to the value of the\n+\t`GIT_AUTHOR_EMAIL` environment variable, or if\n+\tthe environment variable is not set, the `user.email`\n+\tconfiguration variable.\n+\n+author.name::\n+\tThe full name used for the author of newly created commits.\n+\tDefaults to the value of the `GIT_AUTHOR_NAME` environment variable, or\n+\tif the environment variable is not set,\n+\tthe `user.email` configuration variable.\n+\n+committer.email::\n+\tThe email address used for the committer of newly created commits.\n+\tDefaults to the value of the `GIT_COMMITTER_EMAIL` environment\n+\tvariable, or if the environment variable is not set, the `user.email`\n+\tconfiguration variable.\n+\n+committer.name::\n+\tThe full name used for the committer of newly created commits.\n+\tDefaults to the value of the `GIT_COMMITTER_NAME` environment\n+\tvariable, or if the environment variable is not set, the `user.name`\n+\tconfiguration variable.\n+\n user.email::\n \tYour email address to be recorded in any newly created commits.\n \tCan be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and\n-\t`EMAIL` environment variables.  See linkgit:git-commit-tree[1].\n+\t`EMAIL` environment variables or the `author.email` or\n+\t`committer.email` settings discussed above. See linkgit:git-commit-tree[1].\n \n user.name::\n \tYour full name to be recorded in any newly created commits.\n \tCan be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`\n-\tenvironment variables.  See linkgit:git-commit-tree[1].\n+\tenvironment variables or the `author.name` or `committer.name`\n+\tsettings discussed above. See linkgit:git-commit-tree[1].\n \n user.useConfigOnly::\n \tInstruct Git to avoid trying to guess defaults for `user.email`\ndiff --git a/blame.c b/blame.c\nindex 43861437f7..c9c351eb36 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -204,7 +204,8 @@ static struct commit *fake_working_tree_commit(struct repository *r,\n \n \torigin = make_origin(commit, path);\n \n-\tident = fmt_ident(\"Not Committed Yet\", \"not.committed.yet\", NULL, 0);\n+\tident = fmt_ident(\"Not Committed Yet\", \"not.committed.yet\",\n+\t\t\tWANT_BLANK_IDENT, NULL, 0);\n \tstrbuf_addstr(&msg, \"tree 0000000000000000000000000000000000000000\\n\");\n \tfor (parent = commit->parents; parent; parent = parent->next)\n \t\tstrbuf_addf(&msg, \"parent %s\\n\",\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 95370313b6..53fdd22c45 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1594,7 +1594,7 @@ static void do_commit(const struct am_state *state)\n \t}\n \n \tauthor = fmt_ident(state->author_name, state->author_email,\n-\t\t\tstate->ignore_date ? NULL : state->author_date,\n+\t\t\tWANT_AUTHOR_IDENT, state->ignore_date ? NULL : state->author_date,\n \t\t\tIDENT_STRICT);\n \n \tif (state->committer_date_is_author_date)\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 004b816635..f96b90daeb 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -607,7 +607,8 @@ static void determine_author_info(struct strbuf *author_ident)\n \t\tset_ident_var(&date, strbuf_detach(&date_buf, NULL));\n \t}\n \n-\tstrbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));\n+\tstrbuf_addstr(author_ident, fmt_ident(name, email, WANT_AUTHOR_IDENT, date,\n+\t\t\t\tIDENT_STRICT));\n \tassert_split_ident(&author, author_ident);\n \texport_one(\"GIT_AUTHOR_NAME\", author.name_begin, author.name_end, 0);\n \texport_one(\"GIT_AUTHOR_EMAIL\", author.mail_begin, author.mail_end, 0);\ndiff --git a/cache.h b/cache.h\nindex 49713cc5a5..f13c6e244f 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1479,10 +1479,19 @@ int date_overflows(timestamp_t date);\n #define IDENT_STRICT\t       1\n #define IDENT_NO_DATE\t       2\n #define IDENT_NO_NAME\t       4\n+\n+enum want_ident {\n+\tWANT_BLANK_IDENT,\n+\tWANT_AUTHOR_IDENT,\n+\tWANT_COMMITTER_IDENT,\n+};\n+\n extern const char *git_author_info(int);\n extern const char *git_committer_info(int);\n-extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);\n-extern const char *fmt_name(const char *name, const char *email);\n+extern const char *fmt_ident(const char *name, const char *email,\n+\t\tenum want_ident whose_ident,\n+\t\tconst char *date_str, int);\n+extern const char *fmt_name(enum want_ident);\n extern const char *ident_default_name(void);\n extern const char *ident_default_email(void);\n extern const char *git_editor(void);\ndiff --git a/config.c b/config.c\nindex ff521eb27a..4bd5920dea 100644\n--- a/config.c\n+++ b/config.c\n@@ -1484,6 +1484,12 @@ int git_default_config(const char *var, const char *value, void *cb)\n \t\treturn 0;\n \t}\n \n+\tif (starts_with(var, \"author.\"))\n+\t\treturn git_ident_config(var, value, cb);\n+\n+\tif (starts_with(var, \"committer.\"))\n+\t\treturn git_ident_config(var, value, cb);\n+\n \t/* Add other config variables here and to Documentation/config.txt. */\n \treturn 0;\n }\ndiff --git a/ident.c b/ident.c\nindex 33bcf40644..a1e774c3e5 100644\n--- a/ident.c\n+++ b/ident.c\n@@ -11,6 +11,10 @@\n static struct strbuf git_default_name = STRBUF_INIT;\n static struct strbuf git_default_email = STRBUF_INIT;\n static struct strbuf git_default_date = STRBUF_INIT;\n+static struct strbuf git_author_name = STRBUF_INIT;\n+static struct strbuf git_author_email = STRBUF_INIT;\n+static struct strbuf git_committer_name = STRBUF_INIT;\n+static struct strbuf git_committer_email = STRBUF_INIT;\n static int default_email_is_bogus;\n static int default_name_is_bogus;\n \n@@ -355,13 +359,19 @@ N_(\"\\n\"\n    \"\\n\");\n \n const char *fmt_ident(const char *name, const char *email,\n-\t\t      const char *date_str, int flag)\n+\t\t      enum want_ident whose_ident, const char *date_str, int flag)\n {\n \tstatic struct strbuf ident = STRBUF_INIT;\n \tint strict = (flag & IDENT_STRICT);\n \tint want_date = !(flag & IDENT_NO_DATE);\n \tint want_name = !(flag & IDENT_NO_NAME);\n \n+\tif (!email) {\n+\t\tif (whose_ident == WANT_AUTHOR_IDENT && git_author_email.len)\n+\t\t\temail = git_author_email.buf;\n+\t\telse if (whose_ident == WANT_COMMITTER_IDENT && git_committer_email.len)\n+\t\t\temail = git_committer_email.buf;\n+\t}\n \tif (!email) {\n \t\tif (strict && ident_use_config_only\n \t\t    && !(ident_config_given & IDENT_MAIL_GIVEN)) {\n@@ -377,6 +387,13 @@ const char *fmt_ident(const char *name, const char *email,\n \n \tif (want_name) {\n \t\tint using_default = 0;\n+\t\tif (!name) {\n+\t\t\tif (whose_ident == WANT_AUTHOR_IDENT && git_author_name.len)\n+\t\t\t\tname = git_author_name.buf;\n+\t\t\telse if (whose_ident == WANT_COMMITTER_IDENT &&\n+\t\t\t\t\tgit_committer_name.len)\n+\t\t\t\tname = git_committer_name.buf;\n+\t\t}\n \t\tif (!name) {\n \t\t\tif (strict && ident_use_config_only\n \t\t\t    && !(ident_config_given & IDENT_NAME_GIVEN)) {\n@@ -425,9 +442,25 @@ const char *fmt_ident(const char *name, const char *email,\n \treturn ident.buf;\n }\n \n-const char *fmt_name(const char *name, const char *email)\n+const char *fmt_name(enum want_ident whose_ident)\n {\n-\treturn fmt_ident(name, email, NULL, IDENT_STRICT | IDENT_NO_DATE);\n+\tchar *name = NULL;\n+\tchar *email = NULL;\n+\n+\tswitch (whose_ident) {\n+\tcase WANT_BLANK_IDENT:\n+\t\tbreak;\n+\tcase WANT_AUTHOR_IDENT:\n+\t\tname = getenv(\"GIT_AUTHOR_NAME\");\n+\t\temail = getenv(\"GIT_AUTHOR_EMAIL\");\n+\t\tbreak;\n+\tcase WANT_COMMITTER_IDENT:\n+\t\tname = getenv(\"GIT_COMMITTER_NAME\");\n+\t\temail = getenv(\"GIT_COMMITTER_EMAIL\");\n+\t\tbreak;\n+\t}\n+\treturn fmt_ident(name, email, whose_ident, NULL,\n+\t\t\tIDENT_STRICT | IDENT_NO_DATE);\n }\n \n const char *git_author_info(int flag)\n@@ -438,6 +471,7 @@ const char *git_author_info(int flag)\n \t\tauthor_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n \treturn fmt_ident(getenv(\"GIT_AUTHOR_NAME\"),\n \t\t\t getenv(\"GIT_AUTHOR_EMAIL\"),\n+\t\t\t WANT_AUTHOR_IDENT,\n \t\t\t getenv(\"GIT_AUTHOR_DATE\"),\n \t\t\t flag);\n }\n@@ -450,6 +484,7 @@ const char *git_committer_info(int flag)\n \t\tcommitter_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n \treturn fmt_ident(getenv(\"GIT_COMMITTER_NAME\"),\n \t\t\t getenv(\"GIT_COMMITTER_EMAIL\"),\n+\t\t\t WANT_COMMITTER_IDENT,\n \t\t\t getenv(\"GIT_COMMITTER_DATE\"),\n \t\t\t flag);\n }\n@@ -480,6 +515,46 @@ int git_ident_config(const char *var, const char *value, void *data)\n \t\treturn 0;\n \t}\n \n+\tif (!strcmp(var, \"author.name\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tstrbuf_reset(&git_author_name);\n+\t\tstrbuf_addstr(&git_author_name, value);\n+\t\tauthor_ident_explicitly_given |= IDENT_NAME_GIVEN;\n+\t\tident_config_given |= IDENT_NAME_GIVEN;\n+\t\treturn 0;\n+\t}\n+\n+\tif (!strcmp(var, \"author.email\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tstrbuf_reset(&git_author_email);\n+\t\tstrbuf_addstr(&git_author_email, value);\n+\t\tauthor_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n+\t\tident_config_given |= IDENT_MAIL_GIVEN;\n+\t\treturn 0;\n+\t}\n+\n+\tif (!strcmp(var, \"committer.name\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tstrbuf_reset(&git_committer_name);\n+\t\tstrbuf_addstr(&git_committer_name, value);\n+\t\tcommitter_ident_explicitly_given |= IDENT_NAME_GIVEN;\n+\t\tident_config_given |= IDENT_NAME_GIVEN;\n+\t\treturn 0;\n+\t}\n+\n+\tif (!strcmp(var, \"committer.email\")) {\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tstrbuf_reset(&git_committer_email);\n+\t\tstrbuf_addstr(&git_committer_email, value);\n+\t\tcommitter_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n+\t\tident_config_given |= IDENT_MAIL_GIVEN;\n+\t\treturn 0;\n+\t}\n+\n \tif (!strcmp(var, \"user.name\")) {\n \t\tif (!value)\n \t\t\treturn config_error_nonbool(var);\ndiff --git a/log-tree.c b/log-tree.c\nindex 10680c139e..43ef4f4300 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -687,8 +687,7 @@ void show_log(struct rev_info *opt)\n \t */\n \tif (ctx.need_8bit_cte >= 0 && opt->add_signoff)\n \t\tctx.need_8bit_cte =\n-\t\t\thas_non_ascii(fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n-\t\t\t\t\t       getenv(\"GIT_COMMITTER_EMAIL\")));\n+\t\t\thas_non_ascii(fmt_name(WANT_COMMITTER_IDENT));\n \tctx.date_mode = opt->date_mode;\n \tctx.date_mode_explicit = opt->date_mode_explicit;\n \tctx.abbrev = opt->diffopt.abbrev;\ndiff --git a/sequencer.c b/sequencer.c\nindex f5370f4965..3505d52bb9 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -836,7 +836,7 @@ static const char *read_author_ident(struct strbuf *buf)\n \t}\n \n \tstrbuf_reset(&out);\n-\tstrbuf_addstr(&out, fmt_ident(name, email, date, 0));\n+\tstrbuf_addstr(&out, fmt_ident(name, email, WANT_AUTHOR_IDENT, date, 0));\n \tstrbuf_swap(buf, &out);\n \tstrbuf_release(&out);\n \tfree(name);\n@@ -4087,8 +4087,7 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag)\n \tint has_footer;\n \n \tstrbuf_addstr(&sob, sign_off_header);\n-\tstrbuf_addstr(&sob, fmt_name(getenv(\"GIT_COMMITTER_NAME\"),\n-\t\t\t\tgetenv(\"GIT_COMMITTER_EMAIL\")));\n+\tstrbuf_addstr(&sob, fmt_name(WANT_COMMITTER_IDENT));\n \tstrbuf_addch(&sob, '\\n');\n \n \tif (!ignore_footer)\n-- \n2.19.2\n\n"},{"id":"367688","messageId":"20190125215955.30032-3-williamh@gentoo.org","threadId":"50322","inReplyTo":"20190125215955.30032-1-williamh@gentoo.org","subject":"[PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-25T21:59:55Z","receivedAt":"2019-01-25T22:01:05Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"Signed-off-by: William Hubbs <williamh@gentoo.org>\n---\n t/t7517-per-repo-email.sh | 17 +++++++++++++++++\n 1 file changed, 17 insertions(+)\n\ndiff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\nindex 231b8cc19d..06c7c0fb78 100755\n--- a/t/t7517-per-repo-email.sh\n+++ b/t/t7517-per-repo-email.sh\n@@ -85,4 +85,21 @@ test_expect_success REBASE_P \\\n \ttest_must_fail git rebase -p master\n '\n \n+test_expect_success \\\n+\t'author and committer config settings override user config settings' '\n+\tsane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n+\tsane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n+\tgit config user.name user &&\n+\tgit config user.email user@example.com &&\n+\tgit config author.name author &&\n+\tgit config author.email author@example.com &&\n+\tgit config committer.name committer &&\n+\tgit config committer.email committer@example.com &&\n+\ttest_commit config-names &&\n+\t[ \"$(git log --format=%an -1)\" = \"author\" ] &&\n+\t[ \"$(git log --format=%ae -1)\" = \"author@example.com\" ] &&\n+\t[ \"$(git log --format=%cn -1)\" = \"committer\" ] &&\n+\t[ \"$(git log --format=%ce -1)\" = \"committer@example.com\" ]\n+'\n+\n test_done\n-- \n2.19.2\n\n"},{"id":"367693","messageId":"877ees4a65.fsf@evledraar.gmail.com","threadId":"50322","inReplyTo":"20190125215955.30032-2-williamh@gentoo.org","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-01-25T22:58:10Z","receivedAt":"2019-01-25T22:58:17Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Jan 25 2019, William Hubbs wrote:\n\n> The author.email, author.name, committer.email and committer.name\n> settings are analogous to the GIT_AUTHOR_* and GIT_COMMITTER_*\n> environment variables, but for the git config system. This allows them\n> to be set separately for each repository.\n>\n> Git supports setting different authorship and committer\n> information with environment variables. However, environment variables\n> are set in the shell, so if different authorship and committer\n> information is needed for different repositories an external tool is\n> required.\n>\n> This adds support to git config for author.email, author.name,\n> committer.email and committer.name  settings so this information\n> can be set per repository.\n>\n> Also, it generalizes the fmt_ident function so it can handle author vs\n> committer identification.\n\nI have not tested this in any detail...\n\n> diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\n> index b5b2ba1199..18e1ec3c1b 100644\n> --- a/Documentation/config/user.txt\n> +++ b/Documentation/config/user.txt\n> @@ -1,12 +1,39 @@\n> +author.email::\n> +\tThe email address used for the author of newly\n> +\tcreated commits.  Defaults to the value of the\n> +\t`GIT_AUTHOR_EMAIL` environment variable, or if\n> +\tthe environment variable is not set, the `user.email`\n> +\tconfiguration variable.\n> +\n> +author.name::\n> +\tThe full name used for the author of newly created commits.\n> +\tDefaults to the value of the `GIT_AUTHOR_NAME` environment variable, or\n> +\tif the environment variable is not set,\n> +\tthe `user.email` configuration variable.\n> +\n> +committer.email::\n> +\tThe email address used for the committer of newly created commits.\n> +\tDefaults to the value of the `GIT_COMMITTER_EMAIL` environment\n> +\tvariable, or if the environment variable is not set, the `user.email`\n> +\tconfiguration variable.\n> +\n> +committer.name::\n> +\tThe full name used for the committer of newly created commits.\n> +\tDefaults to the value of the `GIT_COMMITTER_NAME` environment\n> +\tvariable, or if the environment variable is not set, the `user.name`\n> +\tconfiguration variable.\n> +\n>  user.email::\n>  \tYour email address to be recorded in any newly created commits.\n>  \tCan be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and\n> -\t`EMAIL` environment variables.  See linkgit:git-commit-tree[1].\n> +\t`EMAIL` environment variables or the `author.email` or\n> +\t`committer.email` settings discussed above. See linkgit:git-commit-tree[1].\n>\n>  user.name::\n>  \tYour full name to be recorded in any newly created commits.\n>  \tCan be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`\n> -\tenvironment variables.  See linkgit:git-commit-tree[1].\n> +\tenvironment variables or the `author.name` or `committer.name`\n> +\tsettings discussed above. See linkgit:git-commit-tree[1].\n\nLooks correct, although I wonder if we're at the point where it would be\nbetter to present this info as a table.\n\n> diff --git a/builtin/am.c b/builtin/am.c\n> index 95370313b6..53fdd22c45 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1594,7 +1594,7 @@ static void do_commit(const struct am_state *state)\n>  \t}\n>\n>  \tauthor = fmt_ident(state->author_name, state->author_email,\n> -\t\t\tstate->ignore_date ? NULL : state->author_date,\n> +\t\t\tWANT_AUTHOR_IDENT, state->ignore_date ? NULL : state->author_date,\n\nThis & a few other things in this series take the code beyond 79\ncharacters.\n\n>  \t\t\tIDENT_STRICT);\n>\n>  \tif (state->committer_date_is_author_date)\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 004b816635..f96b90daeb 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -607,7 +607,8 @@ static void determine_author_info(struct strbuf *author_ident)\n>  \t\tset_ident_var(&date, strbuf_detach(&date_buf, NULL));\n>  \t}\n>\n> -\tstrbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));\n> +\tstrbuf_addstr(author_ident, fmt_ident(name, email, WANT_AUTHOR_IDENT, date,\n> +\t\t\t\tIDENT_STRICT));\n>  \tassert_split_ident(&author, author_ident);\n>  \texport_one(\"GIT_AUTHOR_NAME\", author.name_begin, author.name_end, 0);\n>  \texport_one(\"GIT_AUTHOR_EMAIL\", author.mail_begin, author.mail_end, 0);\n> diff --git a/cache.h b/cache.h\n> index 49713cc5a5..f13c6e244f 100644\n> --- a/cache.h\n> +++ b/cache.h\n> @@ -1479,10 +1479,19 @@ int date_overflows(timestamp_t date);\n>  #define IDENT_STRICT\t       1\n>  #define IDENT_NO_DATE\t       2\n>  #define IDENT_NO_NAME\t       4\n> +\n> +enum want_ident {\n> +\tWANT_BLANK_IDENT,\n> +\tWANT_AUTHOR_IDENT,\n> +\tWANT_COMMITTER_IDENT,\n> +};\n> +\n>  extern const char *git_author_info(int);\n>  extern const char *git_committer_info(int);\n> -extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);\n> -extern const char *fmt_name(const char *name, const char *email);\n> +extern const char *fmt_ident(const char *name, const char *email,\n> +\t\tenum want_ident whose_ident,\n> +\t\tconst char *date_str, int);\n> +extern const char *fmt_name(enum want_ident);\n>  extern const char *ident_default_name(void);\n>  extern const char *ident_default_email(void);\n>  extern const char *git_editor(void);\n> diff --git a/config.c b/config.c\n> index ff521eb27a..4bd5920dea 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -1484,6 +1484,12 @@ int git_default_config(const char *var, const char *value, void *cb)\n>  \t\treturn 0;\n>  \t}\n>\n> +\tif (starts_with(var, \"author.\"))\n> +\t\treturn git_ident_config(var, value, cb);\n> +\n> +\tif (starts_with(var, \"committer.\"))\n> +\t\treturn git_ident_config(var, value, cb);\n> +\n>  \t/* Add other config variables here and to Documentation/config.txt. */\n>  \treturn 0;\n>  }\n> diff --git a/ident.c b/ident.c\n> index 33bcf40644..a1e774c3e5 100644\n> --- a/ident.c\n> +++ b/ident.c\n> @@ -11,6 +11,10 @@\n>  static struct strbuf git_default_name = STRBUF_INIT;\n>  static struct strbuf git_default_email = STRBUF_INIT;\n>  static struct strbuf git_default_date = STRBUF_INIT;\n> +static struct strbuf git_author_name = STRBUF_INIT;\n> +static struct strbuf git_author_email = STRBUF_INIT;\n> +static struct strbuf git_committer_name = STRBUF_INIT;\n> +static struct strbuf git_committer_email = STRBUF_INIT;\n>  static int default_email_is_bogus;\n>  static int default_name_is_bogus;\n>\n> @@ -355,13 +359,19 @@ N_(\"\\n\"\n>     \"\\n\");\n>\n>  const char *fmt_ident(const char *name, const char *email,\n> -\t\t      const char *date_str, int flag)\n> +\t\t      enum want_ident whose_ident, const char *date_str, int flag)\n>  {\n>  \tstatic struct strbuf ident = STRBUF_INIT;\n>  \tint strict = (flag & IDENT_STRICT);\n>  \tint want_date = !(flag & IDENT_NO_DATE);\n>  \tint want_name = !(flag & IDENT_NO_NAME);\n>\n> +\tif (!email) {\n> +\t\tif (whose_ident == WANT_AUTHOR_IDENT && git_author_email.len)\n> +\t\t\temail = git_author_email.buf;\n> +\t\telse if (whose_ident == WANT_COMMITTER_IDENT && git_committer_email.len)\n> +\t\t\temail = git_committer_email.buf;\n> +\t}\n>  \tif (!email) {\n>  \t\tif (strict && ident_use_config_only\n>  \t\t    && !(ident_config_given & IDENT_MAIL_GIVEN)) {\n> @@ -377,6 +387,13 @@ const char *fmt_ident(const char *name, const char *email,\n>\n>  \tif (want_name) {\n>  \t\tint using_default = 0;\n> +\t\tif (!name) {\n> +\t\t\tif (whose_ident == WANT_AUTHOR_IDENT && git_author_name.len)\n> +\t\t\t\tname = git_author_name.buf;\n> +\t\t\telse if (whose_ident == WANT_COMMITTER_IDENT &&\n> +\t\t\t\t\tgit_committer_name.len)\n> +\t\t\t\tname = git_committer_name.buf;\n> +\t\t}\n>  \t\tif (!name) {\n>  \t\t\tif (strict && ident_use_config_only\n>  \t\t\t    && !(ident_config_given & IDENT_NAME_GIVEN)) {\n> @@ -425,9 +442,25 @@ const char *fmt_ident(const char *name, const char *email,\n>  \treturn ident.buf;\n>  }\n>\n> -const char *fmt_name(const char *name, const char *email)\n> +const char *fmt_name(enum want_ident whose_ident)\n>  {\n> -\treturn fmt_ident(name, email, NULL, IDENT_STRICT | IDENT_NO_DATE);\n> +\tchar *name = NULL;\n> +\tchar *email = NULL;\n> +\n> +\tswitch (whose_ident) {\n> +\tcase WANT_BLANK_IDENT:\n> +\t\tbreak;\n> +\tcase WANT_AUTHOR_IDENT:\n> +\t\tname = getenv(\"GIT_AUTHOR_NAME\");\n> +\t\temail = getenv(\"GIT_AUTHOR_EMAIL\");\n> +\t\tbreak;\n> +\tcase WANT_COMMITTER_IDENT:\n> +\t\tname = getenv(\"GIT_COMMITTER_NAME\");\n> +\t\temail = getenv(\"GIT_COMMITTER_EMAIL\");\n> +\t\tbreak;\n> +\t}\n> +\treturn fmt_ident(name, email, whose_ident, NULL,\n> +\t\t\tIDENT_STRICT | IDENT_NO_DATE);\n>  }\n>\n>  const char *git_author_info(int flag)\n> @@ -438,6 +471,7 @@ const char *git_author_info(int flag)\n>  \t\tauthor_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n>  \treturn fmt_ident(getenv(\"GIT_AUTHOR_NAME\"),\n>  \t\t\t getenv(\"GIT_AUTHOR_EMAIL\"),\n> +\t\t\t WANT_AUTHOR_IDENT,\n>  \t\t\t getenv(\"GIT_AUTHOR_DATE\"),\n>  \t\t\t flag);\n>  }\n> @@ -450,6 +484,7 @@ const char *git_committer_info(int flag)\n>  \t\tcommitter_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n>  \treturn fmt_ident(getenv(\"GIT_COMMITTER_NAME\"),\n>  \t\t\t getenv(\"GIT_COMMITTER_EMAIL\"),\n> +\t\t\t WANT_COMMITTER_IDENT,\n>  \t\t\t getenv(\"GIT_COMMITTER_DATE\"),\n>  \t\t\t flag);\n>  }\n> @@ -480,6 +515,46 @@ int git_ident_config(const char *var, const char *value, void *data)\n>  \t\treturn 0;\n>  \t}\n>\n> +\tif (!strcmp(var, \"author.name\")) {\n> +\t\tif (!value)\n> +\t\t\treturn config_error_nonbool(var);\n> +\t\tstrbuf_reset(&git_author_name);\n> +\t\tstrbuf_addstr(&git_author_name, value);\n> +\t\tauthor_ident_explicitly_given |= IDENT_NAME_GIVEN;\n> +\t\tident_config_given |= IDENT_NAME_GIVEN;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tif (!strcmp(var, \"author.email\")) {\n> +\t\tif (!value)\n> +\t\t\treturn config_error_nonbool(var);\n> +\t\tstrbuf_reset(&git_author_email);\n> +\t\tstrbuf_addstr(&git_author_email, value);\n> +\t\tauthor_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n> +\t\tident_config_given |= IDENT_MAIL_GIVEN;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tif (!strcmp(var, \"committer.name\")) {\n> +\t\tif (!value)\n> +\t\t\treturn config_error_nonbool(var);\n> +\t\tstrbuf_reset(&git_committer_name);\n> +\t\tstrbuf_addstr(&git_committer_name, value);\n> +\t\tcommitter_ident_explicitly_given |= IDENT_NAME_GIVEN;\n> +\t\tident_config_given |= IDENT_NAME_GIVEN;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tif (!strcmp(var, \"committer.email\")) {\n> +\t\tif (!value)\n> +\t\t\treturn config_error_nonbool(var);\n> +\t\tstrbuf_reset(&git_committer_email);\n> +\t\tstrbuf_addstr(&git_committer_email, value);\n> +\t\tcommitter_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n> +\t\tident_config_given |= IDENT_MAIL_GIVEN;\n> +\t\treturn 0;\n> +\t}\n> +\n\nThis whole thing should be split into a static function. It's the same\ncode copy/pasted 4x times just with a differnet value for \"var\", the\nstrbuf variable & IDENT_*_GIVEN.\n\n"},{"id":"367694","messageId":"875zuc49uj.fsf@evledraar.gmail.com","threadId":"50322","inReplyTo":"20190125215955.30032-3-williamh@gentoo.org","subject":"Re: [PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-01-25T23:05:08Z","receivedAt":"2019-01-25T23:05:13Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Jan 25 2019, William Hubbs wrote:\n\n> Signed-off-by: William Hubbs <williamh@gentoo.org>\n> ---\n>  t/t7517-per-repo-email.sh | 17 +++++++++++++++++\n>  1 file changed, 17 insertions(+)\n>\n> diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\n> index 231b8cc19d..06c7c0fb78 100755\n> --- a/t/t7517-per-repo-email.sh\n> +++ b/t/t7517-per-repo-email.sh\n> @@ -85,4 +85,21 @@ test_expect_success REBASE_P \\\n>  \ttest_must_fail git rebase -p master\n>  '\n\nLet's include this in the main patch. We don't split up tests into their\nown patches like this.\n\n> +test_expect_success \\\n> +\t'author and committer config settings override user config settings' '\n\nThis can just be on one line. We're not strict about 79 characters in\ntests.\n\n> +\tsane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n> +\tsane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n\nFine, but FYI sets these variables for the rest of the test.\n\nBut more importantly there should be a test for how the various override\ninteractions between the config & env variables work. I.e. whether\nGIT_COMMITTER_NAME set in the env will override \"user.email\" etc.\n\n> +\tgit config user.name user &&\n> +\tgit config user.email user@example.com &&\n> +\tgit config author.name author &&\n> +\tgit config author.email author@example.com &&\n> +\tgit config committer.name committer &&\n> +\tgit config committer.email committer@example.com &&\n\nThis should use \"test_config\" so it'll be unset after this test.\n\n> +\ttest_commit config-names &&\n> +\t[ \"$(git log --format=%an -1)\" = \"author\" ] &&\n> +\t[ \"$(git log --format=%ae -1)\" = \"author@example.com\" ] &&\n> +\t[ \"$(git log --format=%cn -1)\" = \"committer\" ] &&\n> +\t[ \"$(git log --format=%ce -1)\" = \"committer@example.com\" ]\n\nShould use something like test_cmp so that on failure we see what the\ndifference is. I'd just do:\n\n    cat >expected <<EOF... &&\n    git log --format=\"an:%an%nae:%ae[...]\" -1 >actual &&\n    test_cmp ...\n\n> +'\n> +\n>  test_done\n"},{"id":"367699","messageId":"20190126010632.GA4000@whubbs1.gaikai.biz","threadId":"50322","inReplyTo":"875zuc49uj.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-26T01:06:32Z","receivedAt":"2019-01-26T01:06:38Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"On Sat, Jan 26, 2019 at 12:05:08AM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Fri, Jan 25 2019, William Hubbs wrote:\n\n...\n\n> > +\tsane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n> > +\tsane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n> \n> Fine, but FYI sets these variables for the rest of the test.\n\nI'm not quite sure what you mean by this. I want the environment\nvariables to be *unset*. I don't want them to override anything in the\nconfig file for this test.\n\nAre you saying they will not be set for the test unless I set them,\nso I don't need the SANE_UNSET calls?\n\nThanks,\n\nWilliam\n"},{"id":"367701","messageId":"874l9v4x6p.fsf@evledraar.gmail.com","threadId":"50322","inReplyTo":"20190126010632.GA4000@whubbs1.gaikai.biz","subject":"Re: [PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-01-26T08:53:18Z","receivedAt":"2019-01-26T08:53:23Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Sat, Jan 26 2019, William Hubbs wrote:\n\n> On Sat, Jan 26, 2019 at 12:05:08AM +0100, Ævar Arnfjörð Bjarmason wrote:\n>>\n>> On Fri, Jan 25 2019, William Hubbs wrote:\n>\n> ...\n>\n>> > +\tsane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n>> > +\tsane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n>>\n>> Fine, but FYI sets these variables for the rest of the test.\n>\n> I'm not quite sure what you mean by this. I want the environment\n> variables to be *unset*. I don't want them to override anything in the\n> config file for this test.\n>\n> Are you saying they will not be set for the test unless I set them,\n> so I don't need the SANE_UNSET calls?\n\nSorry for not being clear. I just meant that unlike \"test_config\" the\n\"sane_unset\" function won't reset the state at the end of the\n\"test_expect_success\".\n\nRight now it doesn't matter in practice since this is the last test\nbefore \"test_done\", but as tests are added we tend to leak state between\nthem, which is why we use these \"unset at the end\" helper functions.\n\nBut unlike with config that doesn't matter in this case, since we want\nthese unset anyway.\n\nWhich, looking at this again, you'd only want if a previous test in the\nfile was leaking its state. That's not the case, so this isn't needed\nand you can just apply this on top:\n\n    diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh\n    index 06c7c0fb78..e5845b0b86 100755\n    --- a/t/t7517-per-repo-email.sh\n    +++ b/t/t7517-per-repo-email.sh\n    @@ -87,8 +87,6 @@ test_expect_success REBASE_P \\\n\n     test_expect_success \\\n            'author and committer config settings override user config settings' '\n    -       sane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n    -       sane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n            git config user.name user &&\n            git config user.email user@example.com &&\n            git config author.name author &&\n\nYou don't need to be paranoid and unset these, we already unset GIT_*\nvariables that aren't on a whitelist in test-lib.sh, see 'A call to\n\"unset\"' there.\n"},{"id":"367745","messageId":"CAPig+cQKKqL7QD_nwy8tvHaxuGqBXATVt2Mo+gELpif9aULc6A@mail.gmail.com","threadId":"50322","inReplyTo":"874l9v4x6p.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2019-01-27T04:48:40Z","receivedAt":"2019-01-27T04:48:55Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sat, Jan 26, 2019 at 3:53 AM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> Which, looking at this again, you'd only want if a previous test in the\n> file was leaking its state. That's not the case, so this isn't needed\n> and you can just apply this on top:\n>\n>      test_expect_success \\\n>             'author and committer config settings override user config settings' '\n>     -       sane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n>     -       sane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n>             git config user.name user &&\n>             git config user.email user@example.com &&\n>             git config author.name author &&\n\nAside from future-proofing against a test being inserted before this\none which does set those environment variables, these invocations of\nsane_unset() serve the additional purpose of documenting the interplay\nof configuration and environment, and further indicate to readers that\nthe test author took this into consideration (rather than merely\nslapping together the test without thought). As a reviewer and reader\nof the test, I appreciate the additional context the sane_unset()\ncalls provide, thus think it makes sense to retain them.\n"},{"id":"367858","messageId":"20190128185817.GA28155@whubbs1.gaikai.biz","threadId":"50322","inReplyTo":"877ees4a65.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-28T18:58:17Z","receivedAt":"2019-01-28T18:58:23Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"On Fri, Jan 25, 2019 at 11:58:10PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Fri, Jan 25 2019, William Hubbs wrote:\n> \n> > diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\n> > index b5b2ba1199..18e1ec3c1b 100644\n> > --- a/Documentation/config/user.txt\n> > +++ b/Documentation/config/user.txt\n> > @@ -1,12 +1,39 @@\n> > +author.email::\n> > +\tThe email address used for the author of newly\n> > +\tcreated commits.  Defaults to the value of the\n> > +\t`GIT_AUTHOR_EMAIL` environment variable, or if\n> > +\tthe environment variable is not set, the `user.email`\n> > +\tconfiguration variable.\n> > +\n> > +author.name::\n> > +\tThe full name used for the author of newly created commits.\n> > +\tDefaults to the value of the `GIT_AUTHOR_NAME` environment variable, or\n> > +\tif the environment variable is not set,\n> > +\tthe `user.email` configuration variable.\n> > +\n> > +committer.email::\n> > +\tThe email address used for the committer of newly created commits.\n> > +\tDefaults to the value of the `GIT_COMMITTER_EMAIL` environment\n> > +\tvariable, or if the environment variable is not set, the `user.email`\n> > +\tconfiguration variable.\n> > +\n> > +committer.name::\n> > +\tThe full name used for the committer of newly created commits.\n> > +\tDefaults to the value of the `GIT_COMMITTER_NAME` environment\n> > +\tvariable, or if the environment variable is not set, the `user.name`\n> > +\tconfiguration variable.\n> > +\n> >  user.email::\n> >  \tYour email address to be recorded in any newly created commits.\n> >  \tCan be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and\n> > -\t`EMAIL` environment variables.  See linkgit:git-commit-tree[1].\n> > +\t`EMAIL` environment variables or the `author.email` or\n> > +\t`committer.email` settings discussed above. See linkgit:git-commit-tree[1].\n> >\n> >  user.name::\n> >  \tYour full name to be recorded in any newly created commits.\n> >  \tCan be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`\n> > -\tenvironment variables.  See linkgit:git-commit-tree[1].\n> > +\tenvironment variables or the `author.name` or `committer.name`\n> > +\tsettings discussed above. See linkgit:git-commit-tree[1].\n> \n> Looks correct, although I wonder if we're at the point where it would be\n> better to present this info as a table.\n\nMaybe, but can we have someone do that in a separate patch? I ask\nbecause the documentation is not in a markup language and that would\nmake setting up a table difficult for me at best with my screen reader.\n\n> > diff --git a/builtin/am.c b/builtin/am.c\n> > index 95370313b6..53fdd22c45 100644\n> > --- a/builtin/am.c\n> > +++ b/builtin/am.c\n> > @@ -1594,7 +1594,7 @@ static void do_commit(const struct am_state *state)\n> >  \t}\n> >\n> >  \tauthor = fmt_ident(state->author_name, state->author_email,\n> > -\t\t\tstate->ignore_date ? NULL : state->author_date,\n> > +\t\t\tWANT_AUTHOR_IDENT, state->ignore_date ? NULL : state->author_date,\n> \n> This & a few other things in this series take the code beyond 79\n> characters.\n\nThis doesn't look like it is beyond 79 characters to me, but that may be\nbecause I use a tab stop width of 4.\n\nCan you reply again and flag the lines that are longer than 79\ncharacters?\n\nThanks,\n\nWilliam\n"},{"id":"367860","messageId":"xmqqr2cwa9pd.fsf@gitster-ct.c.googlers.com","threadId":"50322","inReplyTo":"20190128185817.GA28155@whubbs1.gaikai.biz","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-01-28T19:00:46Z","receivedAt":"2019-01-28T19:00:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"William Hubbs <williamh@gentoo.org> writes:\n\n> This doesn't look like it is beyond 79 characters to me, but that may be\n> because I use a tab stop width of 4.\n\nIn this project, a tab skips to multiple of 8.\n"},{"id":"367861","messageId":"8736pc4n72.fsf@evledraar.gmail.com","threadId":"50322","inReplyTo":"CAPig+cQKKqL7QD_nwy8tvHaxuGqBXATVt2Mo+gELpif9aULc6A@mail.gmail.com","subject":"Re: [PATCH v2 2/2] tests: add test for separate author and committer idents","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-01-28T19:05:53Z","receivedAt":"2019-01-28T19:05:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Sun, Jan 27 2019, Eric Sunshine wrote:\n\n> On Sat, Jan 26, 2019 at 3:53 AM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> Which, looking at this again, you'd only want if a previous test in the\n>> file was leaking its state. That's not the case, so this isn't needed\n>> and you can just apply this on top:\n>>\n>>      test_expect_success \\\n>>             'author and committer config settings override user config settings' '\n>>     -       sane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n>>     -       sane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL &&\n>>             git config user.name user &&\n>>             git config user.email user@example.com &&\n>>             git config author.name author &&\n>\n> Aside from future-proofing against a test being inserted before this\n> one which does set those environment variables, these invocations of\n> sane_unset() serve the additional purpose of documenting the interplay\n> of configuration and environment, and further indicate to readers that\n> the test author took this into consideration (rather than merely\n> slapping together the test without thought). As a reviewer and reader\n> of the test, I appreciate the additional context the sane_unset()\n> calls provide, thus think it makes sense to retain them.\n\nAs noted in <875zuc49uj.fsf@evledraar.gmail.com> (\"various override\ninteractions\") there should definitely be more tests where the\ncombination of config & env is tested for.\n\nBut I don't see how it makes things clearer to unset a bunch of\nvariables previous tests didn't set. If we applied that to our test\nsuite much of it would be pointlessly unsetting various GIT_*\nvariables.\n\nBetter to assume other tests have cleaned up their own state, and when\nit's not the case fix it.\n"},{"id":"367862","messageId":"871s4w4khs.fsf@evledraar.gmail.com","threadId":"50322","inReplyTo":"20190128185817.GA28155@whubbs1.gaikai.biz","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-01-28T20:04:15Z","receivedAt":"2019-01-28T20:04:21Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Jan 28 2019, William Hubbs wrote:\n\n> On Fri, Jan 25, 2019 at 11:58:10PM +0100, Ævar Arnfjörð Bjarmason wrote:\n>>\n>> On Fri, Jan 25 2019, William Hubbs wrote:\n>>\n>> > diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\n>> > index b5b2ba1199..18e1ec3c1b 100644\n>> > --- a/Documentation/config/user.txt\n>> > +++ b/Documentation/config/user.txt\n>> > @@ -1,12 +1,39 @@\n>> > +author.email::\n>> > +\tThe email address used for the author of newly\n>> > +\tcreated commits.  Defaults to the value of the\n>> > +\t`GIT_AUTHOR_EMAIL` environment variable, or if\n>> > +\tthe environment variable is not set, the `user.email`\n>> > +\tconfiguration variable.\n>> > +\n>> > +author.name::\n>> > +\tThe full name used for the author of newly created commits.\n>> > +\tDefaults to the value of the `GIT_AUTHOR_NAME` environment variable, or\n>> > +\tif the environment variable is not set,\n>> > +\tthe `user.email` configuration variable.\n>> > +\n>> > +committer.email::\n>> > +\tThe email address used for the committer of newly created commits.\n>> > +\tDefaults to the value of the `GIT_COMMITTER_EMAIL` environment\n>> > +\tvariable, or if the environment variable is not set, the `user.email`\n>> > +\tconfiguration variable.\n>> > +\n>> > +committer.name::\n>> > +\tThe full name used for the committer of newly created commits.\n>> > +\tDefaults to the value of the `GIT_COMMITTER_NAME` environment\n>> > +\tvariable, or if the environment variable is not set, the `user.name`\n>> > +\tconfiguration variable.\n>> > +\n>> >  user.email::\n>> >  \tYour email address to be recorded in any newly created commits.\n>> >  \tCan be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and\n>> > -\t`EMAIL` environment variables.  See linkgit:git-commit-tree[1].\n>> > +\t`EMAIL` environment variables or the `author.email` or\n>> > +\t`committer.email` settings discussed above. See linkgit:git-commit-tree[1].\n>> >\n>> >  user.name::\n>> >  \tYour full name to be recorded in any newly created commits.\n>> >  \tCan be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`\n>> > -\tenvironment variables.  See linkgit:git-commit-tree[1].\n>> > +\tenvironment variables or the `author.name` or `committer.name`\n>> > +\tsettings discussed above. See linkgit:git-commit-tree[1].\n>>\n>> Looks correct, although I wonder if we're at the point where it would be\n>> better to present this info as a table.\n>\n> Maybe, but can we have someone do that in a separate patch? I ask\n> because the documentation is not in a markup language and that would\n> make setting up a table difficult for me at best with my screen reader.\n\nI'm happy to help if you'd like. I had a thinko with \"table\", and I\nthink our asciidoc dialect doesn't support it (maybe I'm wrong), but\nthinking about it again we could just describe these variables all in\nthe same documentation. As in this hunk (which you could squash in):\n\nBEGIN QUOTE\ndiff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\nindex 18e1ec3c1b..ad3c43cf47 100644\n--- a/Documentation/config/user.txt\n+++ b/Documentation/config/user.txt\n@@ -1,39 +1,20 @@\n-author.email::\n-\tThe email address used for the author of newly\n-\tcreated commits.  Defaults to the value of the\n-\t`GIT_AUTHOR_EMAIL` environment variable, or if\n-\tthe environment variable is not set, the `user.email`\n-\tconfiguration variable.\n-\n+user.name::\n+user.email::\n author.name::\n-\tThe full name used for the author of newly created commits.\n-\tDefaults to the value of the `GIT_AUTHOR_NAME` environment variable, or\n-\tif the environment variable is not set,\n-\tthe `user.email` configuration variable.\n-\n-committer.email::\n-\tThe email address used for the committer of newly created commits.\n-\tDefaults to the value of the `GIT_COMMITTER_EMAIL` environment\n-\tvariable, or if the environment variable is not set, the `user.email`\n-\tconfiguration variable.\n-\n+author.email::\n committer.name::\n-\tThe full name used for the committer of newly created commits.\n-\tDefaults to the value of the `GIT_COMMITTER_NAME` environment\n-\tvariable, or if the environment variable is not set, the `user.name`\n-\tconfiguration variable.\n-\n-user.email::\n-\tYour email address to be recorded in any newly created commits.\n-\tCan be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and\n-\t`EMAIL` environment variables or the `author.email` or\n-\t`committer.email` settings discussed above. See linkgit:git-commit-tree[1].\n-\n-user.name::\n-\tYour full name to be recorded in any newly created commits.\n-\tCan be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME`\n-\tenvironment variables or the `author.name` or `committer.name`\n-\tsettings discussed above. See linkgit:git-commit-tree[1].\n+committer.email::\n+\tThe `user.name` and `user.email` variables determine what ends\n+\tup in the `author` and `committer` field of commit\n+\tobjects. These config variables will be overridden by\n+\t`GIT_COMMITTER_NAME` and `GIT_COMMITTER_EMAIL`,\n++\n+Most users should have no reason to set the `author.*` and\n+`committer.*` variables, but can do so to e.g. set different a\n+different E-Mail for the `committer` field. Like the `user.name` and\n+`user.email` variables, these can be overridden in the environment\n+with `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME` and\n+`GIT_COMMITTER_EMAIL`.\n\n user.useConfigOnly::\n \tInstruct Git to avoid trying to guess defaults for `user.email`\nEND QUOTE\n\nAnother thing I spotted while hacking that up is that the\ngit-commit-tree docs we're pointing to as the full explanation haven't\nbeen updated. They still just talk about user.{name,email}.\n\nAnd poking at this a bit more I see that something about this is\nintroducing new edge cases into our \"you haven't set user.name or\nuser.email\" logic. I.e. if I do:\n\n    GIT_AUTHOR_NAME=hi GIT_AUTHOR_EMAIL=blah GIT_COMMITTER_NAME=\"hello\" ./git-commit -a -m\"hi\"\n\nI end up with an object like:\n\n    author hi <blah> 1548705397 +0100\n    committer hello <avar@nix.is> 1548705397 +0100\n\nI.e. here I haven't supplied the committer E-Mail but it was inferred\n(and a warning was printed to that effect). But if I do the same thing\nwith setting author.name etc. for all fields except committer.email I'll\nget an empty (\"<>\") field for the committer E-Mail, even though it\nprinted \"Your name and email address were configured automatically based\non your username and hostname\".\n\n\n>> > diff --git a/builtin/am.c b/builtin/am.c\n>> > index 95370313b6..53fdd22c45 100644\n>> > --- a/builtin/am.c\n>> > +++ b/builtin/am.c\n>> > @@ -1594,7 +1594,7 @@ static void do_commit(const struct am_state *state)\n>> >  \t}\n>> >\n>> >  \tauthor = fmt_ident(state->author_name, state->author_email,\n>> > -\t\t\tstate->ignore_date ? NULL : state->author_date,\n>> > +\t\t\tWANT_AUTHOR_IDENT, state->ignore_date ? NULL : state->author_date,\n>>\n>> This & a few other things in this series take the code beyond 79\n>> characters.\n>\n> This doesn't look like it is beyond 79 characters to me, but that may be\n> because I use a tab stop width of 4.\n>\n> Can you reply again and flag the lines that are longer than 79\n> characters?\n\nI see Junio replied to this already.\n\nAdjusting for limited time, I'm happy to help out with this series,\nparticularly if you have visual (screen reader) issues that make some of\nthis prohibitive for you. Just say what you need.\n"},{"id":"367867","messageId":"xmqqmunka2nb.fsf@gitster-ct.c.googlers.com","threadId":"50322","inReplyTo":"871s4w4khs.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-01-28T21:33:12Z","receivedAt":"2019-01-28T21:33:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> I'm happy to help if you'd like. I had a thinko with \"table\", and I\n> think our asciidoc dialect doesn't support it (maybe I'm wrong), but\n> thinking about it again we could just describe these variables all in\n> the same documentation. As in this hunk (which you could squash in):\n>\n> BEGIN QUOTE\n> diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt\n> index 18e1ec3c1b..ad3c43cf47 100644\n> --- a/Documentation/config/user.txt\n> +++ b/Documentation/config/user.txt\n> @@ -1,39 +1,20 @@\n> +user.name::\n> +user.email::\n>  author.name::\n> +author.email::\n>  committer.name::\n> +committer.email::\n> +\tThe `user.name` and `user.email` variables determine what ends\n> +\tup in the `author` and `committer` field of commit\n> +\tobjects. These config variables will be overridden by\n> +\t`GIT_COMMITTER_NAME` and `GIT_COMMITTER_EMAIL`,\n\nYou forgot to list two more obvious ones here.\n\n> ++\n> +Most users should have no reason to set the `author.*` and\n> +`committer.*` variables, but can do so to e.g. set different a\n> +different E-Mail for the `committer` field. Like the `user.name` and\n> +`user.email` variables, these can be overridden in the environment\n> +with `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME` and\n> +`GIT_COMMITTER_EMAIL`.\n\nI do not see a strong reason to say \"most users should have no\nreason\", especially without arguing why (and I do not think this is\na place to make such an argument, either).\n\n    The `user.*` variables can be used to set both author and committer\n    names and e-mail addresses to the same value; users who want to set\n    the committer and author identities differently can use the\n    `author.*` and `committer.*` variables.\n\nor something along that line, perhaps?\n\n"},{"id":"367904","messageId":"20190128233022.GA29068@whubbs1.gaikai.biz","threadId":"50322","inReplyTo":"871s4w4khs.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-28T23:30:22Z","receivedAt":"2019-01-28T23:30:26Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"On Mon, Jan 28, 2019 at 09:04:15PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> Adjusting for limited time, I'm happy to help out with this series,\n> particularly if you have visual (screen reader) issues that make some of\n> this prohibitive for you. Just say what you need.\n\nI guess the best way to handle formatting issues would be, during your\nnormal review, make a note directly below the affected line about what\nis wrong with the formatting and I'll fix it during the next pass.\n\nOr, another option would be to reply with a diff that I can apply on top\nof my patch.\n\nThanks,\n\nWilliam\n"},{"id":"368060","messageId":"20190129224209.GA3392@whubbs1.gaikai.biz","threadId":"50322","inReplyTo":"877ees4a65.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 1/2] config: allow giving separate author and committer idents","fromName":"William Hubbs","fromEmail":"williamh@gentoo.org","sentAt":"2019-01-29T22:42:09Z","receivedAt":"2019-01-29T22:42:15Z","isPatch":true,"sender":{"key":"williamh@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/64355?v=4"},"body":"On Fri, Jan 25, 2019 at 11:58:10PM +0100, Ævar Arnfjörð Bjarmason wrote:\n> \n> On Fri, Jan 25 2019, William Hubbs wrote:\n> \n> > @@ -480,6 +515,46 @@ int git_ident_config(const char *var, const char *value, void *data)\n> >  \t\treturn 0;\n> >  \t}\n> >\n> > +\tif (!strcmp(var, \"author.name\")) {\n> > +\t\tif (!value)\n> > +\t\t\treturn config_error_nonbool(var);\n> > +\t\tstrbuf_reset(&git_author_name);\n> > +\t\tstrbuf_addstr(&git_author_name, value);\n> > +\t\tauthor_ident_explicitly_given |= IDENT_NAME_GIVEN;\n> > +\t\tident_config_given |= IDENT_NAME_GIVEN;\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\tif (!strcmp(var, \"author.email\")) {\n> > +\t\tif (!value)\n> > +\t\t\treturn config_error_nonbool(var);\n> > +\t\tstrbuf_reset(&git_author_email);\n> > +\t\tstrbuf_addstr(&git_author_email, value);\n> > +\t\tauthor_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n> > +\t\tident_config_given |= IDENT_MAIL_GIVEN;\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\tif (!strcmp(var, \"committer.name\")) {\n> > +\t\tif (!value)\n> > +\t\t\treturn config_error_nonbool(var);\n> > +\t\tstrbuf_reset(&git_committer_name);\n> > +\t\tstrbuf_addstr(&git_committer_name, value);\n> > +\t\tcommitter_ident_explicitly_given |= IDENT_NAME_GIVEN;\n> > +\t\tident_config_given |= IDENT_NAME_GIVEN;\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\tif (!strcmp(var, \"committer.email\")) {\n> > +\t\tif (!value)\n> > +\t\t\treturn config_error_nonbool(var);\n> > +\t\tstrbuf_reset(&git_committer_email);\n> > +\t\tstrbuf_addstr(&git_committer_email, value);\n> > +\t\tcommitter_ident_explicitly_given |= IDENT_MAIL_GIVEN;\n> > +\t\tident_config_given |= IDENT_MAIL_GIVEN;\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> \n> This whole thing should be split into a static function. It's the same\n> code copy/pasted 4x times just with a differnet value for \"var\", the\n> strbuf variable & IDENT_*_GIVEN.\n\nI have moved most of this into a separate function in the next version\nof the patch. However, I do not see a way to factor it down further. Let\nme know what you think when I resend.\n\nAlso, if you see anything  longer than 79 characters, please let me know\nwhere the long lines are and I have no problem reformatting them.\n\nThanks much.\n\nWilliam\n\n"}]}