Merge branch 'gr/add-e-use-apply-api' into jch

The application of the edited patch in 'git add -e' has been
refactored to use the internal apply API directly, avoiding the need
to spawn a 'git apply' subprocess.

* gr/add-e-use-apply-api:
  builtin/add.c: replace run_command() with direct apply_all_patches() call
jch
Junio C Hamano 2026-08-31 11:11:59 -07:00
commit d31a43ec7d
2 changed files with 22 additions and 7 deletions

View File

@ -13,7 +13,6 @@
#include "dir.h" #include "dir.h"
#include "gettext.h" #include "gettext.h"
#include "pathspec.h" #include "pathspec.h"
#include "run-command.h"
#include "object-file.h" #include "object-file.h"
#include "odb.h" #include "odb.h"
#include "odb/transaction.h" #include "odb/transaction.h"
@ -23,10 +22,10 @@
#include "diff.h" #include "diff.h"
#include "read-cache.h" #include "read-cache.h"
#include "revision.h" #include "revision.h"
#include "strvec.h"
#include "submodule.h" #include "submodule.h"
#include "add-interactive.h" #include "add-interactive.h"
#include "merge-ll.h" #include "merge-ll.h"
#include "apply.h"


static const char * const builtin_add_usage[] = { static const char * const builtin_add_usage[] = {
N_("git add [<options>] [--] <pathspec>..."), N_("git add [<options>] [--] <pathspec>..."),
@ -189,7 +188,8 @@ static int edit_patch(struct repository *repo,
const char *prefix) const char *prefix)
{ {
char *file = repo_git_path(repo, "ADD_EDIT.patch"); char *file = repo_git_path(repo, "ADD_EDIT.patch");
struct child_process child = CHILD_PROCESS_INIT; struct apply_state state;
const char *apply_argv[2];
struct rev_info rev; struct rev_info rev;
int out; int out;
struct stat st; struct stat st;
@ -219,11 +219,16 @@ static int edit_patch(struct repository *repo,
if (!st.st_size) if (!st.st_size)
die(_("empty patch. aborted")); die(_("empty patch. aborted"));


child.git_cmd = 1; apply_argv[0] = file;
strvec_pushl(&child.args, "apply", "--recount", "--cached", file, apply_argv[1] = NULL;
NULL); if (init_apply_state(&state, repo, NULL))
if (run_command(&child)) die(_("could not initialize apply state"));
state.cached = 1;
if (check_apply_state(&state, 0))
die(_("could not check apply state"));
if (apply_all_patches(&state, 1, apply_argv, APPLY_OPT_RECOUNT))
die(_("could not apply '%s'"), file); die(_("could not apply '%s'"), file);
clear_apply_state(&state);


unlink(file); unlink(file);
free(file); free(file);

View File

@ -124,5 +124,15 @@ test_expect_success 'add -e notices editor failure' '
test_must_fail env GIT_EDITOR=false git add -e && test_must_fail env GIT_EDITOR=false git add -e &&
test_expect_code 1 git diff --exit-code test_expect_code 1 git diff --exit-code
' '
test_expect_success 'add -e works from a subdirectory' '
git reset --hard &&
echo change >>file &&
mkdir -p subdir &&
(
cd subdir &&
GIT_EDITOR=cat git add -e ../file
) &&
git diff --cached | grep -q "^+change"
'


test_done test_done