From: Junio C Hamano <gitster@pobox.com>
To: "Santi Béjar" <santi@agolina.net>
Cc: "Git Mailing List" <git@vger.kernel.org>
Subject: Re* Slow "git rev-list origin/master --not --all" or "git fetch" slow when downloading nothing
Date: Wed, 05 Nov 2008 09:32:51 -0800 [thread overview]
Message-ID: <7vprlakri4.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <adf1fd3d0811050138j7b8bbed1nd94a999f55e38d61@mail.gmail.com> (Santi Béjar's message of "Wed, 5 Nov 2008 10:38:31 +0100")
"Santi Béjar" <santi@agolina.net> writes:
> In cold cache "git rev-list origin/master --not --all" is slow
> reading many files:
>
> cold cache:
> $ /usr/bin/time git rev-list origin/master --not --all
> 0.03user 0.02system 0:04.57elapsed 1%CPU (0avgtext+0avgdata 0maxresident)k
> 77848inputs+0outputs (410major+1798minor)pagefaults 0swaps
>
> hot cache:
> $ /usr/bin/time git rev-list origin/master --not --all
> 0.01user 0.00system 0:00.06elapsed 31%CPU (0avgtext+0avgdata 0maxresident)k
> 0inputs+0outputs (0major+2207minor)pagefaults 0swaps
>
> I think that, in this particular case (when the arguments are the tips
> of some of the branches), this should not read that many files.
What kind of "many files" are you making git read? Do you have too many
unpacked refs? Too many loose objects?
> ... When nothing has changed in the remote repository (so
> refs/<remote>/* has all the remote refs) the "git fetch" could be almost
> instantaneous (even in coldcache),...
You at least need to read:
- what "--all" refs point at; to find this out, you need to read all
unpacked refs files, and one packed-refs file;
- commit objects that these refs point at; to cull refs that do not point
at committish and dereference tag objects that point at commit, you
need to read these objects (either loose objects or in packs);
- commit objects on the ancestry graph starting from the commit pointed
at by origin/master and the commits from "--all" refs, until your
traversal from origin/master hit one of the ancestors of "--all" refs.
I noticed that when you "git pack-refs" (or "git gc"), we do not remove
the leading directories of loose refs that become empty because of
pruning. This can cause many opendir() when you used to have too many
hierachy of refs even after packing them.
dir.c | 13 +++++++++----
pack-refs.c | 5 +++++
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git c/dir.c w/dir.c
index 0131983..7241631 100644
--- c/dir.c
+++ w/dir.c
@@ -779,7 +779,12 @@ int is_inside_dir(const char *dir)
return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
}
-int remove_dir_recursively(struct strbuf *path, int only_empty)
+/*
+ * option:
+ * 1: remove empty directory;
+ * 2: remove empty subdirectories, but not the directory itself
+ */
+int remove_dir_recursively(struct strbuf *path, int option)
{
DIR *dir = opendir(path->buf);
struct dirent *e;
@@ -803,9 +808,9 @@ int remove_dir_recursively(struct strbuf *path, int only_empty)
if (lstat(path->buf, &st))
; /* fall thru */
else if (S_ISDIR(st.st_mode)) {
- if (!remove_dir_recursively(path, only_empty))
+ if (!remove_dir_recursively(path, !!option))
continue; /* happy */
- } else if (!only_empty && !unlink(path->buf))
+ } else if (!option && !unlink(path->buf))
continue; /* happy, too */
/* path too long, stat fails, or non-directory still exists */
@@ -815,7 +820,7 @@ int remove_dir_recursively(struct strbuf *path, int only_empty)
closedir(dir);
strbuf_setlen(path, original_len);
- if (!ret)
+ if (!ret && option != 2)
ret = rmdir(path->buf);
return ret;
}
diff --git c/pack-refs.c w/pack-refs.c
index 2c76fb1..30fbae8 100644
--- c/pack-refs.c
+++ w/pack-refs.c
@@ -2,6 +2,7 @@
#include "refs.h"
#include "tag.h"
#include "pack-refs.h"
+#include "dir.h"
struct ref_to_prune {
struct ref_to_prune *next;
@@ -73,10 +74,14 @@ static void prune_ref(struct ref_to_prune *r)
static void prune_refs(struct ref_to_prune *r)
{
+ struct strbuf refs = STRBUF_INIT;
+
+ strbuf_addstr(&refs, git_path("refs"));
while (r) {
prune_ref(r);
r = r->next;
}
+ remove_dir_recursively(&refs, 2);
}
static struct lock_file packed;
next prev parent reply other threads:[~2008-11-05 17:34 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-05 9:38 Slow "git rev-list origin/master --not --all" or "git fetch" slow when downloading nothing Santi Béjar
2008-11-05 17:32 ` Junio C Hamano [this message]
2008-11-05 17:37 ` Linus Torvalds
2008-11-05 21:37 ` Santi Béjar
2008-11-05 22:08 ` Linus Torvalds
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vprlakri4.fsf@gitster.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=santi@agolina.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox