{"thread":{"id":"26703","subject":"[PATCH] clean cached refs when calling set_git_dir()","startedAt":"2011-03-10T15:19:05Z","lastAt":"2011-03-10T17:14:17Z","messageCount":4,"participants":["Julius Plenz","Nguyen Thai Ngoc Duy","Lars Hjemli"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"163149","messageId":"1299770345-32055-1-git-send-email-plenz@cis.fu-berlin.de","threadId":"26703","inReplyTo":null,"subject":"[PATCH] clean cached refs when calling set_git_dir()","fromName":"Julius Plenz","fromEmail":"plenz@cis.fu-berlin.de","sentAt":"2011-03-10T15:19:05Z","receivedAt":"2011-03-10T15:19:05Z","isPatch":true,"sender":{"key":"plenz@cis.fu-berlin.de","avatar":null},"body":"If you use libgit.a to perform reference resolutions on two or more\nrepositories that contain packed refs, cached_refs will store the packed\nrefs for the first repository to contain a packed-refs file only.\n\nSubsequent calls to get_packed_refs() will return the *cached* list,\neven when you changed to a different repository with set_git_dir().\nThus, references will almost certainly resolve to non-existent commits.\n\nThe patch explicitly invalidates the cached list when calling\nset_git_dir() which calls setup_git_env().\n\nSigned-off-by: Julius Plenz <plenz@cis.fu-berlin.de>\n---\n cache.h       |    1 +\n environment.c |    1 +\n refs.c        |    2 +-\n 3 files changed, 3 insertions(+), 1 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 08a9022..95491fe 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -881,6 +881,7 @@ extern int check_leading_path(const char *name, int len);\n extern int has_dirs_only_path(const char *name, int len, int prefix_len);\n extern void schedule_dir_for_removal(const char *name, int len);\n extern void remove_scheduled_dirs(void);\n+extern void invalidate_cached_refs(void);\n \n extern struct alternate_object_database {\n \tstruct alternate_object_database *next;\ndiff --git a/environment.c b/environment.c\nindex 9564475..3a7e1dc 100644\n--- a/environment.c\n+++ b/environment.c\n@@ -110,6 +110,7 @@ static void setup_git_env(void)\n \t\tgit_graft_file = git_pathdup(\"info/grafts\");\n \tif (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))\n \t\tread_replace_refs = 0;\n+\tinvalidate_cached_refs();\n }\n \n int is_bare_repository(void)\ndiff --git a/refs.c b/refs.c\nindex e3c0511..bbe34fb 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -171,7 +171,7 @@ static void free_ref_list(struct ref_list *list)\n \t}\n }\n \n-static void invalidate_cached_refs(void)\n+void invalidate_cached_refs(void)\n {\n \tstruct cached_refs *ca = &cached_refs;\n \n-- \n1.7.3.1\n"},{"id":"163150","messageId":"AANLkTik1HMQqKc98AF-6DTGJgrk8HOjZTimGnK-XBv-q@mail.gmail.com","threadId":"26703","inReplyTo":"1299770345-32055-1-git-send-email-plenz@cis.fu-berlin.de","subject":"Re: [PATCH] clean cached refs when calling set_git_dir()","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-10T15:59:16Z","receivedAt":"2011-03-10T15:59:16Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Thu, Mar 10, 2011 at 10:19 PM, Julius Plenz <plenz@cis.fu-berlin.de> wrote:\n> If you use libgit.a to perform reference resolutions on two or more\n> repositories that contain packed refs, cached_refs will store the packed\n> refs for the first repository to contain a packed-refs file only.\n\nIf you use libgit.a to do anything on more than one repository, you\nget a lot more messed up that just that. Spawning a new process or\naccessing with libgit2 may be safer. Why do you want to do that in the\nfirst place?\n-- \nDuy\n"},{"id":"163151","messageId":"20110310160948.GL15960@plenz.com","threadId":"26703","inReplyTo":"AANLkTik1HMQqKc98AF-6DTGJgrk8HOjZTimGnK-XBv-q@mail.gmail.com","subject":"Re: [PATCH] clean cached refs when calling set_git_dir()","fromName":"Julius Plenz","fromEmail":"plenz@cis.fu-berlin.de","sentAt":"2011-03-10T16:09:48Z","receivedAt":"2011-03-10T16:09:48Z","isPatch":true,"sender":{"key":"plenz@cis.fu-berlin.de","avatar":null},"body":"Hi!\n\n* Nguyen Thai Ngoc Duy <pclouds@gmail.com> [2011-03-10 17:00]:\n> On Thu, Mar 10, 2011 at 10:19 PM, Julius Plenz <plenz@cis.fu-berlin.de> wrote:\n> > If you use libgit.a to perform reference resolutions on two or more\n> > repositories that contain packed refs, cached_refs will store the packed\n> > refs for the first repository to contain a packed-refs file only.\n> \n> If you use libgit.a to do anything on more than one repository, you\n> get a lot more messed up that just that. Spawning a new process or\n> accessing with libgit2 may be safer. Why do you want to do that in the\n> first place?\n\nI was working on the cgit repository browser, where you have to peek\ninto several repositories to create the overview page. Since cgit\nlinks to libgit.a I fixed the bug there. Not sure if that's the proper\nway to do it, though...\n\nJulius\n"},{"id":"163156","messageId":"AANLkTikrTva2KFxh0O=Ryn1zWZR2rjCSVkGjHQ0w0xL0@mail.gmail.com","threadId":"26703","inReplyTo":"20110310160948.GL15960@plenz.com","subject":"Re: [PATCH] clean cached refs when calling set_git_dir()","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2011-03-10T17:14:17Z","receivedAt":"2011-03-10T17:14:17Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On Thu, Mar 10, 2011 at 17:09, Julius Plenz <plenz@cis.fu-berlin.de> wrote:\n> * Nguyen Thai Ngoc Duy <pclouds@gmail.com> [2011-03-10 17:00]:\n>> On Thu, Mar 10, 2011 at 10:19 PM, Julius Plenz <plenz@cis.fu-berlin.de> wrote:\n>> > If you use libgit.a to perform reference resolutions on two or more\n>> > repositories that contain packed refs, cached_refs will store the packed\n>> > refs for the first repository to contain a packed-refs file only.\n>>\n>> If you use libgit.a to do anything on more than one repository, you\n>> get a lot more messed up that just that. Spawning a new process or\n>> accessing with libgit2 may be safer. Why do you want to do that in the\n>> first place?\n>\n> I was working on the cgit repository browser, where you have to peek\n> into several repositories to create the overview page. Since cgit\n> links to libgit.a I fixed the bug there. Not sure if that's the proper\n> way to do it, though...\n\nI never got around to answer your earlier email about this, but here\nis what I would have said ;)\n\nSince libgit.a doesn't work with multiple repos [1], cgit supports the\nuse of an \"agefile\" (that's the option name in cgitrc) to obtain the\nlast commit-date per repo.\n\nThe content of such an agefile can be generated by a command like the\nfollowing in one (or more) of your git hooks:\n\n  git for-each-ref --sort=-authordate --format='%(authordate:iso8601)' --count=1\n\nHth.\n-- \nlarsh\n\n[1] Even if libgit.a did support working with multiple repos in a\nsingle run, I probably would avoid this particular usage since it is\nbound to perform badly when lots of repos are involved (like on\ncgit.freedesktop.org), and even more so when the list is sorted by\nidle-time. Simply reading a small textfile per repo is much faster.\n"}]}