On Fri, Sep 29, 2017 at 10:11 PM, Jonathan Tan <jonathantanmy@xxxxxxxxxx> wrote: > diff --git a/sha1_file.c b/sha1_file.c > index b4a67bb83..77aa0ffdf 100644 > --- a/sha1_file.c > +++ b/sha1_file.c > @@ -29,6 +29,7 @@ > #include "mergesort.h" > #include "quote.h" > #include "packfile.h" > +#include "fetch-object.h" > > const unsigned char null_sha1[GIT_MAX_RAWSZ]; > const struct object_id null_oid; > @@ -1149,6 +1150,8 @@ static int sha1_loose_object_info(const unsigned char *sha1, > return (status < 0) ? status : 0; > } > > +int fetch_if_missing = 1; > + > int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags) > { > static struct object_info blank_oi = OBJECT_INFO_INIT; > @@ -1157,6 +1160,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, > const unsigned char *real = (flags & OBJECT_INFO_LOOKUP_REPLACE) ? > lookup_replace_object(sha1) : > sha1; > + int already_retried = 0; > > if (!oi) > oi = &blank_oi; > @@ -1181,28 +1185,36 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, > } > } > > - if (!find_pack_entry(real, &e)) { > - /* Most likely it's a loose object. */ > - if (!sha1_loose_object_info(real, oi, flags)) > - return 0; > +retry: > + if (find_pack_entry(real, &e)) > + goto found_packed; > > - /* Not a loose object; someone else may have just packed it. */ > - if (flags & OBJECT_INFO_QUICK) { > - return -1; > - } else { > - reprepare_packed_git(); > - if (!find_pack_entry(real, &e)) > - return -1; > - } > + /* Most likely it's a loose object. */ > + if (!sha1_loose_object_info(real, oi, flags)) > + return 0; > + > + /* Not a loose object; someone else may have just packed it. */ > + reprepare_packed_git(); > + if (find_pack_entry(real, &e)) > + goto found_packed; > + > + /* Check if it is a missing object */ > + if (fetch_if_missing && repository_format_partial_clone && > + !already_retried) { > + fetch_object(repository_format_partial_clone, real); > + already_retried = 1; > + goto retry; > } > > + return -1; > + > +found_packed: > if (oi == &blank_oi) > /* > * We know that the caller doesn't actually need the > * information below, so return early. > */ > return 0; > - > rtype = packed_object_info(e.p, e.offset, oi); > if (rtype < 0) { > mark_bad_packed_object(e.p, real); Instead of adding labels and gotos, I would suggest adding a new function like the following does on top of your changes: diff --git a/sha1_file.c b/sha1_file.c index cc1aa0bd7f..02a6ed1e9b 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1171,18 +1171,40 @@ static int sha1_loose_object_info(const unsigned char *sha1, return (status < 0) ? status : 0; } +int try_find_packed_entry_or_loose_object(const unsigned char *real, struct object_info *oi, + unsigned flags, struct pack_entry *e, int retry) +{ + if (find_pack_entry(real, e)) + return 1; + + /* Most likely it's a loose object. */ + if (!sha1_loose_object_info(real, oi, flags)) + return 0; + + /* Not a loose object; someone else may have just packed it. */ + reprepare_packed_git(); + if (find_pack_entry(real, e)) + return 1; + + /* Check if it is a missing object */ + if (fetch_if_missing && repository_format_partial_clone && retry) { + fetch_object(repository_format_partial_clone, real); + return try_find_packed_entry_or_loose_object(real, oi, flags, e, 0); + } + + return -1; +} + int fetch_if_missing = 1; int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags) { static struct object_info blank_oi = OBJECT_INFO_INIT; struct pack_entry e; - int rtype; + int rtype, res; const unsigned char *real = (flags & OBJECT_INFO_LOOKUP_REPLACE) ? lookup_replace_object(sha1) : sha1; - int already_retried = 0; - if (!oi) oi = &blank_oi; @@ -1206,30 +1228,10 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, } } -retry: - if (find_pack_entry(real, &e)) - goto found_packed; - - /* Most likely it's a loose object. */ - if (!sha1_loose_object_info(real, oi, flags)) - return 0; - - /* Not a loose object; someone else may have just packed it. */ - reprepare_packed_git(); - if (find_pack_entry(real, &e)) - goto found_packed; - - /* Check if it is a missing object */ - if (fetch_if_missing && repository_format_partial_clone && - !already_retried) { - fetch_object(repository_format_partial_clone, real); - already_retried = 1; - goto retry; - } - - return -1; + res = try_find_packed_entry_or_loose_object(real, oi, flags, &e, 1); + if (res < 1) + return res; -found_packed: if (oi == &blank_oi) /* * We know that the caller doesn't actually need the