Hi Ed, [re-Cc:ing the list, I hope you don't mind] On Mon, 13 Jul 2020, Edward Thomson wrote: > On Mon, Jul 13, 2020 at 8:38 PM Johannes Schindelin > <Johannes.Schindelin@xxxxxx> wrote: > > On Sun, 12 Jul 2020, Edward Thomson wrote: > > > One thing that isn't obvious to me, though, is why templates take > > > precedence over the command-line option. I would expect the > > > command-line option to be the highest priority option given, just > > > like configuration values specified on the command-line override > > > values from configuration files. > > > > Side note: I have not tested this, but I trust you did, and my reading > > of the code agrees that it does this. > > I was speaking about the notion of configuration options specified with > `-c` on the command line overridding things in configuration files. > Like how you override `init.templateDir` on the command line: > > > The truth is that overriding the default name via editing the templates is > > just not a very good strategy, it is fraught with peril, as e.g. > > `init.templateDir` is a thing that can be easily specified via the > > command-line (`git -c init.templateDir=/tmp/my-templates init`). > > I agree that setting a template that contains `HEAD` is perilous. But > it's an established and supported bit of peril. I think that the question > of configuration specificity is _also_ an established one (and not nearly > so perilous). Just like `-cinit.defaultBranch` overrides the global > configuration, I would expect it to override the templates as well. Is it really well-established? If so, it might really be worth doing something like this: -- snip -- diff --git a/builtin/init-db.c b/builtin/init-db.c index cee64823cbb..9149f9e51f5 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -210,7 +210,7 @@ static int create_default_files(const char *template_path, struct strbuf buf = STRBUF_INIT; char *path; char junk[2]; - int reinit; + int reinit, override_HEAD_in_templates = 0; int filemode; struct strbuf err = STRBUF_INIT; @@ -218,6 +218,12 @@ static int create_default_files(const char *template_path, init_db_template_dir = NULL; /* re-set in case it was set before */ git_config(git_init_db_config, NULL); + if (initial_branch) { + path = git_path_buf(&buf, "HEAD"); + override_HEAD_in_templates = access(path, R_OK) || + readlink(path, junk, sizeof(junk)-1) < 0; + } + /* * First copy the templates -- we might have the default * config file there, in which case we would want to read @@ -265,7 +271,7 @@ static int create_default_files(const char *template_path, path = git_path_buf(&buf, "HEAD"); reinit = (!access(path, R_OK) || readlink(path, junk, sizeof(junk)-1) != -1); - if (!reinit) { + if (!reinit || override_HEAD_in_templates) { char *ref; if (!initial_branch) -- snap -- Note that I initially considered moving the `reinit = [...]` part to before the `copy_templates()` call, but `reinit` actually does quite a bit more than just guard the symref creation of `HEAD`: it also guards the `core.filemode` test, the `core.symlinks` test and the `core.ignoreCase` test. There _might_ be legitimate use cases to side-step those by delivering a `HEAD` in the templates (which is, just as setting the initial branch using templates, a relatively awkward and fragile way to override it, but hey, we're trying to address exactly such a scenario). However, even having written the patch (which would still lack a regression test), I am not 100% certain that we would want to risk including it in v2.28.0. It strikes me as such a fringe use case (with relatively obvious ways out) while the patch is not completely risk free (I _think_ it should be safe, of course, but it touches a relatively central part of Git). Ciao, Dscho