From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeff King Subject: [PATCH 12/16] sha1_file: add for_each iterators for loose and packed objects Date: Fri, 3 Oct 2014 16:32:19 -0400 Message-ID: <20141003203219.GL16293@peff.net> References: <20141003202045.GA15205@peff.net> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Cc: Michael Haggerty To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Fri Oct 03 22:32:26 2014 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Xa9Wc-0002W9-HK for gcvg-git-2@plane.gmane.org; Fri, 03 Oct 2014 22:32:26 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752206AbaJCUcX (ORCPT ); Fri, 3 Oct 2014 16:32:23 -0400 Received: from cloud.peff.net ([50.56.180.127]:54857 "HELO cloud.peff.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751317AbaJCUcV (ORCPT ); Fri, 3 Oct 2014 16:32:21 -0400 Received: (qmail 3212 invoked by uid 102); 3 Oct 2014 20:32:21 -0000 Received: from Unknown (HELO peff.net) (10.0.1.1) by cloud.peff.net (qpsmtpd/0.84) with SMTP; Fri, 03 Oct 2014 15:32:21 -0500 Received: (qmail 15149 invoked by uid 107); 3 Oct 2014 20:32:20 -0000 Received: from sigill.intra.peff.net (HELO sigill.intra.peff.net) (10.0.0.7) by peff.net (qpsmtpd/0.84) with SMTP; Fri, 03 Oct 2014 16:32:20 -0400 Received: by sigill.intra.peff.net (sSMTP sendmail emulation); Fri, 03 Oct 2014 16:32:19 -0400 Content-Disposition: inline In-Reply-To: <20141003202045.GA15205@peff.net> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: We typically iterate over the reachable objects in a repository by starting at the tips and walking the graph. There's no easy way to iterate over all of the objects, including unreachable ones. Let's provide a way of doing so. Signed-off-by: Jeff King --- cache.h | 11 +++++++++++ sha1_file.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/cache.h b/cache.h index 7abe7f6..3826b4b 100644 --- a/cache.h +++ b/cache.h @@ -1270,6 +1270,17 @@ int for_each_loose_file_in_objdir(const char *path, each_loose_subdir_fn subdir_cb, void *data); +/* + * Iterate over loose and packed objects in both the local + * repository and any alternates repositories. + */ +typedef int each_packed_object_fn(const unsigned char *sha1, + struct packed_git *pack, + uint32_t pos, + void *data); +extern int for_each_loose_object(each_loose_object_fn, void *); +extern int for_each_packed_object(each_packed_object_fn, void *); + struct object_info { /* Request */ enum object_type *typep; diff --git a/sha1_file.c b/sha1_file.c index 9fdad47..d017289 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3313,3 +3313,65 @@ int for_each_loose_file_in_objdir(const char *path, strbuf_release(&buf); return r; } + +struct loose_alt_odb_data { + each_loose_object_fn *cb; + void *data; +}; + +static int loose_from_alt_odb(struct alternate_object_database *alt, + void *vdata) +{ + struct loose_alt_odb_data *data = vdata; + return for_each_loose_file_in_objdir(alt->base, + data->cb, NULL, NULL, + data->data); +} + +int for_each_loose_object(each_loose_object_fn cb, void *data) +{ + struct loose_alt_odb_data alt; + int r; + + r = for_each_loose_file_in_objdir(get_object_directory(), + cb, NULL, NULL, data); + if (r) + return r; + + alt.cb = cb; + alt.data = data; + return foreach_alt_odb(loose_from_alt_odb, &alt); +} + +int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data) +{ + uint32_t i; + int r = 0; + + for (i = 0; i < p->num_objects; i++) { + const unsigned char *sha1 = nth_packed_object_sha1(p, i); + + if (!sha1) + return error("unable to get sha1 of object %u in %s", + i, p->pack_name); + + r = cb(sha1, p, i, data); + if (r) + break; + } + return r; +} + +int for_each_packed_object(each_packed_object_fn cb, void *data) +{ + struct packed_git *p; + int r = 0; + + prepare_packed_git(); + for (p = packed_git; p; p = p->next) { + r = for_each_object_in_pack(p, cb, data); + if (r) + break; + } + return 0; +} -- 2.1.1.566.gdb1f904