Re: [PATCH 4/7] built-in stash: use the built-in `git add -p` if so configured
- From
Johannes Schindelin <johannes.schindelin@gmx.de>
- Date
- Dec 21, 2019, 21:26 UTC
- Message-ID
- <nycvar.QRO.7.76.6.1912212224180.46@tvgsbejvaqbjf.bet>
- In-Reply-To
- <xmqqr212g0xp.fsf@gitster-ct.c.googlers.com>
Hi Junio,
On Tue, 17 Dec 2019, Junio C Hamano wrote:
Show 74 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> 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