diff options
author | Junio C Hamano <gitster@pobox.com> | 2013-11-07 16:30:14 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-11-11 09:36:05 -0800 |
commit | 4bc1ad32b176a1f70bd7dd11b522792a4a588a42 (patch) | |
tree | ff9bda5bf066b5283e39df1650e0b8bf1148167a | |
parent | 0ecd94d7d728606e0047a44e60a277ff4e7b3990 (diff) | |
download | git-jc/create-directories-microopt.tar.gz |
checkout: most of the time we have good leading directoriesjc/create-directories-microopt
When "git checkout" wants to create a path, e.g. a/b/c/d/e, after
seeing if the entire thing already exists (in which case we check if
that is up-to-date and do not bother to check it out, or we unlink
and recreate it) and find it missing, we validate that the leading
directory path is without funny symlinks by seeing that a/, a/b/,
a/b/c/ and then a/b/c/d/ are all without funny symlinks, by calling
has_dirs_only_path() in this order.
When we are checking out many files (imagine: initial checkout),
however, it is likely that an earlier checkout would have already
made sure that the leading directory a/b/c/d/ is in good order, and
has_dirs_only_path() caches this information. We can often bypass
calls to has_dirs_only_path() for leading part by first checking the
whole path a/b/c/d/ first (imagine we just checked out a/b/c/d/e0
and are about to check out a/b/c/d/e).
This cuts down the number of calls to has_dirs_only_path() for
checking out Linux kernel sources afresh from 190k down to 98k.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | entry.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -6,9 +6,17 @@ static void create_directories(const char *path, int path_len, const struct checkout *state) { - char *buf = xmalloc(path_len + 1); - int len = 0; + char *buf; + int len; + + for (len = path_len - 1; 0 <= len; len--) + if (path[len] == '/') + break; + if (has_dirs_only_path(path, len, state->base_dir_len)) + return; /* ok, we have the whole leading directory */ + buf = xmalloc(path_len + 1); + len = 0; while (len < path_len) { do { buf[len] = path[len]; |