[GSoC][PATCH v7 24/26] stash: optimize `get_untracked_files()` and `check_changes()`
From: Paul-Sebastian Ungureanu <hidden>
Date: 2018-08-08 18:59:43
Subsystem:
the rest · Maintainer:
Linus Torvalds
This commits introduces a optimization by avoiding calling the same functions again. For example, `git stash push -u` would call at some points the following functions: * `check_changes()` * `do_create_stash()`, which calls: `check_changes()` and `get_untracked_files()` Note that `check_changes()` also calls `get_untracked_files()`. So, `check_changes()` is called 2 times and `get_untracked_files()` 3 times. By checking at the beginning of the function if we already performed a check, we can avoid making useless calls. --- builtin/stash.c | 50 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/builtin/stash.c b/builtin/stash.c
index 0ef88408a..4d5c0d16e 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c@@ -819,13 +819,23 @@ 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: + * `has_untracked_files` is: + * -2 if `get_untracked_files()` hasn't been called + * -1 if there were errors + * 0 if there are no untracked files + * 1 if there are untracked files + * + * `untracked_files` will be filled with the names of untracked files. + * The return value is: * * = 0 if there are not any untracked files * > 0 if there are untracked files */ +static struct strbuf untracked_files = STRBUF_INIT; +static int has_untracked_files = -2; + static int get_untracked_files(const char **argv, const char *prefix, - int include_untracked, struct strbuf *out) + int include_untracked) { int max_len; int i;
@@ -833,6 +843,9 @@ static int get_untracked_files(const char **argv, const char *prefix, struct dir_struct dir; struct pathspec pathspec; + if (has_untracked_files != -2) + return has_untracked_files; + memset(&dir, 0, sizeof(dir)); if (include_untracked != 2) setup_standard_excludes(&dir);
@@ -849,7 +862,7 @@ static int get_untracked_files(const char **argv, const char *prefix, free(ent); continue; } - strbuf_addf(out, "%s\n", ent->name); + strbuf_addf(&untracked_files, "%s\n", ent->name); free(ent); }
@@ -857,16 +870,25 @@ static int get_untracked_files(const char **argv, const char *prefix, free(dir.ignored); clear_directory(&dir); free(seen); - return out->len; + has_untracked_files = untracked_files.len; + return untracked_files.len; } /* + * `changes` is: + * -2 if `check_changes()` hasn't been called + * -1 if there were any errors + * 0 if there are no changes + * 1 if there are changes + * * The return value of `check_changes()` can be: * * < 0 if there was an error * = 0 if there are no changes. * > 0 if there are changes. */ +static int changes = -2; + static int check_changes(const char **argv, int include_untracked, const char *prefix) {
@@ -874,9 +896,11 @@ static int check_changes(const char **argv, int include_untracked, int ret = 0; struct rev_info rev; struct object_id dummy; - struct strbuf out = STRBUF_INIT; struct argv_array args = ARGV_ARRAY_INIT; + if (changes != -2) + return changes; + init_revisions(&rev, prefix); parse_pathspec(&rev.prune_data, 0, PATHSPEC_PREFER_FULL, prefix, argv);
@@ -912,17 +936,16 @@ static int check_changes(const char **argv, int include_untracked, } if (include_untracked && get_untracked_files(argv, prefix, - include_untracked, &out)) + include_untracked)) ret = 1; done: - strbuf_release(&out); + changes = ret; argv_array_clear(&args); return ret; } -static int save_untracked_files(struct stash_info *info, struct strbuf *msg, - struct strbuf *out) +static int save_untracked_files(struct stash_info *info, struct strbuf *msg) { int ret = 0; struct strbuf untracked_msg = STRBUF_INIT;
@@ -937,7 +960,8 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, stash_index_path.buf); strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf); - if (pipe_command(&cp, out->buf, out->len, NULL, 0, NULL, 0)) { + if (pipe_command(&cp, untracked_files.buf, untracked_files.len, + NULL, 0, NULL, 0)) { ret = -1; goto done; }
@@ -1116,7 +1140,6 @@ static int do_create_stash(int argc, const char **argv, const char *prefix, struct commit_list *parents = NULL; struct strbuf msg = STRBUF_INIT; struct strbuf commit_tree_label = STRBUF_INIT; - struct strbuf out = STRBUF_INIT; struct strbuf final_stash_msg = STRBUF_INIT; read_cache_preload(NULL);
@@ -1158,8 +1181,8 @@ static int do_create_stash(int argc, const char **argv, const char *prefix, } if (include_untracked && get_untracked_files(argv, prefix, - include_untracked, &out)) { - if (save_untracked_files(info, &msg, &out)) { + include_untracked)) { + if (save_untracked_files(info, &msg)) { if (!quiet) printf_ln("Cannot save the untracked files"); ret = -1;
@@ -1213,7 +1236,6 @@ static int do_create_stash(int argc, const char **argv, const char *prefix, done: strbuf_release(&commit_tree_label); strbuf_release(&msg); - strbuf_release(&out); strbuf_release(&final_stash_msg); return ret; }
--
2.18.0.573.g56500d98f