Hi Junio, On Tue, 17 Dec 2019, Junio C Hamano wrote: > "Johannes Schindelin via GitGitGadget" <gitgitgadget@xxxxxxxxx> > writes: > > > diff --git a/builtin/stash.c b/builtin/stash.c > > index 4e806176b0..2dafd97766 100644 > > --- a/builtin/stash.c > > +++ b/builtin/stash.c > > @@ -999,9 +999,9 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, > > { > > int ret = 0; > > struct child_process cp_read_tree = CHILD_PROCESS_INIT; > > - struct child_process cp_add_i = CHILD_PROCESS_INIT; > > struct child_process cp_diff_tree = CHILD_PROCESS_INIT; > > struct index_state istate = { NULL }; > > + char *old_index_env = NULL, *old_repo_index_file; > > > > remove_path(stash_index_path.buf); > > > > Together with the previous step, it makes sense. Earlier we always > spawned the scripted version. Now we first give control to the C > code and allow it to punt to the scripted version unless it is told > to take control with USE_BUILTIN. > > > @@ -1015,16 +1015,19 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, > > } > > > > /* Find out what the user wants. */ > > - cp_add_i.git_cmd = 1; > > - argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash", > > - "--", NULL); > > - add_pathspecs(&cp_add_i.args, ps); > > - argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s", > > - stash_index_path.buf); > > - if (run_command(&cp_add_i)) { > > - ret = -1; > > - goto done; > > - } > > + old_repo_index_file = the_repository->index_file; > > + the_repository->index_file = stash_index_path.buf; > > + old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); > > + setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); > > + > > + ret = run_add_interactive(NULL, "--patch=stash", ps); > > + > > + the_repository->index_file = old_repo_index_file; > > + if (old_index_env && *old_index_env) > > + setenv(INDEX_ENVIRONMENT, old_index_env, 1); > > + else > > + unsetenv(INDEX_ENVIRONMENT); > > + FREE_AND_NULL(old_index_env); > > OK. I suspect that, as we move more stuff that used to be an > external call with one-shot environment assignments like this to an > internall call, we'd see patterns of "save away the state of this > and that environment variables, then replace them with these values" > paired with "now restore the state of those environment variables". > > We might eventually want to add a helper for doing so easily, which > may make the caller look like > > extern void save_environment(struct saved_env *, ...); > > struct saved_env env; > save_environment(&env, > INDEX_ENVIRONMENT, the_repository->index_file, > NULL /* end of "VAR, val" tuples */); > > ret = run_add_interactive(NULL, "--patch=stash", ps); > > restore_environment(&env); > > It might (or might not) be premature to introduce such a helper at > this stage in the series, though. To be honest, I would rather have this at a different layer: I'd like `run_add_interactive()` to take an optional path to the index, to be able to override the default `<gitdir>/index`. But that requires either quite a lot of changes to the Perl script, or it needs to wait until the built-in version of `git add -p` stabilized enough to allow retiring the Perl script. I kinda aimed for the latter solution. Ciao, Dscho