On 08/08, Paul-Sebastian Ungureanu wrote: > This commit replaces spawning `git ls-files` child process with > API calls to get the untracked files. > --- > builtin/stash--helper.c | 49 +++++++++++++++++++++++++++-------------- > 1 file changed, 32 insertions(+), 17 deletions(-) > > diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c > index 4fd79532c..5c27f5dcf 100644 > --- a/builtin/stash--helper.c > +++ b/builtin/stash--helper.c > @@ -813,27 +813,42 @@ static int store_stash(int argc, const char **argv, const char *prefix) > /* > * `out` will be filled with the names of untracked files. The return value is: > * > - * < 0 if there was a bug (any arg given outside the repo will be detected > - * by `setup_revision()`) > * = 0 if there are not any untracked files > * > 0 if there are untracked files > */ > -static int get_untracked_files(const char **argv, int line_term, > +static int get_untracked_files(const char **argv, const char *prefix, > int include_untracked, struct strbuf *out) > { > - struct child_process cp = CHILD_PROCESS_INIT; > - cp.git_cmd = 1; > - argv_array_pushl(&cp.args, "ls-files", "-o", NULL); > - if (line_term) > - argv_array_push(&cp.args, "-z"); > + int max_len; > + int i; > + char *seen; > + struct dir_struct dir; > + struct pathspec pathspec; > + > + memset(&dir, 0, sizeof(dir)); > if (include_untracked != 2) > - argv_array_push(&cp.args, "--exclude-standard"); > - argv_array_push(&cp.args, "--"); > - if (argv) > - argv_array_pushv(&cp.args, argv); > + setup_standard_excludes(&dir); > > - if (pipe_command(&cp, NULL, 0, out, 0, NULL, 0)) > - return -1; > + parse_pathspec(&pathspec, 0, > + PATHSPEC_PREFER_FULL, > + prefix, argv); > + seen = xcalloc(pathspec.nr, 1); > + > + max_len = fill_directory(&dir, the_repository->index, &pathspec); > + for (i = 0; i < dir.nr; i++) { > + struct dir_entry *ent = dir.entries[i]; > + if (!dir_path_match(ent, &pathspec, max_len, seen)) { > + free(ent); > + continue; > + } > + strbuf_addf(out, "%s\n", ent->name); As mentioned in my comments about the 'diff-index' replacement, this '\n' should probably be '\0', and we should keep the '-z' flag in 'git update-index', in case somebody has a '\n' in their filenames. While creating such a file is probably not a good idea anyway, we should still be able to handle it (and have been before this, so we shouldn't break it). > + free(ent); > + } > + > + free(dir.entries); > + free(dir.ignored); > + clear_directory(&dir); > + free(seen); > return out->len; > } > > @@ -888,7 +903,7 @@ static int check_changes(const char **argv, int include_untracked, > goto done; > } > > - if (include_untracked && get_untracked_files(argv, 0, > + if (include_untracked && get_untracked_files(argv, prefix, > include_untracked, &out)) > ret = 1; > > @@ -908,7 +923,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, > struct child_process cp2 = CHILD_PROCESS_INIT; > > cp.git_cmd = 1; > - argv_array_pushl(&cp.args, "update-index", "-z", "--add", > + argv_array_pushl(&cp.args, "update-index", "--add", > "--remove", "--stdin", NULL); > argv_array_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", > stash_index_path.buf); > @@ -1134,7 +1149,7 @@ static int do_create_stash(int argc, const char **argv, const char *prefix, > goto done; > } > > - if (include_untracked && get_untracked_files(argv, 1, > + if (include_untracked && get_untracked_files(argv, prefix, > include_untracked, &out)) { > if (save_untracked_files(info, &msg, &out)) { > if (!quiet) > -- > 2.18.0.573.g56500d98f >