mbox series

[0/8] build-in add -i: implement all commands in the main loop

Message ID pull.171.git.1573821382.gitgitgadget@gmail.com (mailing list archive)
Headers show
Series build-in add -i: implement all commands in the main loop | expand

Message

Derrick Stolee via GitGitGadget Nov. 15, 2019, 12:36 p.m. UTC
Based on the js/builtin-add-i branch, this patch series implements the rest
of the commands in git add -i's main loop: update, revert, add_untracked, 
patch, diff, and quit. Apart from quit, these commands are all very similar
in that they first build a list of files, display it, let the user choose
which ones to act on, and then perform the action.

Note that the patch command is not actually converted to C, not completely
at least: the built-in version simply hands off to git add--interactive 
after letting the user select which files to act on.

The reason for this omission is practicality. Out of the 1,800+ lines of 
git-add--interactive.perl, over a thousand deal just with the git add -p 
part. I did convert that functionality already (to be contributed in a
separate patch series, see https://github.com/gitgitgadget/git/pull/173),
discovering that there is so little overlap between the git add --patch part
and the rest of git add --interactive that I could put the former into a
totally different file: add-patch.c.

Johannes Schindelin (8):
  built-in add -i: allow filtering the modified files list
  built-in add -i: prepare for multi-selection commands
  built-in add -i: implement the `update` command
  built-in add -i: re-implement `revert` in C
  built-in add -i: re-implement `add-untracked` in C
  built-in add -i: implement the `patch` command
  built-in add -i: re-implement the `diff` command
  built-in add -i: offer the `quit` command

 add-interactive.c | 608 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 553 insertions(+), 55 deletions(-)


base-commit: 2b5d5c1524d62add395da2b0ef50bbbe342362e4
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-171%2Fdscho%2Fadd-i-in-c-all-except-patch-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-171/dscho/add-i-in-c-all-except-patch-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/171

Comments

Junio C Hamano Nov. 18, 2019, 2:17 a.m. UTC | #1
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> Based on the js/builtin-add-i branch, this patch series implements the rest
> of the commands in git add -i's main loop: update, revert, add_untracked, 
> patch, diff, and quit. Apart from quit, these commands are all very similar
> in that they first build a list of files, display it, let the user choose
> which ones to act on, and then perform the action.

So, this obviously depends on the previous "let's start the main
loop" series, in which I recall you found at least one remaining bug
after sending the latest round.

I'd prefer to queue this on top of the iteration of that series,
which would hopefully become the final one, which would let me avoid
one rebase of this series ;-)

Thanks.
Junio C Hamano Nov. 18, 2019, 2:22 a.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
>> Based on the js/builtin-add-i branch, this patch series implements the rest
>> of the commands in git add -i's main loop: update, revert, add_untracked, 
>> patch, diff, and quit. Apart from quit, these commands are all very similar
>> in that they first build a list of files, display it, let the user choose
>> which ones to act on, and then perform the action.
>
> So, this obviously depends on the previous "let's start the main
> loop" series, in which I recall you found at least one remaining bug
> after sending the latest round.
>
> I'd prefer to queue this on top of the iteration of that series,
> which would hopefully become the final one, which would let me avoid
> one rebase of this series ;-)
>
> Thanks.

I found the v7 on the list, which is what I wanted to queue this on
top of.  So my wait is over ;-)

Thanks.
Junio C Hamano Nov. 18, 2019, 2:27 a.m. UTC | #3
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> ... there is so little overlap between the git add --patch part
> and the rest of git add --interactive that I could put the former
> into a totally different file: add-patch.c.

We would want to call, after "add -i in C" stabilizes, directly into
"add -p" machinery from different subcommands such as "reset",
"checkout", etc., and bypass the rest of "add -i" when we do so.  We
can credit the lack of overlap to the design that supports such
usage while it is still in a scripted Porcelain.

Preparing the "add -p" machinery in such a way that "add -i" merely
is one of the users would make a lot of sense from organizational
point of view.

Thanks.
Johannes Schindelin Nov. 18, 2019, 6:53 p.m. UTC | #4
Hi Junio,

