{"thread":{"id":"46178","subject":"[PATCH v4 0/6] Avoid problem where git_dir is set after alias expansion","startedAt":"2017-06-14T11:35:50Z","lastAt":"2017-06-15T19:45:22Z","messageCount":10,"participants":["Johannes Schindelin","Jeff King","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":6},"messages":[{"id":"322236","messageId":"cover.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":null,"subject":"[PATCH v4 0/6] Avoid problem where git_dir is set after alias expansion","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:22Z","receivedAt":"2017-06-14T11:35:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When expanding an alias in a subdirectory, we setup the git_dir\n(gently), read the config, and then restore the \"env\" (e.g. the current\nworking directory) so that the command specified by the alias can run\ncorrectly.\n\nWhat we failed to reset was the git_dir, meaning that in the most common\ncase, it was now pointing to a .git/ directory *in the subdirectory*.\n\nThis problem was identified in the GVFS fork, where a pre-command hook\nwas introduced to allow pre-fetching missing blobs.\n\nAn early quick fix in the GVFS fork simply built on top of the\nsave_env_before_alias() hack, introducing another hack that saves the\ngit_dir and restores it after an alias is expanded:\n\n\thttps://github.com/Microsoft/git/commit/2d859ba3b\n\nThat is very hacky, though, and it is much better (although much more\ninvolved, too) to fix this \"properly\", i.e. by replacing the ugly\nsave/restore logic by simply using the early config code path.\n\nHowever, aliases are strange beasts.\n\nWhen an alias refers to a single Git command (originally the sole\nintention of aliases), the current working directory is restored to what\nit had been before expanding the alias.\n\nBut when an alias starts with an exclamation point, i.e. referring to a\ncommand-line to be interpreted by the shell, the current working\ndirectory is no longer in the subdirectory but instead in the worktree's\ntop-level directory.\n\nThis is even true for worktrees added by `git worktree add`.\n\nBut when we are inside the .git/ directory, the current working\ndirectory is *restored* to the subdirectory inside the .git/ directory.\n\nIn short, the rules (what is the expected current working directory after\nexpanding an alias and before actually running it) are a bit complicated.\n\nThis patch series does *not* address the problem identified by Brandon\nWilliams where the early config machinery fails to look into the\n*commondir* in worktrees added by `git worktree add`. My hope is that\nBrandon is okay with applying this patch series before his config patch\nseries.\n\nChanges since v3:\n\n- avoided the strbuf in alias_lookup() by using skip_prefix() and !strcmp()\n  instead.\n\n- fixed tyop (\"read\" instead of \"reading\", causing Junio to stumble) in the\n  commit message of 6/6.\n\n\nJohannes Schindelin (6):\n  discover_git_directory(): avoid setting invalid git_dir\n  config: report correct line number upon error\n  help: use early config when autocorrecting aliases\n  t1308: relax the test verifying that empty alias values are disallowed\n  t7006: demonstrate a problem with aliases in subdirectories\n  Use the early config machinery to expand aliases\n\n alias.c                | 29 +++++++++++++++++++-------\n config.c               |  3 ++-\n git.c                  | 55 ++++----------------------------------------------\n help.c                 |  2 +-\n setup.c                |  1 +\n t/t1300-repo-config.sh |  6 ++++++\n t/t1308-config-set.sh  |  4 +++-\n t/t7006-pager.sh       | 11 ++++++++++\n 8 files changed, 50 insertions(+), 61 deletions(-)\n\n\nbase-commit: 02a2850ad58eff6de70eb2dc5f96345c463857ac\nPublished-As: https://github.com/dscho/git/releases/tag/alias-early-config-v4\nFetch-It-Via: git fetch https://github.com/dscho/git alias-early-config-v4\n\nInterdiff vs v3:\n diff --git a/alias.c b/alias.c\n index 6bdc9363037..5df052ae4c4 100644\n --- a/alias.c\n +++ b/alias.c\n @@ -2,15 +2,16 @@\n  \n  struct config_alias_data\n  {\n -\tstruct strbuf key;\n +\tconst char *alias;\n  \tchar *v;\n  };\n  \n  static int config_alias_cb(const char *key, const char *value, void *d)\n  {\n  \tstruct config_alias_data *data = d;\n +\tconst char *p;\n  \n -\tif (!strcmp(key, data->key.buf))\n +\tif (skip_prefix(key, \"alias.\", &p) && !strcmp(p, data->alias))\n  \t\treturn git_config_string((const char **)&data->v, key, value);\n  \n  \treturn 0;\n @@ -18,12 +19,9 @@ static int config_alias_cb(const char *key, const char *value, void *d)\n  \n  char *alias_lookup(const char *alias)\n  {\n -\tstruct config_alias_data data = { STRBUF_INIT, NULL };\n +\tstruct config_alias_data data = { alias, NULL };\n  \n -\tstrbuf_addf(&data.key, \"alias.%s\", alias);\n -\tif (git_config_key_is_valid(data.key.buf))\n -\t\tread_early_config(config_alias_cb, &data);\n -\tstrbuf_release(&data.key);\n +\tread_early_config(config_alias_cb, &data);\n  \n  \treturn data.v;\n  }\n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n"},{"id":"322237","messageId":"77bc4209b6e1e782dca367c7b3b2500e0cb655d0.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 1/6] discover_git_directory(): avoid setting invalid git_dir","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:26Z","receivedAt":"2017-06-14T11:35:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When discovering a .git/ directory, we take pains to ensure that its\nrepository format version matches Git's expectations, and we return NULL\notherwise.\n\nHowever, we still appended the invalid path to the strbuf passed as\nargument.\n\nLet's just reset the strbuf to the state before we appended the .git/\ndirectory that was eventually rejected.\n\nThere is another early return path in that function, when\nsetup_git_directory_gently_1() returns GIT_DIR_NONE or an error. In that\ncase, the gitdir parameter has not been touched, therefore there is no\nneed for an equivalent change in that code path.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/setup.c b/setup.c\nindex ba6e8551788..ad12d79ac02 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -982,6 +982,7 @@ const char *discover_git_directory(struct strbuf *gitdir)\n \t\twarning(\"ignoring git dir '%s': %s\",\n \t\t\tgitdir->buf + gitdir_offset, err.buf);\n \t\tstrbuf_release(&err);\n+\t\tstrbuf_setlen(gitdir, gitdir_offset);\n \t\treturn NULL;\n \t}\n \n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n\n"},{"id":"322238","messageId":"9ae04aedac595abdf9f24b61df983f1539761046.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 3/6] help: use early config when autocorrecting aliases","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:50Z","receivedAt":"2017-06-14T11:36:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Git has this feature which suggests similar commands (including aliases)\nin case the user specified an unknown command.\n\nThis feature currently relies on a side effect of the way we expand\naliases right now: when a command is not a builtin, we use the regular\nconfig machinery (meaning: discovering the .git/ directory and\ninitializing global state such as the config cache) to see whether the\ncommand refers to an alias.\n\nHowever, we will change the way aliases are expanded in the next\ncommits, to use the early config instead. That means that the\nautocorrect feature can no longer discover the available aliases by\nlooking at the config cache (because it has not yet been initialized).\n\nSo let's just use the early config machinery instead.\n\nThis is slightly less performant than the previous way, as the early\nconfig is used *twice*: once to see whether the command refers to an\nalias, and then to see what aliases are most similar. However, this is\nhardly a performance-critical code path, so performance is less important\nhere.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n help.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/help.c b/help.c\nindex db7f3d79a01..b44c55ec2da 100644\n--- a/help.c\n+++ b/help.c\n@@ -289,7 +289,7 @@ const char *help_unknown_cmd(const char *cmd)\n \tmemset(&other_cmds, 0, sizeof(other_cmds));\n \tmemset(&aliases, 0, sizeof(aliases));\n \n-\tgit_config(git_unknown_cmd_config, NULL);\n+\tread_early_config(git_unknown_cmd_config, NULL);\n \n \tload_command_list(\"git-\", &main_cmds, &other_cmds);\n \n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n\n"},{"id":"322239","messageId":"2c480fe5c160c560b501b6190a95154ef6b19ba7.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 4/6] t1308: relax the test verifying that empty alias values are disallowed","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:53Z","receivedAt":"2017-06-14T11:36:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"We are about to change the way aliases are expanded, to use the early\nconfig machinery.\n\nThis machinery reports errors in a slightly different manner than the\ncached config machinery.\n\nLet's not get hung up by the precise wording of the message mentioning\nthe line number. It is really sufficient to verify that all the relevant\ninformation is given to the user.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t1308-config-set.sh | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh\nindex e495a616161..bafed5c9b88 100755\n--- a/t/t1308-config-set.sh\n+++ b/t/t1308-config-set.sh\n@@ -226,7 +226,9 @@ test_expect_success 'check line errors for malformed values' '\n \t\tbr\n \tEOF\n \ttest_expect_code 128 git br 2>result &&\n-\ttest_i18ngrep \"fatal: .*alias\\.br.*\\.git/config.*line 2\" result\n+\ttest_i18ngrep \"missing value for .alias\\.br\" result &&\n+\ttest_i18ngrep \"fatal: .*\\.git/config\" result &&\n+\ttest_i18ngrep \"fatal: .*line 2\" result\n '\n \n test_expect_success 'error on modifying repo config without repo' '\n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n\n"},{"id":"322240","messageId":"af8b91b870e67600690fc9c1886fa32985b66b0b.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 2/6] config: report correct line number upon error","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:46Z","receivedAt":"2017-06-14T11:36:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When get_value() parses a key/value pair, it is possible that the line\nnumber is decreased (because the \\n has been consumed already) before the\nkey/value pair is passed to the callback function, to allow for the\ncorrect line to be attributed in case of an error.\n\nHowever, when git_parse_source() asks get_value() to parse the key/value\npair, the error reporting is performed *after* get_value() returns.\n\nWhich means that we have to be careful not to increase the line number\nin get_value() after the callback function returned an error.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.c               | 3 ++-\n t/t1300-repo-config.sh | 6 ++++++\n 2 files changed, 8 insertions(+), 1 deletion(-)\n\ndiff --git a/config.c b/config.c\nindex 34a139c40bd..547daf87d40 100644\n--- a/config.c\n+++ b/config.c\n@@ -604,7 +604,8 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)\n \t */\n \tcf->linenr--;\n \tret = fn(name->buf, value, data);\n-\tcf->linenr++;\n+\tif (ret >= 0)\n+\t\tcf->linenr++;\n \treturn ret;\n }\n \ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex 13b7851f7c2..a37ef042221 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -703,6 +703,12 @@ test_expect_success 'invalid unit' '\n \ttest_i18ngrep \"bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit\" actual\n '\n \n+test_expect_success 'line number is reported correctly' '\n+\tprintf \"[bool]\\n\\tvar\\n\" >invalid &&\n+\ttest_must_fail git config -f invalid --path bool.var 2>actual &&\n+\ttest_i18ngrep \"line 2\" actual\n+'\n+\n test_expect_success 'invalid stdin config' '\n \techo \"[broken\" | test_must_fail git config --list --file - >output 2>&1 &&\n \ttest_i18ngrep \"bad config line 1 in standard input\" output\n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n\n"},{"id":"322241","messageId":"ba1ae3d6cc5c1722d00480267cfa9b4946c0c0ea.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 5/6] t7006: demonstrate a problem with aliases in subdirectories","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:35:56Z","receivedAt":"2017-06-14T11:36:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When expanding aliases, the git_dir is set during the alias expansion\n(by virtue of running setup_git_directory_gently()).\n\nThis git_dir may be relative to the current working directory, and\nindeed often is simply \".git/\".\n\nWhen the alias expands to a shell command, we restore the original\nworking directory, though, yet we do not reset git_dir.\n\nAs a consequence, subsequent read_early_config() runs will mistake the\ngit_dir to be populated properly and not find the correct config.\n\nDemonstrate this problem by adding a test case.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n t/t7006-pager.sh | 11 +++++++++++\n 1 file changed, 11 insertions(+)\n\ndiff --git a/t/t7006-pager.sh b/t/t7006-pager.sh\nindex 4f3794d415e..83881ec3a0c 100755\n--- a/t/t7006-pager.sh\n+++ b/t/t7006-pager.sh\n@@ -391,6 +391,17 @@ test_expect_success TTY 'core.pager in repo config works and retains cwd' '\n \t)\n '\n \n+test_expect_failure TTY 'core.pager is found via alias in subdirectory' '\n+\tsane_unset GIT_PAGER &&\n+\ttest_config core.pager \"cat >via-alias\" &&\n+\t(\n+\t\tcd sub &&\n+\t\trm -f via-alias &&\n+\t\ttest_terminal git -c alias.r=\"-p rev-parse\" r HEAD &&\n+\t\ttest_path_is_file via-alias\n+\t)\n+'\n+\n test_doesnt_paginate      expect_failure test_must_fail 'git -p nonsense'\n \n test_pager_choices                       'git shortlog'\n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n\n\n"},{"id":"322242","messageId":"b75481173390d70a64a1156421aaa0ec5aa4abc2.1497440104.git.johannes.schindelin@gmx.de","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 6/6] Use the early config machinery to expand aliases","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-14T11:36:00Z","receivedAt":"2017-06-14T11:36:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Instead of discovering the .git/ directory, reading the config and then\ntrying to painstakingly reset all the global state if we did not find a\nmatching alias, let's use the early config machinery instead.\n\nIt may look like unnecessary work to discover the .git/ directory in the\nearly config machinery and then call setup_git_directory_gently() in the\ncase of a shell alias, repeating the very same discovery *again*.\nHowever, we have to do this as the early config machinery takes pains\n*not* to touch any global state, while shell aliases expect a possibly\nchanged working directory and at least the GIT_PREFIX and GIT_DIR\nvariables to be set.\n\nThis change also fixes a known issue where Git tried to read the pager\nconfig from an incorrect path in a subdirectory of a Git worktree if an\nalias expanded to a shell command.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n alias.c          | 29 ++++++++++++++++++++++-------\n git.c            | 55 ++++---------------------------------------------------\n t/t7006-pager.sh |  2 +-\n 3 files changed, 27 insertions(+), 59 deletions(-)\n\ndiff --git a/alias.c b/alias.c\nindex 3b90397a99d..5df052ae4c4 100644\n--- a/alias.c\n+++ b/alias.c\n@@ -1,14 +1,29 @@\n #include \"cache.h\"\n \n+struct config_alias_data\n+{\n+\tconst char *alias;\n+\tchar *v;\n+};\n+\n+static int config_alias_cb(const char *key, const char *value, void *d)\n+{\n+\tstruct config_alias_data *data = d;\n+\tconst char *p;\n+\n+\tif (skip_prefix(key, \"alias.\", &p) && !strcmp(p, data->alias))\n+\t\treturn git_config_string((const char **)&data->v, key, value);\n+\n+\treturn 0;\n+}\n+\n char *alias_lookup(const char *alias)\n {\n-\tchar *v = NULL;\n-\tstruct strbuf key = STRBUF_INIT;\n-\tstrbuf_addf(&key, \"alias.%s\", alias);\n-\tif (git_config_key_is_valid(key.buf))\n-\t\tgit_config_get_string(key.buf, &v);\n-\tstrbuf_release(&key);\n-\treturn v;\n+\tstruct config_alias_data data = { alias, NULL };\n+\n+\tread_early_config(config_alias_cb, &data);\n+\n+\treturn data.v;\n }\n \n #define SPLIT_CMDLINE_BAD_ENDING 1\ndiff --git a/git.c b/git.c\nindex 8ff44f081d4..58ef570294d 100644\n--- a/git.c\n+++ b/git.c\n@@ -16,50 +16,6 @@ const char git_more_info_string[] =\n \t   \"to read about a specific subcommand or concept.\");\n \n static int use_pager = -1;\n-static char *orig_cwd;\n-static const char *env_names[] = {\n-\tGIT_DIR_ENVIRONMENT,\n-\tGIT_WORK_TREE_ENVIRONMENT,\n-\tGIT_IMPLICIT_WORK_TREE_ENVIRONMENT,\n-\tGIT_PREFIX_ENVIRONMENT\n-};\n-static char *orig_env[4];\n-static int save_restore_env_balance;\n-\n-static void save_env_before_alias(void)\n-{\n-\tint i;\n-\n-\tassert(save_restore_env_balance == 0);\n-\tsave_restore_env_balance = 1;\n-\torig_cwd = xgetcwd();\n-\tfor (i = 0; i < ARRAY_SIZE(env_names); i++) {\n-\t\torig_env[i] = getenv(env_names[i]);\n-\t\torig_env[i] = xstrdup_or_null(orig_env[i]);\n-\t}\n-}\n-\n-static void restore_env(int external_alias)\n-{\n-\tint i;\n-\n-\tassert(save_restore_env_balance == 1);\n-\tsave_restore_env_balance = 0;\n-\tif (!external_alias && orig_cwd && chdir(orig_cwd))\n-\t\tdie_errno(\"could not move to %s\", orig_cwd);\n-\tfree(orig_cwd);\n-\tfor (i = 0; i < ARRAY_SIZE(env_names); i++) {\n-\t\tif (external_alias &&\n-\t\t    !strcmp(env_names[i], GIT_PREFIX_ENVIRONMENT))\n-\t\t\tcontinue;\n-\t\tif (orig_env[i]) {\n-\t\t\tsetenv(env_names[i], orig_env[i], 1);\n-\t\t\tfree(orig_env[i]);\n-\t\t} else {\n-\t\t\tunsetenv(env_names[i]);\n-\t\t}\n-\t}\n-}\n \n static void commit_pager_choice(void) {\n \tswitch (use_pager) {\n@@ -250,19 +206,18 @@ static int handle_alias(int *argcp, const char ***argv)\n \tconst char **new_argv;\n \tconst char *alias_command;\n \tchar *alias_string;\n-\tint unused_nongit;\n-\n-\tsave_env_before_alias();\n-\tsetup_git_directory_gently(&unused_nongit);\n \n \talias_command = (*argv)[0];\n \talias_string = alias_lookup(alias_command);\n \tif (alias_string) {\n \t\tif (alias_string[0] == '!') {\n \t\t\tstruct child_process child = CHILD_PROCESS_INIT;\n+\t\t\tint nongit_ok;\n+\n+\t\t\t/* Aliases expect GIT_PREFIX, GIT_DIR etc to be set */\n+\t\t\tsetup_git_directory_gently(&nongit_ok);\n \n \t\t\tcommit_pager_choice();\n-\t\t\trestore_env(1);\n \n \t\t\tchild.use_shell = 1;\n \t\t\targv_array_push(&child.args, alias_string + 1);\n@@ -308,8 +263,6 @@ static int handle_alias(int *argcp, const char ***argv)\n \t\tret = 1;\n \t}\n \n-\trestore_env(0);\n-\n \terrno = saved_errno;\n \n \treturn ret;\ndiff --git a/t/t7006-pager.sh b/t/t7006-pager.sh\nindex 83881ec3a0c..20b4d83c281 100755\n--- a/t/t7006-pager.sh\n+++ b/t/t7006-pager.sh\n@@ -391,7 +391,7 @@ test_expect_success TTY 'core.pager in repo config works and retains cwd' '\n \t)\n '\n \n-test_expect_failure TTY 'core.pager is found via alias in subdirectory' '\n+test_expect_success TTY 'core.pager is found via alias in subdirectory' '\n \tsane_unset GIT_PAGER &&\n \ttest_config core.pager \"cat >via-alias\" &&\n \t(\n-- \n2.13.1.windows.1.1.ga36e14b3aaa\n"},{"id":"322296","messageId":"20170615063739.xpja3bayrmiogbcz@sigill.intra.peff.net","threadId":"46178","inReplyTo":"cover.1497440104.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v4 0/6] Avoid problem where git_dir is set after alias expansion","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-06-15T06:37:40Z","receivedAt":"2017-06-15T06:37:51Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 14, 2017 at 01:35:22PM +0200, Johannes Schindelin wrote:\n\n> Changes since v3:\n> \n> - avoided the strbuf in alias_lookup() by using skip_prefix() and !strcmp()\n>   instead.\n> \n> - fixed tyop (\"read\" instead of \"reading\", causing Junio to stumble) in the\n>   commit message of 6/6.\n\nThanks, this whole series looks good to me (and it sounds like Brandon\nwill address the common-dir thing on top).\n\n-Peff\n"},{"id":"322380","messageId":"xmqqd1a511rr.fsf@gitster.mtv.corp.google.com","threadId":"46178","inReplyTo":"b75481173390d70a64a1156421aaa0ec5aa4abc2.1497440104.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v4 6/6] Use the early config machinery to expand aliases","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-06-15T19:36:40Z","receivedAt":"2017-06-15T19:36:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> +struct config_alias_data\n> +{\n\nStyle: \"struct config_alias_data {\"\n\nwhich I can tweak while applying.\n\nOther than that, everything looks good.\n\nThanks.\n"},{"id":"322381","messageId":"alpine.DEB.2.21.1.1706152144390.4200@virtualbox","threadId":"46178","inReplyTo":"xmqqd1a511rr.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v4 6/6] Use the early config machinery to expand aliases","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-06-15T19:44:51Z","receivedAt":"2017-06-15T19:45:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Thu, 15 Jun 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > +struct config_alias_data\n> > +{\n> \n> Style: \"struct config_alias_data {\"\n> \n> which I can tweak while applying.\n\nPlease do.\n\n> Other than that, everything looks good.\n\nThanks,\nDscho\n"}]}