Skip to content

Commit 50f3221

Browse files
committed
Start to implement a built-in version of git add --interactive
This is hardly the first conversion of a Git command that is implemented as a script to a built-in. So far, the most successful strategy for such conversions has been to add a built-in helper and call that for more and more functionality from the script, as more and more parts are converted. With the interactive add, we choose a different strategy. The sole reason for this is that on Windows (where such a conversion has the most benefits in terms of speed and robustness) we face the very specific problem that a `system()` call in Perl seems to close `stdin` in the parent process when the spawned process consumes even one character from `stdin`. And that just does not work for us here, as it would stop the main loop as soon as any interactive command was performed by the helper. Which is almost all of the commands in `git add -i`. It is almost as if Perl told us once again that it does not want us to use it on Windows. Instead, we follow the opposite route where we start with a bare-bones version of the built-in interactive add, guarded by the new `add.interactive.useBuiltin` config variable, and then add more and more functionality to it, until it is feature complete. At this point, the built-in version of `git add -i` only states that it cannot do anything yet ;-) Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 5b8234a commit 50f3221

File tree

6 files changed

+35
-0
lines changed

6 files changed

+35
-0
lines changed

Documentation/config/add.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@ add.ignore-errors (deprecated)::
55
option of linkgit:git-add[1]. `add.ignore-errors` is deprecated,
66
as it does not follow the usual naming convention for configuration
77
variables.
8+
9+
add.interactive.useBuiltin::
10+
[EXPERIMENTAL] Set to `true` to use the experimental built-in
11+
implementation of the interactive version of linkgit:git-add[1]
12+
instead of the Perl script version. Is `false` by default.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentat
823823
-name '*.h' -print)))
824824

825825
LIB_OBJS += abspath.o
826+
LIB_OBJS += add-interactive.o
826827
LIB_OBJS += advice.o
827828
LIB_OBJS += alias.o
828829
LIB_OBJS += alloc.o

add-interactive.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "cache.h"
2+
#include "add-interactive.h"
3+
4+
int run_add_i(struct repository *r, const struct pathspec *ps)
5+
{
6+
die(_("No commands are available in the built-in `git add -i` yet!"));
7+
}

add-interactive.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef ADD_INTERACTIVE_H
2+
#define ADD_INTERACTIVE_H
3+
4+
struct repository;
5+
struct pathspec;
6+
int run_add_i(struct repository *r, const struct pathspec *ps);
7+
8+
#endif

builtin/add.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "bulk-checkin.h"
2121
#include "argv-array.h"
2222
#include "submodule.h"
23+
#include "add-interactive.h"
2324

2425
static const char * const builtin_add_usage[] = {
2526
N_("git add [<options>] [--] <pathspec>..."),
@@ -185,6 +186,14 @@ int run_add_interactive(const char *revision, const char *patch_mode,
185186
{
186187
int status, i;
187188
struct argv_array argv = ARGV_ARRAY_INIT;
189+
int use_builtin_add_i =
190+
git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
191+
if (use_builtin_add_i < 0)
192+
git_config_get_bool("add.interactive.usebuiltin",
193+
&use_builtin_add_i);
194+
195+
if (use_builtin_add_i == 1 && !patch_mode)
196+
return !!run_add_i(the_repository, pathspec);
188197

189198
argv_array_push(&argv, "add--interactive");
190199
if (patch_mode)
@@ -319,6 +328,7 @@ static int add_config(const char *var, const char *value, void *cb)
319328
ignore_add_errors = git_config_bool(var, value);
320329
return 0;
321330
}
331+
322332
return git_default_config(var, value, cb);
323333
}
324334

t/README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,10 @@ GIT_TEST_STASH_USE_BUILTIN=<boolean>, when false, disables the
397397
built-in version of git-stash. See 'stash.useBuiltin' in
398398
git-config(1).
399399

400+
GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the
401+
built-in version of git add -i. See 'add.interactive.useBuiltin' in
402+
git-config(1).
403+
400404
GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
401405
of the index for the whole test suite by bypassing the default number of
402406
cache entries and thread minimums. Setting this to 1 will make the

0 commit comments

Comments
 (0)