On Mon, 18 Nov 2019, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > ... there is so little overlap between the git add --patch part
> > and the rest of git add --interactive that I could put the former
> > into a totally different file: add-patch.c.
>
> We would want to call, after "add -i in C" stabilizes, directly into
> "add -p" machinery from different subcommands such as "reset",
> "checkout", etc., and bypass the rest of "add -i" when we do so.  We
> can credit the lack of overlap to the design that supports such
> usage while it is still in a scripted Porcelain.
>
> Preparing the "add -p" machinery in such a way that "add -i" merely
> is one of the users would make a lot of sense from organizational
> point of view.

If I understand you correctly, you mean that e.g. `git checkout -p` will
call the code from `add-patch.c` directly? That is indeed the case.
Already now, `git checkout -p` calls `run_add_interactive()` (see
https://github.com/git/git/blob/v2.24.0/builtin/checkout.c#L463):

	if (opts->patch_mode) {
		const char *patch_mode;


		if (opts->checkout_index && opts->checkout_worktree)
			patch_mode = "--patch=checkout";
		else if (opts->checkout_index && !opts->checkout_worktree)
			patch_mode = "--patch=reset";
		else if (!opts->checkout_index && opts->checkout_worktree)
			patch_mode = "--patch=worktree";
		else
			BUG("either flag must have been set, worktree=%d, index=%d",
			    opts->checkout_worktree, opts->checkout_index);
		return run_add_interactive(revision, patch_mode, &opts->pathspec);
	}

And with the changes in PR #174 (i.e. three patch series later, see
https://github.com/gitgitgadget/git/pull/174/files#diff-1f1eb09e4703764f9f9b9f1f1e67eb97R205-R218
for details), this will call `run_add_p()`, i.e. the newly-added code in
`add-patch.c` directly:

		if (!strcmp(patch_mode, "--patch"))
			mode = ADD_P_STAGE;
		else if (!strcmp(patch_mode, "--patch=stash"))
			mode = ADD_P_STASH;
		else if (!strcmp(patch_mode, "--patch=reset"))
			mode = ADD_P_RESET;
		else if (!strcmp(patch_mode, "--patch=checkout"))
			mode = ADD_P_CHECKOUT;
		else if (!strcmp(patch_mode, "--patch=worktree"))
			mode = ADD_P_WORKTREE;
		else
			die("'%s' not supported", patch_mode);

		return !!run_add_p(the_repository, mode, revision, pathspec);

Now that I see it, it does not look the most elegant that the
`patch_mode` is a string instead of that enum, but I think that will be
relatively easy to fix once the legacy `git-add--interactive.perl` will
have been decomissioned.

Ciao,
Dscho
Johannes Schindelin Nov. 18, 2019, 7:22 p.m. UTC | #5
Hi Junio,

On Mon, 18 Nov 2019, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
>
> > "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> > writes:
> >
> >> Based on the js/builtin-add-i branch, this patch series implements the rest
> >> of the commands in git add -i's main loop: update, revert, add_untracked,
> >> patch, diff, and quit. Apart from quit, these commands are all very similar
> >> in that they first build a list of files, display it, let the user choose
> >> which ones to act on, and then perform the action.
> >
> > So, this obviously depends on the previous "let's start the main
> > loop" series, in which I recall you found at least one remaining bug
> > after sending the latest round.
> >
> > I'd prefer to queue this on top of the iteration of that series,
> > which would hopefully become the final one, which would let me avoid
> > one rebase of this series ;-)
> >
> > Thanks.
>
> I found the v7 on the list, which is what I wanted to queue this on
> top of.  So my wait is over ;-)

Yes, sorry, I did not think that I was opaque but I was.

So to clarify: I will always rebase the built-in add -i/-p patch series
on top of what you put on gitster/git. That is, this here patch series
will always be rebased on top of js/builtin-add-i, the next patch series
will always be rebased on top of js/builtin-add-i-cmds, etc

Ciao,
Dscho
Junio C Hamano Nov. 19, 2019, 1:29 a.m. UTC | #6
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Preparing the "add -p" machinery in such a way that "add -i" merely
>> is one of the users would make a lot of sense from organizational
>> point of view.
>
> If I understand you correctly, you mean that e.g. `git checkout -p` will
> call the code from `add-patch.c` directly?...

Yup, and it is a good organization that the "add -p" machinery is
held not too intimate with the rest of "add -i" but treats "add -i"
as just one of its users from the beginning, which is what you did
here.

In case it wasn't clear, I am saying that I like the resulting
organization of these 8 patches.