All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/39] per-repository object store, part 1
@ 2017-08-30  6:46 Jonathan Nieder
  2017-08-30  6:48 ` [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer Jonathan Nieder
                   ` (39 more replies)
  0 siblings, 40 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:46 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Hi,

Most of the credit for this series should go to Stefan Beller.  I just
decided to pull the trigger on sending out what we have so far.

This series is about API.  It makes no functional change yet.

Today, when a git command wants to operate on some objects from another
repository (e.g., a submodule), it has two choices:

 A. Use run_command to operate on that repository in a separate process.

 B. Use add_to_alternates_memory to pretend the repository is an
    alternate.  This has a number of downsides.  Aside from aesthetics,
    one particularly painful consequence is that as alternates
    accumulate, the number of packs git has to check for objects
    increases, which can cause significant slowdowns.

Brandon Williams's recent work to introduce "struct repository" points
to a better way.  Encapsulating object access in struct repository
would mean:

  i. The API for accessing objects in another repository becomes more
     simple and familiar (instead of using the CLI or abusing alternates).

  ii. Operations on one repository do not interfere with another,
      neither in semantics (e.g. replace objects do not work correctly
      with the approach (B) above) nor performance (already described
      above).

 iii. Resources associated with access to a repository could be freed
      when done with that repo.

  iv. Thread-safe multiple readers to a single repository also become
      straightforward, by using multiple repository objects for the same
      repo.

This series is a small step in that direction.

At the end of this series, sha1_loose_object_info takes a repository
argument and can be independently called for multiple repositories.
Not incredibly useful on its own, but a future series will do the same
for sha1_object_info, which will be enough to migrate a caller in
submodule.c (which uses the object store for commit existence checks).

This series has a few phases:

 1. Patch 1 is a cleanup that made some of the later patches easier.

 2. Patches 2-6 create a struct object_store field inside struct
    repository and move some globals to it.

 3. Patches 7-24 are mechanical changes that update some functions to
    accept a repository argument. The only goal is to make the later
    patches that teach these functions to actual handle a repository
    other than the_repository easier to review.  The patches enforce
    at compile time that no caller passes a repository other than
    the_repository --- see patch 7 in particular for details on how
    that works.

 4. Patches 25-39 update the implementations of those functions to
    handle a repository other than the_repository.  This means the
    safety check introduced in phase 3 goes away completely --- all
    functions that gained a repository argument are safe to use with
    a repository argument other than the_repository.

Patches 2-6 and 25-39 should be the most interesting to review.  I'd
particularly appreciate if people can look over 25-39 carefully.  We
were careful not to leave any calls to functions that assume they are
operating on the_repository, but a triple-check is always welcome.

Thanks as well to brian m. carlson, who showed us how such a long and
potentially tedius series can be made bearable for reviewers.

Thoughts of all kinds welcome, as always.

Thanks,
Jonathan Nieder (24):
  pack: make packed_git_mru global a value instead of a pointer
  object-store: move packed_git and packed_git_mru to object store
    struct
  pack: move prepare_packed_git_run_once to object store struct
  pack: move approximate object count to object store struct
  pack: add repository argument to install_packed_git
  pack: add repository argument to prepare_packed_git_one
  pack: add repository argument to rearrange_packed_git
  pack: add repository argument to prepare_packed_git_mru
  pack: add repository argument to prepare_packed_git
  pack: add repository argument to reprepare_packed_git
  pack: add repository argument to sha1_file_name
  pack: add repository argument to map_sha1_file
  pack: allow install_packed_git to handle arbitrary repositories
  pack: allow rearrange_packed_git to handle arbitrary repositories
  pack: allow prepare_packed_git_mru to handle arbitrary repositories
  pack: allow prepare_packed_git_one to handle arbitrary repositories
  pack: allow prepare_packed_git to handle arbitrary repositories
  pack: allow reprepare_packed_git to handle arbitrary repositories
  pack: allow sha1_file_name to handle arbitrary repositories
  pack: allow stat_sha1_file to handle arbitrary repositories
  pack: allow open_sha1_file to handle arbitrary repositories
  pack: allow map_sha1_file_1 to handle arbitrary repositories
  pack: allow map_sha1_file to handle arbitrary repositories
  pack: allow sha1_loose_object_info to handle arbitrary repositories

Stefan Beller (15):
  repository: introduce object store field
  object-store: move alt_odb_list and alt_odb_tail to object store
    struct
  sha1_file: add repository argument to alt_odb_usable
  sha1_file: add repository argument to link_alt_odb_entry
  sha1_file: add repository argument to read_info_alternates
  sha1_file: add repository argument to link_alt_odb_entries
  sha1_file: add repository argument to stat_sha1_file
  sha1_file: add repository argument to open_sha1_file
  sha1_file: add repository argument to map_sha1_file_1
  sha1_file: add repository argument to sha1_loose_object_info
  object-store: add repository argument to prepare_alt_odb
  object-store: add repository argument to foreach_alt_odb
  sha1_file: allow alt_odb_usable to handle arbitrary repositories
  object-store: allow prepare_alt_odb to handle arbitrary repositories
  object-store: allow foreach_alt_odb to handle arbitrary repositories

 builtin/count-objects.c             |  10 ++-
 builtin/fsck.c                      |  15 ++--
 builtin/gc.c                        |   8 +-
 builtin/index-pack.c                |   1 +
 builtin/pack-objects.c              |  23 +++--
 builtin/pack-redundant.c            |   8 +-
 builtin/receive-pack.c              |   4 +-
 builtin/submodule--helper.c         |   4 +-
 bulk-checkin.c                      |   3 +-
 cache.h                             |  50 ++---------
 contrib/coccinelle/packed_git.cocci |  15 ++++
 fast-import.c                       |  10 ++-
 fetch-pack.c                        |   3 +-
 http-backend.c                      |   8 +-
 http-push.c                         |   1 +
 http-walker.c                       |   4 +-
 http.c                              |   9 +-
 mru.h                               |   1 +
 object-store.h                      |  71 ++++++++++++++++
 pack-bitmap.c                       |   6 +-
 pack-check.c                        |   1 +
 pack-revindex.c                     |   1 +
 packfile.c                          |  94 ++++++++++----------
 packfile.h                          |   6 +-
 reachable.c                         |   1 +
 repository.c                        |   4 +-
 repository.h                        |   7 ++
 server-info.c                       |   8 +-
 sha1_file.c                         | 165 ++++++++++++++++++++----------------
 sha1_name.c                         |  11 ++-
 streaming.c                         |   5 +-
 transport.c                         |   4 +-
 32 files changed, 344 insertions(+), 217 deletions(-)
 create mode 100644 contrib/coccinelle/packed_git.cocci
 create mode 100644 object-store.h

-- 
2.14.1.581.gf28d330327


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
@ 2017-08-30  6:48 ` Jonathan Nieder
  2017-08-30 19:44   ` Jeff King
  2017-08-30  6:52 ` [PATCH 02/39] repository: introduce object store field Jonathan Nieder
                   ` (38 subsequent siblings)
  39 siblings, 1 reply; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:48 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson, Jeff King

The MRU cache that keeps track of recently used packs is represented
using two global variables:

	struct mru packed_git_mru_storage;
	struct mru *packed_git_mru = &packed_git_mru_storage;

Callers never assign to the packed_git_mru pointer, though, so we can
simplify by eliminating it and using &packed_git_mru_storage (renamed
to &packed_git_mru) directly.  This variable is only used by the
packfile subsystem, making this a relatively uninvasive change (and
any new unadapted callers would trigger a compile error).

Noticed while moving these globals to the object_store struct.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/pack-objects.c |  4 ++--
 cache.h                |  4 ++--
 packfile.c             | 12 +++++-------
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 82ad6e0c81..ad53d4fa72 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1012,7 +1012,7 @@ static int want_object_in_pack(const unsigned char *sha1,
 			return want;
 	}
 
-	for (entry = packed_git_mru->head; entry; entry = entry->next) {
+	for (entry = packed_git_mru.head; entry; entry = entry->next) {
 		struct packed_git *p = entry->item;
 		off_t offset;
 
@@ -1030,7 +1030,7 @@ static int want_object_in_pack(const unsigned char *sha1,
 			}
 			want = want_found_object(exclude, p);
 			if (!exclude && want > 0)
-				mru_mark(packed_git_mru, entry);
+				mru_mark(&packed_git_mru, entry);
 			if (want != -1)
 				return want;
 		}
diff --git a/cache.h b/cache.h
index a916bc79e3..49b083ee0a 100644
--- a/cache.h
+++ b/cache.h
@@ -4,6 +4,7 @@
 #include "git-compat-util.h"
 #include "strbuf.h"
 #include "hashmap.h"
+#include "mru.h"
 #include "advice.h"
 #include "gettext.h"
 #include "convert.h"
@@ -1589,8 +1590,7 @@ extern struct packed_git {
  * A most-recently-used ordered version of the packed_git list, which can
  * be iterated instead of packed_git (and marked via mru_mark).
  */
-struct mru;
-extern struct mru *packed_git_mru;
+extern struct mru packed_git_mru;
 
 struct pack_entry {
 	off_t offset;
diff --git a/packfile.c b/packfile.c
index f86fa051c9..f69a5c8d60 100644
--- a/packfile.c
+++ b/packfile.c
@@ -40,9 +40,7 @@ static unsigned int pack_max_fds;
 static size_t peak_pack_mapped;
 static size_t pack_mapped;
 struct packed_git *packed_git;
-
-static struct mru packed_git_mru_storage;
-struct mru *packed_git_mru = &packed_git_mru_storage;
+struct mru packed_git_mru;
 
 #define SZ_FMT PRIuMAX
 static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -861,9 +859,9 @@ static void prepare_packed_git_mru(void)
 {
 	struct packed_git *p;
 
-	mru_clear(packed_git_mru);
+	mru_clear(&packed_git_mru);
 	for (p = packed_git; p; p = p->next)
-		mru_append(packed_git_mru, p);
+		mru_append(&packed_git_mru, p);
 }
 
 static int prepare_packed_git_run_once = 0;
@@ -1832,9 +1830,9 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 	if (!packed_git)
 		return 0;
 
-	for (p = packed_git_mru->head; p; p = p->next) {
+	for (p = packed_git_mru.head; p; p = p->next) {
 		if (fill_pack_entry(sha1, e, p->item)) {
-			mru_mark(packed_git_mru, p);
+			mru_mark(&packed_git_mru, p);
 			return 1;
 		}
 	}
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 02/39] repository: introduce object store field
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
  2017-08-30  6:48 ` [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer Jonathan Nieder
@ 2017-08-30  6:52 ` Jonathan Nieder
  2017-08-30  6:53 ` [PATCH 03/39] object-store: move alt_odb_list and alt_odb_tail to object store Jonathan Nieder
                   ` (37 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:52 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

The object store field will contain any objects needed for access to
objects in a given repository.

This patch introduces the object store but for now it is empty.  C99
forbids empty structs, but common C compilers cope well with them and
this struct will gain members very soon (starting with the next
patch).

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Are there any straightforward ways to avoid the empty struct?  Should
the struct have a placeholder member to avoid language issues with an
object that would have size 0?

 object-store.h | 8 ++++++++
 repository.c   | 4 +++-
 repository.h   | 7 +++++++
 3 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 object-store.h

diff --git a/object-store.h b/object-store.h
new file mode 100644
index 0000000000..05722cdde0
--- /dev/null
+++ b/object-store.h
@@ -0,0 +1,8 @@
+#ifndef OBJECT_STORE_H
+#define OBJECT_STORE_H
+
+struct object_store {
+};
+#define OBJECT_STORE_INIT {}
+
+#endif /* OBJECT_STORE_H */
diff --git a/repository.c b/repository.c
index f107af7d76..566753ed4b 100644
--- a/repository.c
+++ b/repository.c
@@ -1,11 +1,13 @@
 #include "cache.h"
 #include "repository.h"
+#include "object-store.h"
 #include "config.h"
 #include "submodule-config.h"
 
 /* The main repository */
 static struct repository the_repo = {
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &the_index, 0, 0
+	NULL, NULL, NULL, OBJECT_STORE_INIT,
+	NULL, NULL, NULL, NULL, NULL, NULL, &the_index, 0, 0
 };
 struct repository *the_repository = &the_repo;
 
diff --git a/repository.h b/repository.h
index 7f5e24a0a2..9633ad10f5 100644
--- a/repository.h
+++ b/repository.h
@@ -1,6 +1,8 @@
 #ifndef REPOSITORY_H
 #define REPOSITORY_H
 
+#include "object-store.h"
+
 struct config_set;
 struct index_state;
 struct submodule_cache;
@@ -25,6 +27,11 @@ struct repository {
 	 */
 	char *objectdir;
 
+	/*
+	 * Holds any information related to the object store.
+	 */
+	struct object_store objects;
+
 	/*
 	 * Path to the repository's graft file.
 	 * Cannot be NULL after initialization.
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 03/39] object-store: move alt_odb_list and alt_odb_tail to object store
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
  2017-08-30  6:48 ` [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer Jonathan Nieder
  2017-08-30  6:52 ` [PATCH 02/39] repository: introduce object store field Jonathan Nieder
@ 2017-08-30  6:53 ` Jonathan Nieder
  2017-08-30  6:54 ` [PATCH 04/39] object-store: move packed_git and packed_git_mru " Jonathan Nieder
                   ` (36 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:53 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

In a process with multiple repositories open, alternates should be
associated to a single repository and not shared globally. Move
alt_odb_list and alt_odb_tail into the_repository and adjust callers
to reflect this.

No functional change intended.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/fsck.c |  4 +++-
 cache.h        |  4 ++--
 object-store.h |  6 +++++-
 packfile.c     |  3 ++-
 sha1_file.c    | 25 ++++++++++++-------------
 sha1_name.c    |  3 ++-
 6 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 1e4c471b41..188e32acd6 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "commit.h"
 #include "tree.h"
@@ -699,7 +700,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 		fsck_object_dir(get_object_directory());
 
 		prepare_alt_odb();
-		for (alt = alt_odb_list; alt; alt = alt->next)
+		for (alt = the_repository->objects.alt_odb_list;
+				alt; alt = alt->next)
 			fsck_object_dir(alt->path);
 
 		if (check_full) {
diff --git a/cache.h b/cache.h
index 49b083ee0a..8d0d34f78b 100644
--- a/cache.h
+++ b/cache.h
@@ -1504,7 +1504,7 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len);
 extern void schedule_dir_for_removal(const char *name, int len);
 extern void remove_scheduled_dirs(void);
 
-extern struct alternate_object_database {
+struct alternate_object_database {
 	struct alternate_object_database *next;
 
 	/* see alt_scratch_buf() */
@@ -1522,7 +1522,7 @@ extern struct alternate_object_database {
 	struct oid_array loose_objects_cache;
 
 	char path[FLEX_ARRAY];
-} *alt_odb_list;
+};
 extern void prepare_alt_odb(void);
 extern char *compute_alternate_path(const char *path, struct strbuf *err);
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
diff --git a/object-store.h b/object-store.h
index 05722cdde0..ace3efbfab 100644
--- a/object-store.h
+++ b/object-store.h
@@ -1,8 +1,12 @@
 #ifndef OBJECT_STORE_H
 #define OBJECT_STORE_H
 
+#include "cache.h"
+
 struct object_store {
+	struct alternate_object_database *alt_odb_list;
+	struct alternate_object_database **alt_odb_tail;
 };
-#define OBJECT_STORE_INIT {}
+#define OBJECT_STORE_INIT { NULL, NULL }
 
 #endif /* OBJECT_STORE_H */
diff --git a/packfile.c b/packfile.c
index f69a5c8d60..5040c9f137 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "mru.h"
 #include "pack.h"
+#include "repository.h"
 #include "dir.h"
 #include "mergesort.h"
 #include "packfile.h"
@@ -873,7 +874,7 @@ void prepare_packed_git(void)
 		return;
 	prepare_packed_git_one(get_object_directory(), 1);
 	prepare_alt_odb();
-	for (alt = alt_odb_list; alt; alt = alt->next)
+	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
 		prepare_packed_git_one(alt->path, 0);
 	rearrange_packed_git();
 	prepare_packed_git_mru();
diff --git a/sha1_file.c b/sha1_file.c
index f56bb5cae7..7c6ffd205a 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -22,6 +22,7 @@
 #include "pack-revindex.h"
 #include "sha1-lookup.h"
 #include "bulk-checkin.h"
+#include "repository.h"
 #include "streaming.h"
 #include "dir.h"
 #include "mru.h"
@@ -276,9 +277,6 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
 	return buf->buf;
 }
 
-struct alternate_object_database *alt_odb_list;
-static struct alternate_object_database **alt_odb_tail;
-
 /*
  * Return non-zero iff the path is usable as an alternate object database.
  */
@@ -298,7 +296,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
 	 * Prevent the common mistake of listing the same
 	 * thing twice, or object directory itself.
 	 */
-	for (alt = alt_odb_list; alt; alt = alt->next) {
+	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		if (!fspathcmp(path->buf, alt->path))
 			return 0;
 	}
@@ -358,8 +356,8 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
 	ent = alloc_alt_odb(pathbuf.buf);
 
 	/* add the alternate entry */
-	*alt_odb_tail = ent;
-	alt_odb_tail = &(ent->next);
+	*the_repository->objects.alt_odb_tail = ent;
+	the_repository->objects.alt_odb_tail = &(ent->next);
 	ent->next = NULL;
 
 	/* recursively add alternates */
@@ -502,7 +500,7 @@ void add_to_alternates_file(const char *reference)
 		fprintf_or_die(out, "%s\n", reference);
 		if (commit_lock_file(lock))
 			die_errno("unable to move new alternates file into place");
-		if (alt_odb_tail)
+		if (the_repository->objects.alt_odb_tail)
 			link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
 	}
 	free(alts);
@@ -600,7 +598,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
 	int r = 0;
 
 	prepare_alt_odb();
-	for (ent = alt_odb_list; ent; ent = ent->next) {
+	for (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {
 		r = fn(ent, cb);
 		if (r)
 			break;
@@ -612,13 +610,14 @@ void prepare_alt_odb(void)
 {
 	const char *alt;
 
-	if (alt_odb_tail)
+	if (the_repository->objects.alt_odb_tail)
 		return;
 
 	alt = getenv(ALTERNATE_DB_ENVIRONMENT);
 	if (!alt) alt = "";
 
-	alt_odb_tail = &alt_odb_list;
+	the_repository->objects.alt_odb_tail =
+			&the_repository->objects.alt_odb_list;
 	link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
 
 	read_info_alternates(get_object_directory(), 0);
@@ -657,7 +656,7 @@ static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
 {
 	struct alternate_object_database *alt;
 	prepare_alt_odb();
-	for (alt = alt_odb_list; alt; alt = alt->next) {
+	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		const char *path = alt_sha1_path(alt, sha1);
 		if (check_and_freshen_file(path, freshen))
 			return 1;
@@ -813,7 +812,7 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
 
 	prepare_alt_odb();
 	errno = ENOENT;
-	for (alt = alt_odb_list; alt; alt = alt->next) {
+	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
 		if (!lstat(*path, st))
 			return 0;
@@ -839,7 +838,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
 	most_interesting_errno = errno;
 
 	prepare_alt_odb();
-	for (alt = alt_odb_list; alt; alt = alt->next) {
+	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
 		fd = git_open(*path);
 		if (fd >= 0)
diff --git a/sha1_name.c b/sha1_name.c
index 134ac9742f..5b8ce1c42c 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -10,6 +10,7 @@
 #include "dir.h"
 #include "sha1-array.h"
 #include "packfile.h"
+#include "repository.h"
 
 static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
 
@@ -104,7 +105,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
 		 */
 		fakeent = alloc_alt_odb(get_object_directory());
 	}
-	fakeent->next = alt_odb_list;
+	fakeent->next = the_repository->objects.alt_odb_list;
 
 	for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
 		int pos;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 04/39] object-store: move packed_git and packed_git_mru to object store
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (2 preceding siblings ...)
  2017-08-30  6:53 ` [PATCH 03/39] object-store: move alt_odb_list and alt_odb_tail to object store Jonathan Nieder
@ 2017-08-30  6:54 ` Jonathan Nieder
  2017-08-30  6:54 ` [PATCH 05/39] pack: move prepare_packed_git_run_once " Jonathan Nieder
                   ` (35 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

In a process with multiple repositories open, packfile accessors
should be associated to a single repository and not shared globally.
Move packed_git and packed_git_mru into the_repository and adjust
callers to reflect this.

Patch generated by

 1. Moving the struct packed_git declaration to object-store.h
    and packed_git, packed_git_mru globals to struct object_store.

 2. Applying the semantic patch contrib/coccinelle/packed_git.cocci
    to adjust callers.

 3. Applying line wrapping fixes from "make style" to break the
    resulting long lines.

 4. Adding missing #includes of repository.h and object-store.h
    where needed.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/count-objects.c             |  6 ++++--
 builtin/fsck.c                      |  7 +++++--
 builtin/gc.c                        |  4 +++-
 builtin/index-pack.c                |  1 +
 builtin/pack-objects.c              | 21 ++++++++++++--------
 builtin/pack-redundant.c            |  6 ++++--
 builtin/receive-pack.c              |  1 +
 cache.h                             | 28 --------------------------
 contrib/coccinelle/packed_git.cocci |  7 +++++++
 fast-import.c                       |  6 ++++--
 http-backend.c                      |  6 ++++--
 http-push.c                         |  1 +
 http-walker.c                       |  1 +
 http.c                              |  1 +
 mru.h                               |  1 +
 object-store.h                      | 33 ++++++++++++++++++++++++++++++-
 pack-bitmap.c                       |  4 +++-
 pack-check.c                        |  1 +
 pack-revindex.c                     |  1 +
 packfile.c                          | 39 +++++++++++++++++++------------------
 reachable.c                         |  1 +
 server-info.c                       |  6 ++++--
 sha1_name.c                         |  3 ++-
 23 files changed, 114 insertions(+), 71 deletions(-)
 create mode 100644 contrib/coccinelle/packed_git.cocci

diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 33343818c8..9334648dcc 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -7,6 +7,8 @@
 #include "cache.h"
 #include "config.h"
 #include "dir.h"
+#include "repository.h"
+#include "object-store.h"
 #include "builtin.h"
 #include "parse-options.h"
 #include "quote.h"
@@ -120,9 +122,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
 		struct strbuf loose_buf = STRBUF_INIT;
 		struct strbuf pack_buf = STRBUF_INIT;
 		struct strbuf garbage_buf = STRBUF_INIT;
-		if (!packed_git)
+		if (!the_repository->objects.packed_git)
 			prepare_packed_git();
-		for (p = packed_git; p; p = p->next) {
+		for (p = the_repository->objects.packed_git; p; p = p->next) {
 			if (!p->pack_local)
 				continue;
 			if (open_pack_index(p))
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 188e32acd6..20bbcdcf4a 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -2,6 +2,7 @@
 #include "cache.h"
 #include "repository.h"
 #include "config.h"
+#include "object-store.h"
 #include "commit.h"
 #include "tree.h"
 #include "blob.h"
@@ -712,7 +713,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 			prepare_packed_git();
 
 			if (show_progress) {
-				for (p = packed_git; p; p = p->next) {
+				for (p = the_repository->objects.packed_git; p;
+				     p = p->next) {
 					if (open_pack_index(p))
 						continue;
 					total += p->num_objects;
@@ -720,7 +722,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 
 				progress = start_progress(_("Checking objects"), total);
 			}
-			for (p = packed_git; p; p = p->next) {
+			for (p = the_repository->objects.packed_git; p;
+			     p = p->next) {
 				/* verify gives error messages itself */
 				if (verify_pack(p, fsck_obj_buffer,
 						progress, count))
diff --git a/builtin/gc.c b/builtin/gc.c
index 3c78fcb9b1..73f727332c 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -11,6 +11,7 @@
  */
 
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "tempfile.h"
 #include "lockfile.h"
@@ -18,6 +19,7 @@
 #include "run-command.h"
 #include "sigchain.h"
 #include "argv-array.h"
+#include "object-store.h"
 #include "commit.h"
 #include "packfile.h"
 
@@ -173,7 +175,7 @@ static int too_many_packs(void)
 		return 0;
 
 	prepare_packed_git();
-	for (cnt = 0, p = packed_git; p; p = p->next) {
+	for (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {
 		if (!p->pack_local)
 			continue;
 		if (p->pack_keep)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index f2be145e12..82f98b56ed 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -12,6 +12,7 @@
 #include "exec_cmd.h"
 #include "streaming.h"
 #include "thread-utils.h"
+#include "object-store.h"
 #include "packfile.h"
 
 static const char index_pack_usage[] =
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index ad53d4fa72..b135fb3fb9 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1,6 +1,8 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
+#include "object-store.h"
 #include "attr.h"
 #include "object.h"
 #include "blob.h"
@@ -1012,7 +1014,8 @@ static int want_object_in_pack(const unsigned char *sha1,
 			return want;
 	}
 
-	for (entry = packed_git_mru.head; entry; entry = entry->next) {
+	for (entry = the_repository->objects.packed_git_mru.head; entry;
+	     entry = entry->next) {
 		struct packed_git *p = entry->item;
 		off_t offset;
 
@@ -1030,7 +1033,8 @@ static int want_object_in_pack(const unsigned char *sha1,
 			}
 			want = want_found_object(exclude, p);
 			if (!exclude && want > 0)
-				mru_mark(&packed_git_mru, entry);
+				mru_mark(&the_repository->objects.packed_git_mru,
+					 entry);
 			if (want != -1)
 				return want;
 		}
@@ -2594,7 +2598,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 
 	memset(&in_pack, 0, sizeof(in_pack));
 
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		const unsigned char *sha1;
 		struct object *o;
 
@@ -2657,7 +2661,8 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
 	static struct packed_git *last_found = (void *)1;
 	struct packed_git *p;
 
-	p = (last_found != (void *)1) ? last_found : packed_git;
+	p = (last_found != (void *)1) ? last_found :
+					the_repository->objects.packed_git;
 
 	while (p) {
 		if ((!p->pack_local || p->pack_keep) &&
@@ -2666,7 +2671,7 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
 			return 1;
 		}
 		if (p == last_found)
-			p = packed_git;
+			p = the_repository->objects.packed_git;
 		else
 			p = p->next;
 		if (p == last_found)
@@ -2702,7 +2707,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
 	uint32_t i;
 	struct object_id oid;
 
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (!p->pack_local || p->pack_keep)
 			continue;
 
@@ -3050,7 +3055,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 	prepare_packed_git();
 	if (ignore_packed_keep) {
 		struct packed_git *p;
-		for (p = packed_git; p; p = p->next)
+		for (p = the_repository->objects.packed_git; p; p = p->next)
 			if (p->pack_local && p->pack_keep)
 				break;
 		if (!p) /* no keep-able packs found */
@@ -3063,7 +3068,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 		 * also covers non-local objects
 		 */
 		struct packed_git *p;
-		for (p = packed_git; p; p = p->next) {
+		for (p = the_repository->objects.packed_git; p; p = p->next) {
 			if (!p->pack_local) {
 				have_non_local_packs = 1;
 				break;
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index aaa8136322..55462bc826 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -7,6 +7,8 @@
 */
 
 #include "builtin.h"
+#include "repository.h"
+#include "object-store.h"
 #include "packfile.h"
 
 #define BLKSIZE 512
@@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p)
 
 static struct pack_list * add_pack_file(const char *filename)
 {
-	struct packed_git *p = packed_git;
+	struct packed_git *p = the_repository->objects.packed_git;
 
 	if (strlen(filename) < 40)
 		die("Bad pack filename: %s", filename);
@@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename)
 
 static void load_all(void)
 {
-	struct packed_git *p = packed_git;
+	struct packed_git *p = the_repository->objects.packed_git;
 
 	while (p) {
 		add_pack(p);
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 52c63ebfdc..6657ba1375 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -7,6 +7,7 @@
 #include "sideband.h"
 #include "run-command.h"
 #include "exec_cmd.h"
+#include "object-store.h"
 #include "commit.h"
 #include "object.h"
 #include "remote.h"
diff --git a/cache.h b/cache.h
index 8d0d34f78b..cd59c2fdb7 100644
--- a/cache.h
+++ b/cache.h
@@ -1564,34 +1564,6 @@ struct pack_window {
 	unsigned int inuse_cnt;
 };
 
-extern struct packed_git {
-	struct packed_git *next;
-	struct pack_window *windows;
-	off_t pack_size;
-	const void *index_data;
-	size_t index_size;
-	uint32_t num_objects;
-	uint32_t num_bad_objects;
-	unsigned char *bad_object_sha1;
-	int index_version;
-	time_t mtime;
-	int pack_fd;
-	unsigned pack_local:1,
-		 pack_keep:1,
-		 freshened:1,
-		 do_not_close:1;
-	unsigned char sha1[20];
-	struct revindex_entry *revindex;
-	/* something like ".git/objects/pack/xxxxx.pack" */
-	char pack_name[FLEX_ARRAY]; /* more */
-} *packed_git;
-
-/*
- * A most-recently-used ordered version of the packed_git list, which can
- * be iterated instead of packed_git (and marked via mru_mark).
- */
-extern struct mru packed_git_mru;
-
 struct pack_entry {
 	off_t offset;
 	unsigned char sha1[20];
diff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci
new file mode 100644
index 0000000000..da317a51a9
--- /dev/null
+++ b/contrib/coccinelle/packed_git.cocci
@@ -0,0 +1,7 @@
+@@ @@
+- packed_git
++ the_repository->objects.packed_git
+
+@@ @@
+- packed_git_mru
++ the_repository->objects.packed_git_mru
diff --git a/fast-import.c b/fast-import.c
index 49516d60e6..9a725ebf4f 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -154,8 +154,10 @@ Format of STDIN stream:
 
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
+#include "object-store.h"
 #include "object.h"
 #include "blob.h"
 #include "tree.h"
@@ -1110,7 +1112,7 @@ static int store_object(
 	if (e->idx.offset) {
 		duplicate_count_by_type[type]++;
 		return 1;
-	} else if (find_sha1_pack(oid.hash, packed_git)) {
+	} else if (find_sha1_pack(oid.hash, the_repository->objects.packed_git)) {
 		e->type = type;
 		e->pack_id = MAX_PACK_ID;
 		e->idx.offset = 1; /* just not zero! */
@@ -1305,7 +1307,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
 		duplicate_count_by_type[OBJ_BLOB]++;
 		truncate_pack(&checkpoint);
 
-	} else if (find_sha1_pack(oid.hash, packed_git)) {
+	} else if (find_sha1_pack(oid.hash, the_repository->objects.packed_git)) {
 		e->type = OBJ_BLOB;
 		e->pack_id = MAX_PACK_ID;
 		e->idx.offset = 1; /* just not zero! */
diff --git a/http-backend.c b/http-backend.c
index 8076b1d5e5..681515aefd 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -1,7 +1,9 @@
 #include "cache.h"
 #include "config.h"
+#include "repository.h"
 #include "refs.h"
 #include "pkt-line.h"
+#include "object-store.h"
 #include "object.h"
 #include "tag.h"
 #include "exec_cmd.h"
@@ -519,13 +521,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
 
 	select_getanyfile(hdr);
 	prepare_packed_git();
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (p->pack_local)
 			cnt++;
 	}
 
 	strbuf_grow(&buf, cnt * 53 + 2);
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (p->pack_local)
 			strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
 	}
diff --git a/http-push.c b/http-push.c
index e4c9b065ce..dfd83c4769 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "object-store.h"
 #include "commit.h"
 #include "tag.h"
 #include "blob.h"
diff --git a/http-walker.c b/http-walker.c
index 1ae8363de2..a1c6f2639b 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -4,6 +4,7 @@
 #include "http.h"
 #include "list.h"
 #include "transport.h"
+#include "object-store.h"
 #include "packfile.h"
 
 struct alt_base {
diff --git a/http.c b/http.c
index 9e40a465fd..3186de107b 100644
--- a/http.c
+++ b/http.c
@@ -1,6 +1,7 @@
 #include "git-compat-util.h"
 #include "http.h"
 #include "config.h"
+#include "object-store.h"
 #include "pack.h"
 #include "sideband.h"
 #include "run-command.h"
diff --git a/mru.h b/mru.h
index 42e4aeaa10..d7de81efb9 100644
--- a/mru.h
+++ b/mru.h
@@ -37,6 +37,7 @@ struct mru_entry {
 struct mru {
 	struct mru_entry *head, *tail;
 };
+#define MRU_INIT { NULL, NULL }
 
 void mru_append(struct mru *mru, void *item);
 void mru_mark(struct mru *mru, struct mru_entry *entry);
diff --git a/object-store.h b/object-store.h
index ace3efbfab..e2a59a0611 100644
--- a/object-store.h
+++ b/object-store.h
@@ -2,11 +2,42 @@
 #define OBJECT_STORE_H
 
 #include "cache.h"
+#include "mru.h"
 
 struct object_store {
+	struct packed_git *packed_git;
+
+	/*
+	 * A most-recently-used ordered version of the packed_git list, which can
+	 * be iterated instead of packed_git (and marked via mru_mark).
+	 */
+	struct mru packed_git_mru;
+
 	struct alternate_object_database *alt_odb_list;
 	struct alternate_object_database **alt_odb_tail;
 };
-#define OBJECT_STORE_INIT { NULL, NULL }
+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL }
+
+struct packed_git {
+	struct packed_git *next;
+	struct pack_window *windows;
+	off_t pack_size;
+	const void *index_data;
+	size_t index_size;
+	uint32_t num_objects;
+	uint32_t num_bad_objects;
+	unsigned char *bad_object_sha1;
+	int index_version;
+	time_t mtime;
+	int pack_fd;
+	unsigned pack_local:1,
+		 pack_keep:1,
+		 freshened:1,
+		 do_not_close:1;
+	unsigned char sha1[20];
+	struct revindex_entry *revindex;
+	/* something like ".git/objects/pack/xxxxx.pack" */
+	char pack_name[FLEX_ARRAY]; /* more */
+};
 
 #endif /* OBJECT_STORE_H */
diff --git a/pack-bitmap.c b/pack-bitmap.c
index cb3d14ba45..396abb75bd 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -5,11 +5,13 @@
 #include "revision.h"
 #include "progress.h"
 #include "list-objects.h"
+#include "object-store.h"
 #include "pack.h"
 #include "pack-bitmap.h"
 #include "pack-revindex.h"
 #include "pack-objects.h"
 #include "packfile.h"
+#include "repository.h"
 
 /*
  * An entry on the bitmap index, representing the bitmap for a given
@@ -335,7 +337,7 @@ static int open_pack_bitmap(void)
 	assert(!bitmap_git.map && !bitmap_git.loaded);
 
 	prepare_packed_git();
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (open_pack_bitmap_1(p) == 0)
 			ret = 0;
 	}
diff --git a/pack-check.c b/pack-check.c
index 073c1fbd46..c80c3ed8fd 100644
--- a/pack-check.c
+++ b/pack-check.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "pack.h"
+#include "object-store.h"
 #include "pack-revindex.h"
 #include "progress.h"
 #include "packfile.h"
diff --git a/pack-revindex.c b/pack-revindex.c
index 1b7ebd8d7e..82c3119652 100644
--- a/pack-revindex.c
+++ b/pack-revindex.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "pack-revindex.h"
+#include "object-store.h"
 
 /*
  * Pack index for existing packs give us easy access to the offsets into
diff --git a/packfile.c b/packfile.c
index 5040c9f137..57260a9b34 100644
--- a/packfile.c
+++ b/packfile.c
@@ -7,6 +7,7 @@
 #include "packfile.h"
 #include "delta.h"
 #include "list.h"
+#include "object-store.h"
 #include "streaming.h"
 #include "sha1-lookup.h"
 
@@ -40,8 +41,6 @@ static unsigned int pack_open_fds;
 static unsigned int pack_max_fds;
 static size_t peak_pack_mapped;
 static size_t pack_mapped;
-struct packed_git *packed_git;
-struct mru packed_git_mru;
 
 #define SZ_FMT PRIuMAX
 static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -241,7 +240,7 @@ static int unuse_one_window(struct packed_git *current)
 
 	if (current)
 		scan_windows(current, &lru_p, &lru_w, &lru_l);
-	for (p = packed_git; p; p = p->next)
+	for (p = the_repository->objects.packed_git; p; p = p->next)
 		scan_windows(p, &lru_p, &lru_w, &lru_l);
 	if (lru_p) {
 		munmap(lru_w->base, lru_w->len);
@@ -311,7 +310,7 @@ void close_all_packs(void)
 {
 	struct packed_git *p;
 
-	for (p = packed_git; p; p = p->next)
+	for (p = the_repository->objects.packed_git; p; p = p->next)
 		if (p->do_not_close)
 			die("BUG: want to close pack marked 'do-not-close'");
 		else
@@ -379,7 +378,7 @@ static int close_one_pack(void)
 	struct pack_window *mru_w = NULL;
 	int accept_windows_inuse = 1;
 
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (p->pack_fd == -1)
 			continue;
 		find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
@@ -670,8 +669,8 @@ void install_packed_git(struct packed_git *pack)
 	if (pack->pack_fd != -1)
 		pack_open_fds++;
 
-	pack->next = packed_git;
-	packed_git = pack;
+	pack->next = the_repository->objects.packed_git;
+	the_repository->objects.packed_git = pack;
 }
 
 void (*report_garbage)(unsigned seen_bits, const char *path);
@@ -753,7 +752,8 @@ static void prepare_packed_git_one(char *objdir, int local)
 		base_len = path.len;
 		if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
 			/* Don't reopen a pack we already have. */
-			for (p = packed_git; p; p = p->next) {
+			for (p = the_repository->objects.packed_git; p;
+			     p = p->next) {
 				size_t len;
 				if (strip_suffix(p->pack_name, ".pack", &len) &&
 				    len == base_len &&
@@ -803,7 +803,7 @@ unsigned long approximate_object_count(void)
 
 		prepare_packed_git();
 		count = 0;
-		for (p = packed_git; p; p = p->next) {
+		for (p = the_repository->objects.packed_git; p; p = p->next) {
 			if (open_pack_index(p))
 				continue;
 			count += p->num_objects;
@@ -852,17 +852,18 @@ static int sort_pack(const void *a_, const void *b_)
 
 static void rearrange_packed_git(void)
 {
-	packed_git = llist_mergesort(packed_git, get_next_packed_git,
-				     set_next_packed_git, sort_pack);
+	the_repository->objects.packed_git = llist_mergesort(
+		the_repository->objects.packed_git, get_next_packed_git,
+		set_next_packed_git, sort_pack);
 }
 
 static void prepare_packed_git_mru(void)
 {
 	struct packed_git *p;
 
-	mru_clear(&packed_git_mru);
-	for (p = packed_git; p; p = p->next)
-		mru_append(&packed_git_mru, p);
+	mru_clear(&the_repository->objects.packed_git_mru);
+	for (p = the_repository->objects.packed_git; p; p = p->next)
+		mru_append(&the_repository->objects.packed_git_mru, p);
 }
 
 static int prepare_packed_git_run_once = 0;
@@ -996,7 +997,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
 	struct packed_git *p;
 	unsigned i;
 
-	for (p = packed_git; p; p = p->next)
+	for (p = the_repository->objects.packed_git; p; p = p->next)
 		for (i = 0; i < p->num_bad_objects; i++)
 			if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
 				return p;
@@ -1828,12 +1829,12 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 	struct mru_entry *p;
 
 	prepare_packed_git();
-	if (!packed_git)
+	if (!the_repository->objects.packed_git)
 		return 0;
 
-	for (p = packed_git_mru.head; p; p = p->next) {
+	for (p = the_repository->objects.packed_git_mru.head; p; p = p->next) {
 		if (fill_pack_entry(sha1, e, p->item)) {
-			mru_mark(&packed_git_mru, p);
+			mru_mark(&the_repository->objects.packed_git_mru, p);
 			return 1;
 		}
 	}
@@ -1880,7 +1881,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
 	int pack_errors = 0;
 
 	prepare_packed_git();
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
 			continue;
 		if (open_pack_index(p)) {
diff --git a/reachable.c b/reachable.c
index d1ac5d97ef..efd1224f97 100644
--- a/reachable.c
+++ b/reachable.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "refs.h"
+#include "object-store.h"
 #include "tag.h"
 #include "commit.h"
 #include "blob.h"
diff --git a/server-info.c b/server-info.c
index 26a6c20b7d..96885c45f6 100644
--- a/server-info.c
+++ b/server-info.c
@@ -1,5 +1,7 @@
 #include "cache.h"
+#include "repository.h"
 #include "refs.h"
+#include "object-store.h"
 #include "object.h"
 #include "commit.h"
 #include "tag.h"
@@ -200,7 +202,7 @@ static void init_pack_info(const char *infofile, int force)
 	objdirlen = strlen(objdir);
 
 	prepare_packed_git();
-	for (p = packed_git; p; p = p->next) {
+	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		/* we ignore things on alternate path since they are
 		 * not available to the pullers in general.
 		 */
@@ -210,7 +212,7 @@ static void init_pack_info(const char *infofile, int force)
 	}
 	num_pack = i;
 	info = xcalloc(num_pack, sizeof(struct pack_info *));
-	for (i = 0, p = packed_git; p; p = p->next) {
+	for (i = 0, p = the_repository->objects.packed_git; p; p = p->next) {
 		if (!p->pack_local)
 			continue;
 		info[i] = xcalloc(1, sizeof(struct pack_info));
diff --git a/sha1_name.c b/sha1_name.c
index 5b8ce1c42c..153bcd83b9 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -194,7 +194,8 @@ static void find_short_packed_object(struct disambiguate_state *ds)
 	struct packed_git *p;
 
 	prepare_packed_git();
-	for (p = packed_git; p && !ds->ambiguous; p = p->next)
+	for (p = the_repository->objects.packed_git; p && !ds->ambiguous;
+	     p = p->next)
 		unique_in_pack(p, ds);
 }
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 05/39] pack: move prepare_packed_git_run_once to object store
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (3 preceding siblings ...)
  2017-08-30  6:54 ` [PATCH 04/39] object-store: move packed_git and packed_git_mru " Jonathan Nieder
@ 2017-08-30  6:54 ` Jonathan Nieder
  2017-08-30  6:55 ` [PATCH 06/39] pack: move approximate object count " Jonathan Nieder
                   ` (34 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:54 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Each repository's object store can be initialized independently, so
they must not share a run_once variable.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 object-store.h | 8 +++++++-
 packfile.c     | 7 +++----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/object-store.h b/object-store.h
index e2a59a0611..14129fbba1 100644
--- a/object-store.h
+++ b/object-store.h
@@ -15,8 +15,14 @@ struct object_store {
 
 	struct alternate_object_database *alt_odb_list;
 	struct alternate_object_database **alt_odb_tail;
+
+	/*
+	 * Whether packed_git has already been populated with this repository's
+	 * packs.
+	 */
+	unsigned packed_git_initialized : 1;
 };
-#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL }
+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0 }
 
 struct packed_git {
 	struct packed_git *next;
diff --git a/packfile.c b/packfile.c
index 57260a9b34..c54fe0ac1c 100644
--- a/packfile.c
+++ b/packfile.c
@@ -866,12 +866,11 @@ static void prepare_packed_git_mru(void)
 		mru_append(&the_repository->objects.packed_git_mru, p);
 }
 
-static int prepare_packed_git_run_once = 0;
 void prepare_packed_git(void)
 {
 	struct alternate_object_database *alt;
 
-	if (prepare_packed_git_run_once)
+	if (the_repository->objects.packed_git_initialized)
 		return;
 	prepare_packed_git_one(get_object_directory(), 1);
 	prepare_alt_odb();
@@ -879,13 +878,13 @@ void prepare_packed_git(void)
 		prepare_packed_git_one(alt->path, 0);
 	rearrange_packed_git();
 	prepare_packed_git_mru();
-	prepare_packed_git_run_once = 1;
+	the_repository->objects.packed_git_initialized = 1;
 }
 
 void reprepare_packed_git(void)
 {
 	approximate_object_count_valid = 0;
-	prepare_packed_git_run_once = 0;
+	the_repository->objects.packed_git_initialized = 0;
 	prepare_packed_git();
 }
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 06/39] pack: move approximate object count to object store
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (4 preceding siblings ...)
  2017-08-30  6:54 ` [PATCH 05/39] pack: move prepare_packed_git_run_once " Jonathan Nieder
@ 2017-08-30  6:55 ` Jonathan Nieder
  2017-08-30  6:56 ` [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable Jonathan Nieder
                   ` (33 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:55 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

The approximate_object_count() function maintains a rough count of
objects in a repository to estimate how long object name abbreviates
should be.  Object names are scoped to a repository and the
appropriate length may differ by repository, so the object count
should not be global.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 object-store.h | 10 +++++++++-
 packfile.c     | 11 +++++------
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/object-store.h b/object-store.h
index 14129fbba1..99f77d10cd 100644
--- a/object-store.h
+++ b/object-store.h
@@ -16,13 +16,21 @@ struct object_store {
 	struct alternate_object_database *alt_odb_list;
 	struct alternate_object_database **alt_odb_tail;
 
+	/*
+	 * A fast, rough count of the number of objects in the repository.
+	 * These two fields are not meant for direct access. Use
+	 * approximate_object_count() instead.
+	 */
+	unsigned long approximate_object_count;
+	unsigned approximate_object_count_valid : 1;
+
 	/*
 	 * Whether packed_git has already been populated with this repository's
 	 * packs.
 	 */
 	unsigned packed_git_initialized : 1;
 };
-#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0 }
+#define OBJECT_STORE_INIT { NULL, MRU_INIT, NULL, NULL, 0, 0, 0 }
 
 struct packed_git {
 	struct packed_git *next;
diff --git a/packfile.c b/packfile.c
index c54fe0ac1c..98267f014f 100644
--- a/packfile.c
+++ b/packfile.c
@@ -786,8 +786,6 @@ static void prepare_packed_git_one(char *objdir, int local)
 	strbuf_release(&path);
 }
 
-static int approximate_object_count_valid;
-
 /*
  * Give a fast, rough count of the number of objects in the repository. This
  * ignores loose objects completely. If you have a lot of them, then either
@@ -797,8 +795,8 @@ static int approximate_object_count_valid;
  */
 unsigned long approximate_object_count(void)
 {
-	static unsigned long count;
-	if (!approximate_object_count_valid) {
+	if (!the_repository->objects.approximate_object_count_valid) {
+		unsigned long count;
 		struct packed_git *p;
 
 		prepare_packed_git();
@@ -808,8 +806,9 @@ unsigned long approximate_object_count(void)
 				continue;
 			count += p->num_objects;
 		}
+		the_repository->objects.approximate_object_count = count;
 	}
-	return count;
+	return the_repository->objects.approximate_object_count;
 }
 
 static void *get_next_packed_git(const void *p)
@@ -883,7 +882,7 @@ void prepare_packed_git(void)
 
 void reprepare_packed_git(void)
 {
-	approximate_object_count_valid = 0;
+	the_repository->objects.approximate_object_count_valid = 0;
 	the_repository->objects.packed_git_initialized = 0;
 	prepare_packed_git();
 }
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (5 preceding siblings ...)
  2017-08-30  6:55 ` [PATCH 06/39] pack: move approximate object count " Jonathan Nieder
@ 2017-08-30  6:56 ` Jonathan Nieder
  2017-08-30 22:40   ` Brandon Williams
  2017-08-30  6:57 ` [PATCH 08/39] sha1_file: add repository argument to link_alt_odb_entry Jonathan Nieder
                   ` (32 subsequent siblings)
  39 siblings, 1 reply; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:56 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the alt_odb_usable caller to be
more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

Since the implementation does not yet work with other repositories,
use a wrapper macro to enforce that the caller passes in
the_repository as the first argument. It would be more appealing to
use BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work
because it requires a compile-time constant and common compilers like
gcc 4.8.4 do not consider "r == the_repository" a compile-time
constant.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 7c6ffd205a..1c757b44a3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -280,7 +280,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
 /*
  * Return non-zero iff the path is usable as an alternate object database.
  */
-static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
+#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)
+static int alt_odb_usable_the_repository(struct strbuf *path,
+					 const char *normalized_objdir)
 {
 	struct alternate_object_database *alt;
 
@@ -348,7 +350,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
 	while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
 		strbuf_setlen(&pathbuf, pathbuf.len - 1);
 
-	if (!alt_odb_usable(&pathbuf, normalized_objdir)) {
+	if (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {
 		strbuf_release(&pathbuf);
 		return -1;
 	}
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 08/39] sha1_file: add repository argument to link_alt_odb_entry
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (6 preceding siblings ...)
  2017-08-30  6:56 ` [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable Jonathan Nieder
@ 2017-08-30  6:57 ` Jonathan Nieder
  2017-08-30  6:58 ` [PATCH 09/39] sha1_file: add repository argument to read_info_alternates Jonathan Nieder
                   ` (31 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:57 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the link_alt_odb_entry caller to be
more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commit, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 1c757b44a3..c63b52f6fa 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -324,8 +324,9 @@ static int alt_odb_usable_the_repository(struct strbuf *path,
  * terminating NUL.
  */
 static void read_info_alternates(const char * relative_base, int depth);
-static int link_alt_odb_entry(const char *entry, const char *relative_base,
-	int depth, const char *normalized_objdir)
+#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)
+static int link_alt_odb_entry_the_repository(const char *entry,
+	const char *relative_base, int depth, const char *normalized_objdir)
 {
 	struct alternate_object_database *ent;
 	struct strbuf pathbuf = STRBUF_INIT;
@@ -419,7 +420,8 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,
 		alt = parse_alt_odb_entry(alt, sep, &entry);
 		if (!entry.len)
 			continue;
-		link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf);
+		link_alt_odb_entry(the_repository, entry.buf,
+				   relative_base, depth, objdirbuf.buf);
 	}
 	strbuf_release(&entry);
 	strbuf_release(&objdirbuf);
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 09/39] sha1_file: add repository argument to read_info_alternates
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (7 preceding siblings ...)
  2017-08-30  6:57 ` [PATCH 08/39] sha1_file: add repository argument to link_alt_odb_entry Jonathan Nieder
@ 2017-08-30  6:58 ` Jonathan Nieder
  2017-08-30  6:58 ` [PATCH 10/39] sha1_file: add repository argument to link_alt_odb_entries Jonathan Nieder
                   ` (30 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:58 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the read_info_alternates caller to
be more specific about which repository to read from. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commit, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index c63b52f6fa..29cead6d2c 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -323,7 +323,9 @@ static int alt_odb_usable_the_repository(struct strbuf *path,
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static void read_info_alternates(const char * relative_base, int depth);
+#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d)
+static void read_info_alternates_the_repository(const char *relative_base,
+						int depth);
 #define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)
 static int link_alt_odb_entry_the_repository(const char *entry,
 	const char *relative_base, int depth, const char *normalized_objdir)
@@ -364,7 +366,7 @@ static int link_alt_odb_entry_the_repository(const char *entry,
 	ent->next = NULL;
 
 	/* recursively add alternates */
-	read_info_alternates(pathbuf.buf, depth + 1);
+	read_info_alternates(the_repository, pathbuf.buf, depth + 1);
 
 	strbuf_release(&pathbuf);
 	return 0;
@@ -427,7 +429,8 @@ static void link_alt_odb_entries(const char *alt, int len, int sep,
 	strbuf_release(&objdirbuf);
 }
 
-static void read_info_alternates(const char * relative_base, int depth)
+static void read_info_alternates_the_repository(const char *relative_base,
+						int depth)
 {
 	char *map;
 	size_t mapsz;
@@ -624,7 +627,7 @@ void prepare_alt_odb(void)
 			&the_repository->objects.alt_odb_list;
 	link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
 
-	read_info_alternates(get_object_directory(), 0);
+	read_info_alternates(the_repository, get_object_directory(), 0);
 }
 
 /* Returns 1 if we have successfully freshened the file, 0 otherwise. */
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 10/39] sha1_file: add repository argument to link_alt_odb_entries
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (8 preceding siblings ...)
  2017-08-30  6:58 ` [PATCH 09/39] sha1_file: add repository argument to read_info_alternates Jonathan Nieder
@ 2017-08-30  6:58 ` Jonathan Nieder
  2017-08-30  6:59 ` [PATCH 11/39] sha1_file: add repository argument to stat_sha1_file Jonathan Nieder
                   ` (29 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:58 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the link_alt_odb_entries caller to
be more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 29cead6d2c..7938bd2a6f 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -401,8 +401,12 @@ static const char *parse_alt_odb_entry(const char *string,
 	return end;
 }
 
-static void link_alt_odb_entries(const char *alt, int len, int sep,
-				 const char *relative_base, int depth)
+#define link_alt_odb_entries(r, a, l, s, rb, d) \
+	link_alt_odb_entries_##r(a, l, s, rb, d)
+static void link_alt_odb_entries_the_repository(const char *alt, int len,
+						int sep,
+						const char *relative_base,
+						int depth)
 {
 	struct strbuf objdirbuf = STRBUF_INIT;
 	struct strbuf entry = STRBUF_INIT;
@@ -451,7 +455,7 @@ static void read_info_alternates_the_repository(const char *relative_base,
 	map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
 	close(fd);
 
-	link_alt_odb_entries(map, mapsz, '\n', relative_base, depth);
+	link_alt_odb_entries(the_repository, map, mapsz, '\n', relative_base, depth);
 
 	munmap(map, mapsz);
 }
@@ -508,7 +512,8 @@ void add_to_alternates_file(const char *reference)
 		if (commit_lock_file(lock))
 			die_errno("unable to move new alternates file into place");
 		if (the_repository->objects.alt_odb_tail)
-			link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+			link_alt_odb_entries(the_repository, reference,
+					     strlen(reference), '\n', NULL, 0);
 	}
 	free(alts);
 }
@@ -521,7 +526,8 @@ void add_to_alternates_memory(const char *reference)
 	 */
 	prepare_alt_odb();
 
-	link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+	link_alt_odb_entries(the_repository, reference, strlen(reference),
+			     '\n', NULL, 0);
 }
 
 /*
@@ -625,7 +631,8 @@ void prepare_alt_odb(void)
 
 	the_repository->objects.alt_odb_tail =
 			&the_repository->objects.alt_odb_list;
-	link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
+	link_alt_odb_entries(the_repository, alt, strlen(alt),
+			     PATH_SEP, NULL, 0);
 
 	read_info_alternates(the_repository, get_object_directory(), 0);
 }
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 11/39] sha1_file: add repository argument to stat_sha1_file
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (9 preceding siblings ...)
  2017-08-30  6:58 ` [PATCH 10/39] sha1_file: add repository argument to link_alt_odb_entries Jonathan Nieder
@ 2017-08-30  6:59 ` Jonathan Nieder
  2017-08-30  6:59 ` [PATCH 12/39] sha1_file: add repository argument to open_sha1_file Jonathan Nieder
                   ` (28 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:59 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the stat_sha1_file caller to be
more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 7938bd2a6f..d3573cec62 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -815,8 +815,9 @@ int git_open_cloexec(const char *name, int flags)
  * Note that it may point to static storage and is only valid until another
  * call to sha1_file_name(), etc.
  */
-static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
-			  const char **path)
+#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p)
+static int stat_sha1_file_the_repository(const unsigned char *sha1,
+					 struct stat *st, const char **path)
 {
 	struct alternate_object_database *alt;
 
@@ -1114,7 +1115,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 	if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {
 		const char *path;
 		struct stat st;
-		if (stat_sha1_file(sha1, &st, &path) < 0)
+		if (stat_sha1_file(the_repository, sha1, &st, &path) < 0)
 			return -1;
 		if (oi->disk_sizep)
 			*oi->disk_sizep = st.st_size;
@@ -1306,7 +1307,7 @@ void *read_sha1_file_extended(const unsigned char *sha1,
 		die("replacement %s not found for %s",
 		    sha1_to_hex(repl), sha1_to_hex(sha1));
 
-	if (!stat_sha1_file(repl, &st, &path))
+	if (!stat_sha1_file(the_repository, repl, &st, &path))
 		die("loose object %s (stored in %s) is corrupt",
 		    sha1_to_hex(repl), path);
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 12/39] sha1_file: add repository argument to open_sha1_file
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (10 preceding siblings ...)
  2017-08-30  6:59 ` [PATCH 11/39] sha1_file: add repository argument to stat_sha1_file Jonathan Nieder
@ 2017-08-30  6:59 ` Jonathan Nieder
  2017-08-30  7:00 ` [PATCH 13/39] sha1_file: add repository argument to map_sha1_file_1 Jonathan Nieder
                   ` (27 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  6:59 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the open_sha1_file caller to be
more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index d3573cec62..893e37afec 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -840,7 +840,9 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,
  * Like stat_sha1_file(), but actually open the object and return the
  * descriptor. See the caveats on the "path" parameter above.
  */
-static int open_sha1_file(const unsigned char *sha1, const char **path)
+#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p)
+static int open_sha1_file_the_repository(const unsigned char *sha1,
+					 const char **path)
 {
 	int fd;
 	struct alternate_object_database *alt;
@@ -879,7 +881,7 @@ static void *map_sha1_file_1(const char *path,
 	if (path)
 		fd = git_open(path);
 	else
-		fd = open_sha1_file(sha1, &path);
+		fd = open_sha1_file(the_repository, sha1, &path);
 	map = NULL;
 	if (fd >= 0) {
 		struct stat st;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 13/39] sha1_file: add repository argument to map_sha1_file_1
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (11 preceding siblings ...)
  2017-08-30  6:59 ` [PATCH 12/39] sha1_file: add repository argument to open_sha1_file Jonathan Nieder
@ 2017-08-30  7:00 ` Jonathan Nieder
  2017-08-30  7:01 ` [PATCH 14/39] sha1_file: add repository argument to sha1_loose_object_info Jonathan Nieder
                   ` (26 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:00 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the map_sha1_file_1 caller to be
more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 893e37afec..3adae104c6 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -871,9 +871,10 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,
  * Map the loose object at "path" if it is not NULL, or the path found by
  * searching for a loose object named "sha1".
  */
-static void *map_sha1_file_1(const char *path,
-			     const unsigned char *sha1,
-			     unsigned long *size)
+#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si)
+static void *map_sha1_file_1_the_repository(const char *path,
+					    const unsigned char *sha1,
+					    unsigned long *size)
 {
 	void *map;
 	int fd;
@@ -902,7 +903,7 @@ static void *map_sha1_file_1(const char *path,
 
 void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
 {
-	return map_sha1_file_1(NULL, sha1, size);
+	return map_sha1_file_1(the_repository, NULL, sha1, size);
 }
 
 static int unpack_sha1_short_header(git_zstream *stream,
@@ -2102,7 +2103,7 @@ int read_loose_object(const char *path,
 
 	*contents = NULL;
 
-	map = map_sha1_file_1(path, NULL, &mapsize);
+	map = map_sha1_file_1(the_repository, path, NULL, &mapsize);
 	if (!map) {
 		error_errno("unable to mmap %s", path);
 		goto out;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 14/39] sha1_file: add repository argument to sha1_loose_object_info
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (12 preceding siblings ...)
  2017-08-30  7:00 ` [PATCH 13/39] sha1_file: add repository argument to map_sha1_file_1 Jonathan Nieder
@ 2017-08-30  7:01 ` Jonathan Nieder
  2017-08-30  7:01 ` [PATCH 15/39] object-store: add repository argument to prepare_alt_odb Jonathan Nieder
                   ` (25 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow the sha1_loose_object_info caller
to be more specific about which repository to act on. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 3adae104c6..d1c8dbcfa5 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1092,9 +1092,10 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
 	return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-static int sha1_loose_object_info(const unsigned char *sha1,
-				  struct object_info *oi,
-				  int flags)
+#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f)
+static int sha1_loose_object_info_the_repository(const unsigned char *sha1,
+						 struct object_info *oi,
+						 int flags)
 {
 	int status = 0;
 	unsigned long mapsize;
@@ -1200,7 +1201,7 @@ 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))
+		if (!sha1_loose_object_info(the_repository, real, oi, flags))
 			return 0;
 
 		/* Not a loose object; someone else may have just packed it. */
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 15/39] object-store: add repository argument to prepare_alt_odb
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (13 preceding siblings ...)
  2017-08-30  7:01 ` [PATCH 14/39] sha1_file: add repository argument to sha1_loose_object_info Jonathan Nieder
@ 2017-08-30  7:01 ` Jonathan Nieder
  2017-08-30  7:02 ` [PATCH 16/39] object-store: add repository argument to foreach_alt_odb Jonathan Nieder
                   ` (24 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow prepare_alt_odb callers to be more
specific about which repository to handle. This is a small mechanical
change; it doesn't change the implementation to handle repositories
other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

While at it, move the declaration to object-store.h, where it should
be easier to find.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/fsck.c |  2 +-
 cache.h        |  1 -
 object-store.h |  3 +++
 packfile.c     |  2 +-
 sha1_file.c    | 13 +++++++------
 sha1_name.c    |  3 ++-
 6 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 20bbcdcf4a..35972fe2be 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -700,7 +700,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 	} else {
 		fsck_object_dir(get_object_directory());
 
-		prepare_alt_odb();
+		prepare_alt_odb(the_repository);
 		for (alt = the_repository->objects.alt_odb_list;
 				alt; alt = alt->next)
 			fsck_object_dir(alt->path);
diff --git a/cache.h b/cache.h
index cd59c2fdb7..5770224167 100644
--- a/cache.h
+++ b/cache.h
@@ -1523,7 +1523,6 @@ struct alternate_object_database {
 
 	char path[FLEX_ARRAY];
 };
-extern void prepare_alt_odb(void);
 extern char *compute_alternate_path(const char *path, struct strbuf *err);
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
 extern int foreach_alt_odb(alt_odb_fn, void*);
diff --git a/object-store.h b/object-store.h
index 99f77d10cd..e749c952d5 100644
--- a/object-store.h
+++ b/object-store.h
@@ -54,4 +54,7 @@ struct packed_git {
 	char pack_name[FLEX_ARRAY]; /* more */
 };
 
+#define prepare_alt_odb(r) prepare_alt_odb_##r()
+extern void prepare_alt_odb_the_repository(void);
+
 #endif /* OBJECT_STORE_H */
diff --git a/packfile.c b/packfile.c
index 98267f014f..2cd61b32a3 100644
--- a/packfile.c
+++ b/packfile.c
@@ -872,7 +872,7 @@ void prepare_packed_git(void)
 	if (the_repository->objects.packed_git_initialized)
 		return;
 	prepare_packed_git_one(get_object_directory(), 1);
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
 		prepare_packed_git_one(alt->path, 0);
 	rearrange_packed_git();
diff --git a/sha1_file.c b/sha1_file.c
index d1c8dbcfa5..9211c73920 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -23,6 +23,7 @@
 #include "sha1-lookup.h"
 #include "bulk-checkin.h"
 #include "repository.h"
+#include "object-store.h"
 #include "streaming.h"
 #include "dir.h"
 #include "mru.h"
@@ -524,7 +525,7 @@ void add_to_alternates_memory(const char *reference)
 	 * Make sure alternates are initialized, or else our entry may be
 	 * overwritten when they are.
 	 */
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 
 	link_alt_odb_entries(the_repository, reference, strlen(reference),
 			     '\n', NULL, 0);
@@ -610,7 +611,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
 	struct alternate_object_database *ent;
 	int r = 0;
 
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	for (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {
 		r = fn(ent, cb);
 		if (r)
@@ -619,7 +620,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
 	return r;
 }
 
-void prepare_alt_odb(void)
+void prepare_alt_odb_the_repository(void)
 {
 	const char *alt;
 
@@ -669,7 +670,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)
 static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
 {
 	struct alternate_object_database *alt;
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		const char *path = alt_sha1_path(alt, sha1);
 		if (check_and_freshen_file(path, freshen))
@@ -825,7 +826,7 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,
 	if (!lstat(*path, st))
 		return 0;
 
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	errno = ENOENT;
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
@@ -854,7 +855,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,
 		return fd;
 	most_interesting_errno = errno;
 
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
 		fd = git_open(*path);
diff --git a/sha1_name.c b/sha1_name.c
index 153bcd83b9..952eb64711 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -11,6 +11,7 @@
 #include "sha1-array.h"
 #include "packfile.h"
 #include "repository.h"
+#include "object-store.h"
 
 static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
 
@@ -351,7 +352,7 @@ static int init_object_disambiguation(const char *name, int len,
 
 	ds->len = len;
 	ds->hex_pfx[len] = '\0';
-	prepare_alt_odb();
+	prepare_alt_odb(the_repository);
 	return 0;
 }
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 16/39] object-store: add repository argument to foreach_alt_odb
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (14 preceding siblings ...)
  2017-08-30  7:01 ` [PATCH 15/39] object-store: add repository argument to prepare_alt_odb Jonathan Nieder
@ 2017-08-30  7:02 ` Jonathan Nieder
  2017-08-30  7:02 ` [PATCH 17/39] pack: add repository argument to install_packed_git Jonathan Nieder
                   ` (23 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:02 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Add a repository argument to allow foreach_alt_odb callers to be more
specific about which repository to handle. This is a small mechanical
change; it doesn't change the implementation to handle repositories
other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

While at it, move the declaration to object-store.h, where it should
be easier to find.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/count-objects.c     | 2 +-
 builtin/submodule--helper.c | 4 +++-
 cache.h                     | 2 --
 object-store.h              | 4 ++++
 sha1_file.c                 | 4 ++--
 transport.c                 | 4 +++-
 6 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 9334648dcc..843a7d7d7e 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -155,7 +155,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
 		printf("prune-packable: %lu\n", packed_loose);
 		printf("garbage: %lu\n", garbage);
 		printf("size-garbage: %s\n", garbage_buf.buf);
-		foreach_alt_odb(print_alternate, NULL);
+		foreach_alt_odb(the_repository, print_alternate, NULL);
 		strbuf_release(&loose_buf);
 		strbuf_release(&pack_buf);
 		strbuf_release(&garbage_buf);
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 818fe74f0a..299a71b90c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -6,6 +6,7 @@
 #include "quote.h"
 #include "pathspec.h"
 #include "dir.h"
+#include "object-store.h"
 #include "submodule.h"
 #include "submodule-config.h"
 #include "string-list.h"
@@ -598,7 +599,8 @@ static void prepare_possible_alternates(const char *sm_name,
 		die(_("Value '%s' for submodule.alternateErrorStrategy is not recognized"), error_strategy);
 
 	if (!strcmp(sm_alternate, "superproject"))
-		foreach_alt_odb(add_possible_reference_from_superproject, &sas);
+		foreach_alt_odb(the_repository,
+				add_possible_reference_from_superproject, &sas);
 	else if (!strcmp(sm_alternate, "no"))
 		; /* do nothing */
 	else
diff --git a/cache.h b/cache.h
index 5770224167..abec62dc9b 100644
--- a/cache.h
+++ b/cache.h
@@ -1524,8 +1524,6 @@ struct alternate_object_database {
 	char path[FLEX_ARRAY];
 };
 extern char *compute_alternate_path(const char *path, struct strbuf *err);
-typedef int alt_odb_fn(struct alternate_object_database *, void *);
-extern int foreach_alt_odb(alt_odb_fn, void*);
 
 /*
  * Allocate a "struct alternate_object_database" but do _not_ actually
diff --git a/object-store.h b/object-store.h
index e749c952d5..eef8d3b653 100644
--- a/object-store.h
+++ b/object-store.h
@@ -57,4 +57,8 @@ struct packed_git {
 #define prepare_alt_odb(r) prepare_alt_odb_##r()
 extern void prepare_alt_odb_the_repository(void);
 
+typedef int alt_odb_fn(struct alternate_object_database *, void *);
+#define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)
+extern int foreach_alt_odb_the_repository(alt_odb_fn, void*);
+
 #endif /* OBJECT_STORE_H */
diff --git a/sha1_file.c b/sha1_file.c
index 9211c73920..8c599dbfc2 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -606,7 +606,7 @@ char *compute_alternate_path(const char *path, struct strbuf *err)
 	return ref_git;
 }
 
-int foreach_alt_odb(alt_odb_fn fn, void *cb)
+int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)
 {
 	struct alternate_object_database *ent;
 	int r = 0;
@@ -2031,7 +2031,7 @@ int for_each_loose_object(each_loose_object_fn cb, void *data, unsigned flags)
 
 	alt.cb = cb;
 	alt.data = data;
-	return foreach_alt_odb(loose_from_alt_odb, &alt);
+	return foreach_alt_odb(the_repository, loose_from_alt_odb, &alt);
 }
 
 static int check_stream_sha1(git_zstream *stream,
diff --git a/transport.c b/transport.c
index d75ff0514d..426a3a3a80 100644
--- a/transport.c
+++ b/transport.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "config.h"
 #include "transport.h"
+#include "repository.h"
 #include "run-command.h"
 #include "pkt-line.h"
 #include "fetch-pack.h"
@@ -11,6 +12,7 @@
 #include "bundle.h"
 #include "dir.h"
 #include "refs.h"
+#include "object-store.h"
 #include "branch.h"
 #include "url.h"
 #include "submodule.h"
@@ -1286,5 +1288,5 @@ void for_each_alternate_ref(alternate_ref_fn fn, void *data)
 	struct alternate_refs_data cb;
 	cb.fn = fn;
 	cb.data = data;
-	foreach_alt_odb(refs_from_alternate_cb, &cb);
+	foreach_alt_odb(the_repository, refs_from_alternate_cb, &cb);
 }
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 17/39] pack: add repository argument to install_packed_git
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (15 preceding siblings ...)
  2017-08-30  7:02 ` [PATCH 16/39] object-store: add repository argument to foreach_alt_odb Jonathan Nieder
@ 2017-08-30  7:02 ` Jonathan Nieder
  2017-08-30  7:03 ` [PATCH 18/39] pack: add repository argument to prepare_packed_git_one Jonathan Nieder
                   ` (22 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:02 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow install_packed_git callers to be
more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 fast-import.c | 2 +-
 http.c        | 3 ++-
 packfile.c    | 4 ++--
 packfile.h    | 3 ++-
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/fast-import.c b/fast-import.c
index 9a725ebf4f..4c3b3d9df6 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1038,7 +1038,7 @@ static void end_packfile(void)
 		if (!new_p)
 			die("core git rejected index %s", idx_name);
 		all_packs[pack_id] = new_p;
-		install_packed_git(new_p);
+		install_packed_git(the_repository, new_p);
 		free(idx_name);
 
 		/* Print the boundary */
diff --git a/http.c b/http.c
index 3186de107b..0979053272 100644
--- a/http.c
+++ b/http.c
@@ -1,5 +1,6 @@
 #include "git-compat-util.h"
 #include "http.h"
+#include "repository.h"
 #include "config.h"
 #include "object-store.h"
 #include "pack.h"
@@ -2049,7 +2050,7 @@ int finish_http_pack_request(struct http_pack_request *preq)
 		return -1;
 	}
 
-	install_packed_git(p);
+	install_packed_git(the_repository, p);
 	free(tmp_idx);
 	return 0;
 }
diff --git a/packfile.c b/packfile.c
index 2cd61b32a3..cea3698af5 100644
--- a/packfile.c
+++ b/packfile.c
@@ -664,7 +664,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
 	return p;
 }
 
-void install_packed_git(struct packed_git *pack)
+void install_packed_git_the_repository(struct packed_git *pack)
 {
 	if (pack->pack_fd != -1)
 		pack_open_fds++;
@@ -766,7 +766,7 @@ static void prepare_packed_git_one(char *objdir, int local)
 			     * corresponding .pack file that we can map.
 			     */
 			    (p = add_packed_git(path.buf, path.len, local)) != NULL)
-				install_packed_git(p);
+				install_packed_git(the_repository, p);
 		}
 
 		if (!report_garbage)
diff --git a/packfile.h b/packfile.h
index 0cdeb54dcd..7e6959d440 100644
--- a/packfile.h
+++ b/packfile.h
@@ -34,7 +34,8 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
 extern void prepare_packed_git(void);
 extern void reprepare_packed_git(void);
-extern void install_packed_git(struct packed_git *pack);
+#define install_packed_git(r, p) install_packed_git_##r(p)
+extern void install_packed_git_the_repository(struct packed_git *pack);
 
 /*
  * Give a rough count of objects in the repository. This sacrifices accuracy
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 18/39] pack: add repository argument to prepare_packed_git_one
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (16 preceding siblings ...)
  2017-08-30  7:02 ` [PATCH 17/39] pack: add repository argument to install_packed_git Jonathan Nieder
@ 2017-08-30  7:03 ` Jonathan Nieder
  2017-08-30  7:03 ` [PATCH 19/39] pack: add repository argument to rearrange_packed_git Jonathan Nieder
                   ` (21 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:03 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow the prepare_packed_git_one caller
to be more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/packfile.c b/packfile.c
index cea3698af5..3a841c0f69 100644
--- a/packfile.c
+++ b/packfile.c
@@ -719,7 +719,8 @@ static void report_pack_garbage(struct string_list *list)
 	report_helper(list, seen_bits, first, list->nr);
 }
 
-static void prepare_packed_git_one(char *objdir, int local)
+#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l)
+static void prepare_packed_git_one_the_repository(char *objdir, int local)
 {
 	struct strbuf path = STRBUF_INIT;
 	size_t dirnamelen;
@@ -871,10 +872,10 @@ void prepare_packed_git(void)
 
 	if (the_repository->objects.packed_git_initialized)
 		return;
-	prepare_packed_git_one(get_object_directory(), 1);
+	prepare_packed_git_one(the_repository, get_object_directory(), 1);
 	prepare_alt_odb(the_repository);
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
-		prepare_packed_git_one(alt->path, 0);
+		prepare_packed_git_one(the_repository, alt->path, 0);
 	rearrange_packed_git();
 	prepare_packed_git_mru();
 	the_repository->objects.packed_git_initialized = 1;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 19/39] pack: add repository argument to rearrange_packed_git
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (17 preceding siblings ...)
  2017-08-30  7:03 ` [PATCH 18/39] pack: add repository argument to prepare_packed_git_one Jonathan Nieder
@ 2017-08-30  7:03 ` Jonathan Nieder
  2017-08-30  7:04 ` [PATCH 20/39] pack: add repository argument to prepare_packed_git_mru Jonathan Nieder
                   ` (20 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:03 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow the rearrange_packed_git caller to
be more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/packfile.c b/packfile.c
index 3a841c0f69..1d03bf48b4 100644
--- a/packfile.c
+++ b/packfile.c
@@ -850,7 +850,8 @@ static int sort_pack(const void *a_, const void *b_)
 	return -1;
 }
 
-static void rearrange_packed_git(void)
+#define rearrange_packed_git(r) rearrange_packed_git_##r()
+static void rearrange_packed_git_the_repository(void)
 {
 	the_repository->objects.packed_git = llist_mergesort(
 		the_repository->objects.packed_git, get_next_packed_git,
@@ -876,7 +877,7 @@ void prepare_packed_git(void)
 	prepare_alt_odb(the_repository);
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
 		prepare_packed_git_one(the_repository, alt->path, 0);
-	rearrange_packed_git();
+	rearrange_packed_git(the_repository);
 	prepare_packed_git_mru();
 	the_repository->objects.packed_git_initialized = 1;
 }
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 20/39] pack: add repository argument to prepare_packed_git_mru
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (18 preceding siblings ...)
  2017-08-30  7:03 ` [PATCH 19/39] pack: add repository argument to rearrange_packed_git Jonathan Nieder
@ 2017-08-30  7:04 ` Jonathan Nieder
  2017-08-30  7:05 ` [PATCH 21/39] pack: add repository argument to prepare_packed_git Jonathan Nieder
                   ` (19 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:04 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow the prepare_packed_git_mru caller
to be more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/packfile.c b/packfile.c
index 1d03bf48b4..6a04e4bb1b 100644
--- a/packfile.c
+++ b/packfile.c
@@ -858,7 +858,8 @@ static void rearrange_packed_git_the_repository(void)
 		set_next_packed_git, sort_pack);
 }
 
-static void prepare_packed_git_mru(void)
+#define prepare_packed_git_mru(r) prepare_packed_git_mru_##r()
+static void prepare_packed_git_mru_the_repository(void)
 {
 	struct packed_git *p;
 
@@ -878,7 +879,7 @@ void prepare_packed_git(void)
 	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
 		prepare_packed_git_one(the_repository, alt->path, 0);
 	rearrange_packed_git(the_repository);
-	prepare_packed_git_mru();
+	prepare_packed_git_mru(the_repository);
 	the_repository->objects.packed_git_initialized = 1;
 }
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 21/39] pack: add repository argument to prepare_packed_git
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (19 preceding siblings ...)
  2017-08-30  7:04 ` [PATCH 20/39] pack: add repository argument to prepare_packed_git_mru Jonathan Nieder
@ 2017-08-30  7:05 ` Jonathan Nieder
  2017-08-30  7:06 ` [PATCH 22/39] pack: add repository argument to reprepare_packed_git Jonathan Nieder
                   ` (18 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:05 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow prepare_packed_git_mru callers to
be more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

Callers adapted using contrib/coccinelle/packed_git.cocci.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/count-objects.c             |  2 +-
 builtin/fsck.c                      |  2 +-
 builtin/gc.c                        |  2 +-
 builtin/pack-objects.c              |  2 +-
 builtin/pack-redundant.c            |  2 +-
 contrib/coccinelle/packed_git.cocci |  4 ++++
 fast-import.c                       |  2 +-
 http-backend.c                      |  2 +-
 pack-bitmap.c                       |  2 +-
 packfile.c                          | 10 +++++-----
 packfile.h                          |  3 ++-
 server-info.c                       |  2 +-
 sha1_name.c                         |  2 +-
 13 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 843a7d7d7e..e340b3e3c3 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -123,7 +123,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
 		struct strbuf pack_buf = STRBUF_INIT;
 		struct strbuf garbage_buf = STRBUF_INIT;
 		if (!the_repository->objects.packed_git)
-			prepare_packed_git();
+			prepare_packed_git(the_repository);
 		for (p = the_repository->objects.packed_git; p; p = p->next) {
 			if (!p->pack_local)
 				continue;
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 35972fe2be..9ed210b377 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -710,7 +710,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 			uint32_t total = 0, count = 0;
 			struct progress *progress = NULL;
 
-			prepare_packed_git();
+			prepare_packed_git(the_repository);
 
 			if (show_progress) {
 				for (p = the_repository->objects.packed_git; p;
diff --git a/builtin/gc.c b/builtin/gc.c
index 73f727332c..11312529c8 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -174,7 +174,7 @@ static int too_many_packs(void)
 	if (gc_auto_pack_limit <= 0)
 		return 0;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (cnt = 0, p = the_repository->objects.packed_git; p; p = p->next) {
 		if (!p->pack_local)
 			continue;
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index b135fb3fb9..cf2941e68f 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -3052,7 +3052,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 	if (progress && all_progress_implied)
 		progress = 2;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	if (ignore_packed_keep) {
 		struct packed_git *p;
 		for (p = the_repository->objects.packed_git; p; p = p->next)
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 55462bc826..83d2395dae 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -631,7 +631,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
 			break;
 	}
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 
 	if (load_all_packs)
 		load_all();
diff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci
index da317a51a9..7554f4773c 100644
--- a/contrib/coccinelle/packed_git.cocci
+++ b/contrib/coccinelle/packed_git.cocci
@@ -5,3 +5,7 @@
 @@ @@
 - packed_git_mru
 + the_repository->objects.packed_git_mru
+
+@@ @@
+- prepare_packed_git()
++ prepare_packed_git(the_repository)
diff --git a/fast-import.c b/fast-import.c
index 4c3b3d9df6..0024a5e132 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -3471,7 +3471,7 @@ int cmd_main(int argc, const char **argv)
 		rc_free[i].next = &rc_free[i + 1];
 	rc_free[cmd_save - 1].next = NULL;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	start_packfile();
 	set_die_routine(die_nicely);
 	set_checkpoint_signal();
diff --git a/http-backend.c b/http-backend.c
index 681515aefd..c62796a131 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -520,7 +520,7 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
 	size_t cnt = 0;
 
 	select_getanyfile(hdr);
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (p->pack_local)
 			cnt++;
diff --git a/pack-bitmap.c b/pack-bitmap.c
index 396abb75bd..39ec1eaf05 100644
--- a/pack-bitmap.c
+++ b/pack-bitmap.c
@@ -336,7 +336,7 @@ static int open_pack_bitmap(void)
 
 	assert(!bitmap_git.map && !bitmap_git.loaded);
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if (open_pack_bitmap_1(p) == 0)
 			ret = 0;
diff --git a/packfile.c b/packfile.c
index 6a04e4bb1b..34b887e7e5 100644
--- a/packfile.c
+++ b/packfile.c
@@ -800,7 +800,7 @@ unsigned long approximate_object_count(void)
 		unsigned long count;
 		struct packed_git *p;
 
-		prepare_packed_git();
+		prepare_packed_git(the_repository);
 		count = 0;
 		for (p = the_repository->objects.packed_git; p; p = p->next) {
 			if (open_pack_index(p))
@@ -868,7 +868,7 @@ static void prepare_packed_git_mru_the_repository(void)
 		mru_append(&the_repository->objects.packed_git_mru, p);
 }
 
-void prepare_packed_git(void)
+void prepare_packed_git_the_repository(void)
 {
 	struct alternate_object_database *alt;
 
@@ -887,7 +887,7 @@ void reprepare_packed_git(void)
 {
 	the_repository->objects.approximate_object_count_valid = 0;
 	the_repository->objects.packed_git_initialized = 0;
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 }
 
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
@@ -1829,7 +1829,7 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
 {
 	struct mru_entry *p;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	if (!the_repository->objects.packed_git)
 		return 0;
 
@@ -1881,7 +1881,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
 	int r = 0;
 	int pack_errors = 0;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
 			continue;
diff --git a/packfile.h b/packfile.h
index 7e6959d440..e543a98b23 100644
--- a/packfile.h
+++ b/packfile.h
@@ -32,7 +32,8 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
 #define PACKDIR_FILE_GARBAGE 4
 extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
-extern void prepare_packed_git(void);
+#define prepare_packed_git(r) prepare_packed_git_##r()
+extern void prepare_packed_git_the_repository(void);
 extern void reprepare_packed_git(void);
 #define install_packed_git(r, p) install_packed_git_##r(p)
 extern void install_packed_git_the_repository(struct packed_git *pack);
diff --git a/server-info.c b/server-info.c
index 96885c45f6..6cd1506e5e 100644
--- a/server-info.c
+++ b/server-info.c
@@ -201,7 +201,7 @@ static void init_pack_info(const char *infofile, int force)
 	objdir = get_object_directory();
 	objdirlen = strlen(objdir);
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (p = the_repository->objects.packed_git; p; p = p->next) {
 		/* we ignore things on alternate path since they are
 		 * not available to the pullers in general.
diff --git a/sha1_name.c b/sha1_name.c
index 952eb64711..387836e717 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -194,7 +194,7 @@ static void find_short_packed_object(struct disambiguate_state *ds)
 {
 	struct packed_git *p;
 
-	prepare_packed_git();
+	prepare_packed_git(the_repository);
 	for (p = the_repository->objects.packed_git; p && !ds->ambiguous;
 	     p = p->next)
 		unique_in_pack(p, ds);
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 22/39] pack: add repository argument to reprepare_packed_git
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (20 preceding siblings ...)
  2017-08-30  7:05 ` [PATCH 21/39] pack: add repository argument to prepare_packed_git Jonathan Nieder
@ 2017-08-30  7:06 ` Jonathan Nieder
  2017-08-30  7:06 ` [PATCH 23/39] pack: add repository argument to sha1_file_name Jonathan Nieder
                   ` (17 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:06 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow reprepare_packed_git_mru callers to
be more specific about which repository to handle. This is a small
mechanical change; it doesn't change the implementation to handle
repositories other than the_repository yet.

Callers adapted using contrib/coccinelle/packed_git.cocci.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 builtin/gc.c                        | 2 +-
 builtin/receive-pack.c              | 3 ++-
 bulk-checkin.c                      | 3 ++-
 contrib/coccinelle/packed_git.cocci | 4 ++++
 fetch-pack.c                        | 3 ++-
 packfile.c                          | 2 +-
 packfile.h                          | 3 ++-
 sha1_file.c                         | 2 +-
 8 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/builtin/gc.c b/builtin/gc.c
index 11312529c8..d0da9e5403 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -475,7 +475,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
 		return error(FAILED_RUN, rerere.argv[0]);
 
 	report_garbage = report_pack_garbage;
-	reprepare_packed_git();
+	reprepare_packed_git(the_repository);
 	if (pack_garbage.nr > 0)
 		clean_pack_garbage();
 
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 6657ba1375..97750d0d4e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1,4 +1,5 @@
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "pack.h"
@@ -1779,7 +1780,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
 		status = finish_command(&child);
 		if (status)
 			return "index-pack abnormal exit";
-		reprepare_packed_git();
+		reprepare_packed_git(the_repository);
 	}
 	return NULL;
 }
diff --git a/bulk-checkin.c b/bulk-checkin.c
index 9a1f6c49ab..96f37100fc 100644
--- a/bulk-checkin.c
+++ b/bulk-checkin.c
@@ -3,6 +3,7 @@
  */
 #include "cache.h"
 #include "bulk-checkin.h"
+#include "repository.h"
 #include "csum-file.h"
 #include "pack.h"
 #include "strbuf.h"
@@ -57,7 +58,7 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state)
 
 	strbuf_release(&packname);
 	/* Make objects we just wrote available to ourselves */
-	reprepare_packed_git();
+	reprepare_packed_git(the_repository);
 }
 
 static int already_written(struct bulk_checkin_state *state, unsigned char sha1[])
diff --git a/contrib/coccinelle/packed_git.cocci b/contrib/coccinelle/packed_git.cocci
index 7554f4773c..0cb0e95f82 100644
--- a/contrib/coccinelle/packed_git.cocci
+++ b/contrib/coccinelle/packed_git.cocci
@@ -9,3 +9,7 @@
 @@ @@
 - prepare_packed_git()
 + prepare_packed_git(the_repository)
+
+@@ @@
+- reprepare_packed_git()
++ reprepare_packed_git(the_repository)
diff --git a/fetch-pack.c b/fetch-pack.c
index 105506e9aa..e9a6683437 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "refs.h"
@@ -1168,7 +1169,7 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
 	prepare_shallow_info(&si, shallow);
 	ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
 				&si, pack_lockfile);
-	reprepare_packed_git();
+	reprepare_packed_git(the_repository);
 	update_shallow(args, sought, nr_sought, &si);
 	clear_shallow_info(&si);
 	return ref_cpy;
diff --git a/packfile.c b/packfile.c
index 34b887e7e5..86c3964018 100644
--- a/packfile.c
+++ b/packfile.c
@@ -883,7 +883,7 @@ void prepare_packed_git_the_repository(void)
 	the_repository->objects.packed_git_initialized = 1;
 }
 
-void reprepare_packed_git(void)
+void reprepare_packed_git_the_repository(void)
 {
 	the_repository->objects.approximate_object_count_valid = 0;
 	the_repository->objects.packed_git_initialized = 0;
diff --git a/packfile.h b/packfile.h
index e543a98b23..74f293c439 100644
--- a/packfile.h
+++ b/packfile.h
@@ -34,7 +34,8 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
 #define prepare_packed_git(r) prepare_packed_git_##r()
 extern void prepare_packed_git_the_repository(void);
-extern void reprepare_packed_git(void);
+#define reprepare_packed_git(r) reprepare_packed_git_##r()
+extern void reprepare_packed_git_the_repository(void);
 #define install_packed_git(r, p) install_packed_git_##r(p)
 extern void install_packed_git_the_repository(struct packed_git *pack);
 
diff --git a/sha1_file.c b/sha1_file.c
index 8c599dbfc2..6af88e5b04 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1209,7 +1209,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
 		if (flags & OBJECT_INFO_QUICK) {
 			return -1;
 		} else {
-			reprepare_packed_git();
+			reprepare_packed_git(the_repository);
 			if (!find_pack_entry(real, &e))
 				return -1;
 		}
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 23/39] pack: add repository argument to sha1_file_name
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (21 preceding siblings ...)
  2017-08-30  7:06 ` [PATCH 22/39] pack: add repository argument to reprepare_packed_git Jonathan Nieder
@ 2017-08-30  7:06 ` Jonathan Nieder
  2017-08-30  7:07 ` [PATCH 24/39] pack: add repository argument to map_sha1_file Jonathan Nieder
                   ` (16 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:06 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow sha1_file_name callers to be more
specific about which repository to handle. This is a small mechanical
change; it doesn't change the implementation to handle repositories
other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

While at it, move the declaration to object-store.h, where it should
be easier to find.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 cache.h        |  8 --------
 http-walker.c  |  3 ++-
 http.c         |  5 +++--
 object-store.h |  9 +++++++++
 sha1_file.c    | 11 ++++++-----
 5 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/cache.h b/cache.h
index abec62dc9b..0d120b9327 100644
--- a/cache.h
+++ b/cache.h
@@ -895,14 +895,6 @@ extern void check_repository_format(void);
 #define DATA_CHANGED    0x0020
 #define TYPE_CHANGED    0x0040
 
-/*
- * Return the name of the file in the local object database that would
- * be used to store a loose object with the specified sha1.  The
- * return value is a pointer to a statically allocated buffer that is
- * overwritten each time the function is called.
- */
-extern const char *sha1_file_name(const unsigned char *sha1);
-
 /*
  * Return an abbreviated sha1 unique within this repository's object database.
  * The result will be at least `len` characters long, and will be NUL
diff --git a/http-walker.c b/http-walker.c
index a1c6f2639b..96873bdfed 100644
--- a/http-walker.c
+++ b/http-walker.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "repository.h"
 #include "commit.h"
 #include "walker.h"
 #include "http.h"
@@ -546,7 +547,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
 		ret = error("File %s has bad hash", hex);
 	} else if (req->rename < 0) {
 		ret = error("unable to write sha1 filename %s",
-			    sha1_file_name(req->sha1));
+			    sha1_file_name(the_repository, req->sha1));
 	}
 
 	release_http_object_request(req);
diff --git a/http.c b/http.c
index 0979053272..2c86e6e76e 100644
--- a/http.c
+++ b/http.c
@@ -2163,7 +2163,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
 	hashcpy(freq->sha1, sha1);
 	freq->localfile = -1;
 
-	filename = sha1_file_name(sha1);
+	filename = sha1_file_name(the_repository, sha1);
 	snprintf(freq->tmpfile, sizeof(freq->tmpfile),
 		 "%s.temp", filename);
 
@@ -2311,7 +2311,8 @@ int finish_http_object_request(struct http_object_request *freq)
 		return -1;
 	}
 	freq->rename =
-		finalize_object_file(freq->tmpfile, sha1_file_name(freq->sha1));
+		finalize_object_file(freq->tmpfile,
+				     sha1_file_name(the_repository, freq->sha1));
 
 	return freq->rename;
 }
diff --git a/object-store.h b/object-store.h
index eef8d3b653..228c2ce8ae 100644
--- a/object-store.h
+++ b/object-store.h
@@ -54,6 +54,15 @@ struct packed_git {
 	char pack_name[FLEX_ARRAY]; /* more */
 };
 
+/*
+ * Return the name of the file in a repository's local object database
+ * that would be used to store a loose object with the specified sha1.
+ * The return value is a pointer to a statically allocated buffer that
+ * is overwritten each time the function is called.
+ */
+#define sha1_file_name(r, s) sha1_file_name_##r(s)
+extern const char *sha1_file_name_the_repository(const unsigned char *sha1);
+
 #define prepare_alt_odb(r) prepare_alt_odb_##r()
 extern void prepare_alt_odb_the_repository(void);
 
diff --git a/sha1_file.c b/sha1_file.c
index 6af88e5b04..8ab26fb3b3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -253,7 +253,7 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
 	}
 }
 
-const char *sha1_file_name(const unsigned char *sha1)
+const char *sha1_file_name_the_repository(const unsigned char *sha1)
 {
 	static struct strbuf buf = STRBUF_INIT;
 
@@ -664,7 +664,8 @@ int check_and_freshen_file(const char *fn, int freshen)
 
 static int check_and_freshen_local(const unsigned char *sha1, int freshen)
 {
-	return check_and_freshen_file(sha1_file_name(sha1), freshen);
+	return check_and_freshen_file(sha1_file_name(the_repository, sha1),
+				      freshen);
 }
 
 static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
@@ -822,7 +823,7 @@ static int stat_sha1_file_the_repository(const unsigned char *sha1,
 {
 	struct alternate_object_database *alt;
 
-	*path = sha1_file_name(sha1);
+	*path = sha1_file_name(the_repository, sha1);
 	if (!lstat(*path, st))
 		return 0;
 
@@ -849,7 +850,7 @@ static int open_sha1_file_the_repository(const unsigned char *sha1,
 	struct alternate_object_database *alt;
 	int most_interesting_errno;
 
-	*path = sha1_file_name(sha1);
+	*path = sha1_file_name(the_repository, sha1);
 	fd = git_open(*path);
 	if (fd >= 0)
 		return fd;
@@ -1509,7 +1510,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
 	git_SHA_CTX c;
 	unsigned char parano_sha1[20];
 	static struct strbuf tmp_file = STRBUF_INIT;
-	const char *filename = sha1_file_name(sha1);
+	const char *filename = sha1_file_name(the_repository, sha1);
 
 	fd = create_tmpfile(&tmp_file, filename);
 	if (fd < 0) {
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 24/39] pack: add repository argument to map_sha1_file
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (22 preceding siblings ...)
  2017-08-30  7:06 ` [PATCH 23/39] pack: add repository argument to sha1_file_name Jonathan Nieder
@ 2017-08-30  7:07 ` Jonathan Nieder
  2017-08-30  7:08 ` [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories Jonathan Nieder
                   ` (15 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:07 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Add a repository argument to allow map_sha1_file callers to be more
specific about which repository to handle. This is a small mechanical
change; it doesn't change the implementation to handle repositories
other than the_repository yet.

As with the previous commits, use a macro to catch callers passing a
repository other than the_repository at compile time.

While at it, move the declaration to object-store.h, where it should
be easier to find.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 cache.h        | 1 -
 object-store.h | 2 ++
 sha1_file.c    | 4 ++--
 streaming.c    | 5 ++++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/cache.h b/cache.h
index 0d120b9327..454cfb50c4 100644
--- a/cache.h
+++ b/cache.h
@@ -1176,7 +1176,6 @@ extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned c
 extern int force_object_loose(const unsigned char *sha1, time_t mtime);
 extern int git_open_cloexec(const char *name, int flags);
 #define git_open(name) git_open_cloexec(name, O_RDONLY)
-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
 extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
 extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
 
diff --git a/object-store.h b/object-store.h
index 228c2ce8ae..92fbf4a9ca 100644
--- a/object-store.h
+++ b/object-store.h
@@ -62,6 +62,8 @@ struct packed_git {
  */
 #define sha1_file_name(r, s) sha1_file_name_##r(s)
 extern const char *sha1_file_name_the_repository(const unsigned char *sha1);
+#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)
+extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);
 
 #define prepare_alt_odb(r) prepare_alt_odb_##r()
 extern void prepare_alt_odb_the_repository(void);
diff --git a/sha1_file.c b/sha1_file.c
index 8ab26fb3b3..e7c86e5363 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -903,7 +903,7 @@ static void *map_sha1_file_1_the_repository(const char *path,
 	return map;
 }
 
-void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
+void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size)
 {
 	return map_sha1_file_1(the_repository, NULL, sha1, size);
 }
@@ -1128,7 +1128,7 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1,
 		return 0;
 	}
 
-	map = map_sha1_file(sha1, &mapsize);
+	map = map_sha1_file(the_repository, sha1, &mapsize);
 	if (!map)
 		return -1;
 
diff --git a/streaming.c b/streaming.c
index 6f1c60f12b..86808a6d99 100644
--- a/streaming.c
+++ b/streaming.c
@@ -3,6 +3,8 @@
  */
 #include "cache.h"
 #include "streaming.h"
+#include "repository.h"
+#include "object-store.h"
 #include "packfile.h"
 
 enum input_source {
@@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = {
 
 static open_method_decl(loose)
 {
-	st->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);
+	st->u.loose.mapped = map_sha1_file(the_repository,
+					   sha1, &st->u.loose.mapsize);
 	if (!st->u.loose.mapped)
 		return -1;
 	if ((unpack_sha1_header(&st->z,
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (23 preceding siblings ...)
  2017-08-30  7:07 ` [PATCH 24/39] pack: add repository argument to map_sha1_file Jonathan Nieder
@ 2017-08-30  7:08 ` Jonathan Nieder
  2017-09-06 20:01   ` Junio C Hamano
  2017-08-30  7:10 ` [PATCH 26/39] object-store: allow prepare_alt_odb " Jonathan Nieder
                   ` (14 subsequent siblings)
  39 siblings, 1 reply; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:08 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 sha1_file.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index e7c86e5363..b854cad970 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -25,6 +25,7 @@
 #include "repository.h"
 #include "object-store.h"
 #include "streaming.h"
+#include "path.h"
 #include "dir.h"
 #include "mru.h"
 #include "list.h"
@@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
 /*
  * Return non-zero iff the path is usable as an alternate object database.
  */
-#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)
-static int alt_odb_usable_the_repository(struct strbuf *path,
-					 const char *normalized_objdir)
+static int alt_odb_usable(struct repository *r, struct strbuf *path,
+			  const char *normalized_objdir)
 {
 	struct alternate_object_database *alt;
 
 	/* Detect cases where alternate disappeared */
 	if (!is_directory(path->buf)) {
-		error("object directory %s does not exist; "
-		      "check .git/objects/info/alternates.",
-		      path->buf);
+		struct strbuf sb = STRBUF_INIT;
+		strbuf_repo_git_path(&sb, r, "objects/info/alternates");
+		error("object directory %s does not exist; check %s",
+		      path->buf, sb.buf);
+		strbuf_release(&sb);
 		return 0;
 	}
 
@@ -299,7 +301,7 @@ static int alt_odb_usable_the_repository(struct strbuf *path,
 	 * Prevent the common mistake of listing the same
 	 * thing twice, or object directory itself.
 	 */
-	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
+	for (alt = r->objects.alt_odb_list; alt; alt = alt->next) {
 		if (!fspathcmp(path->buf, alt->path))
 			return 0;
 	}
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 26/39] object-store: allow prepare_alt_odb to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (24 preceding siblings ...)
  2017-08-30  7:08 ` [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories Jonathan Nieder
@ 2017-08-30  7:10 ` Jonathan Nieder
  2017-08-30  7:11 ` [PATCH 27/39] object-store: allow foreach_alt_odb " Jonathan Nieder
                   ` (13 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:10 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 cache.h        |  4 ++++
 object-store.h |  3 +--
 sha1_file.c    | 65 ++++++++++++++++++++++++++++++----------------------------
 3 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/cache.h b/cache.h
index 454cfb50c4..d204048d3d 100644
--- a/cache.h
+++ b/cache.h
@@ -1512,6 +1512,10 @@ struct alternate_object_database {
 	char loose_objects_subdir_seen[256];
 	struct oid_array loose_objects_cache;
 
+	/*
+	 * Path to the alternate object database, relative to the
+	 * current working directory.
+	 */
 	char path[FLEX_ARRAY];
 };
 extern char *compute_alternate_path(const char *path, struct strbuf *err);
diff --git a/object-store.h b/object-store.h
index 92fbf4a9ca..fcf36c7370 100644
--- a/object-store.h
+++ b/object-store.h
@@ -65,8 +65,7 @@ extern const char *sha1_file_name_the_repository(const unsigned char *sha1);
 #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)
 extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);
 
-#define prepare_alt_odb(r) prepare_alt_odb_##r()
-extern void prepare_alt_odb_the_repository(void);
+extern void prepare_alt_odb(struct repository *r);
 
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
 #define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)
diff --git a/sha1_file.c b/sha1_file.c
index b854cad970..452c8f0bbd 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -326,11 +326,10 @@ static int alt_odb_usable(struct repository *r, struct strbuf *path,
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-#define read_info_alternates(r, rb, d) read_info_alternates_##r(rb, d)
-static void read_info_alternates_the_repository(const char *relative_base,
-						int depth);
-#define link_alt_odb_entry(r, e, rb, d, n) link_alt_odb_entry_##r(e, rb, d, n)
-static int link_alt_odb_entry_the_repository(const char *entry,
+static void read_info_alternates(struct repository *r,
+				 const char *relative_base,
+				 int depth);
+static int link_alt_odb_entry(struct repository *r, const char *entry,
 	const char *relative_base, int depth, const char *normalized_objdir)
 {
 	struct alternate_object_database *ent;
@@ -356,7 +355,7 @@ static int link_alt_odb_entry_the_repository(const char *entry,
 	while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
 		strbuf_setlen(&pathbuf, pathbuf.len - 1);
 
-	if (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {
+	if (!alt_odb_usable(r, &pathbuf, normalized_objdir)) {
 		strbuf_release(&pathbuf);
 		return -1;
 	}
@@ -364,12 +363,12 @@ static int link_alt_odb_entry_the_repository(const char *entry,
 	ent = alloc_alt_odb(pathbuf.buf);
 
 	/* add the alternate entry */
-	*the_repository->objects.alt_odb_tail = ent;
-	the_repository->objects.alt_odb_tail = &(ent->next);
+	*r->objects.alt_odb_tail = ent;
+	r->objects.alt_odb_tail = &(ent->next);
 	ent->next = NULL;
 
 	/* recursively add alternates */
-	read_info_alternates(the_repository, pathbuf.buf, depth + 1);
+	read_info_alternates(r, pathbuf.buf, depth + 1);
 
 	strbuf_release(&pathbuf);
 	return 0;
@@ -404,12 +403,8 @@ static const char *parse_alt_odb_entry(const char *string,
 	return end;
 }
 
-#define link_alt_odb_entries(r, a, l, s, rb, d) \
-	link_alt_odb_entries_##r(a, l, s, rb, d)
-static void link_alt_odb_entries_the_repository(const char *alt, int len,
-						int sep,
-						const char *relative_base,
-						int depth)
+static void link_alt_odb_entries(struct repository *r, const char *alt, int len,
+				 int sep, const char *relative_base, int depth)
 {
 	struct strbuf objdirbuf = STRBUF_INIT;
 	struct strbuf entry = STRBUF_INIT;
@@ -420,7 +415,7 @@ static void link_alt_odb_entries_the_repository(const char *alt, int len,
 		return;
 	}
 
-	strbuf_add_absolute_path(&objdirbuf, get_object_directory());
+	strbuf_add_absolute_path(&objdirbuf, r->objectdir);
 	if (strbuf_normalize_path(&objdirbuf) < 0)
 		die("unable to normalize object directory: %s",
 		    objdirbuf.buf);
@@ -429,15 +424,16 @@ static void link_alt_odb_entries_the_repository(const char *alt, int len,
 		alt = parse_alt_odb_entry(alt, sep, &entry);
 		if (!entry.len)
 			continue;
-		link_alt_odb_entry(the_repository, entry.buf,
+		link_alt_odb_entry(r, entry.buf,
 				   relative_base, depth, objdirbuf.buf);
 	}
 	strbuf_release(&entry);
 	strbuf_release(&objdirbuf);
 }
 
-static void read_info_alternates_the_repository(const char *relative_base,
-						int depth)
+static void read_info_alternates(struct repository *r,
+				 const char *relative_base,
+				 int depth)
 {
 	char *map;
 	size_t mapsz;
@@ -458,7 +454,7 @@ static void read_info_alternates_the_repository(const char *relative_base,
 	map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
 	close(fd);
 
-	link_alt_odb_entries(the_repository, map, mapsz, '\n', relative_base, depth);
+	link_alt_odb_entries(r, map, mapsz, '\n', relative_base, depth);
 
 	munmap(map, mapsz);
 }
@@ -622,22 +618,29 @@ int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)
 	return r;
 }
 
-void prepare_alt_odb_the_repository(void)
+void prepare_alt_odb(struct repository *r)
 {
-	const char *alt;
-
-	if (the_repository->objects.alt_odb_tail)
+	if (r->objects.alt_odb_tail)
 		return;
 
+	r->objects.alt_odb_tail = &r->objects.alt_odb_list;
+
-	alt = getenv(ALTERNATE_DB_ENVIRONMENT);
-	if (!alt) alt = "";
-
-	the_repository->objects.alt_odb_tail =
-			&the_repository->objects.alt_odb_list;
-	link_alt_odb_entries(the_repository, alt, strlen(alt),
-			     PATH_SEP, NULL, 0);
+	if (!r->ignore_env) {
+		const char *alt = getenv(ALTERNATE_DB_ENVIRONMENT);
+		if (!alt)
+			alt = "";
+
+		/*
+		 * Paths in alt are relative to the cwd. We ignore environment
+		 * settings like this for all repositories except for
+		 * the_repository, so we don't have to worry about transforming
+		 * the path to be relative to another repository.
+		 */
+		link_alt_odb_entries(r, alt, strlen(alt),
+				     PATH_SEP, NULL, 0);
+	}
 
-	read_info_alternates(the_repository, get_object_directory(), 0);
+	read_info_alternates(r, r->objectdir, 0);
 }
 
 /* Returns 1 if we have successfully freshened the file, 0 otherwise. */
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 27/39] object-store: allow foreach_alt_odb to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (25 preceding siblings ...)
  2017-08-30  7:10 ` [PATCH 26/39] object-store: allow prepare_alt_odb " Jonathan Nieder
@ 2017-08-30  7:11 ` Jonathan Nieder
  2017-08-30  7:11 ` [PATCH 28/39] pack: allow install_packed_git " Jonathan Nieder
                   ` (12 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:11 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

From: Stefan Beller <sbeller@google.com>

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 object-store.h |  3 +--
 sha1_file.c    | 14 +++++++-------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/object-store.h b/object-store.h
index fcf36c7370..518da80367 100644
--- a/object-store.h
+++ b/object-store.h
@@ -68,7 +68,6 @@ extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned lo
 extern void prepare_alt_odb(struct repository *r);
 
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
-#define foreach_alt_odb(r, fn, cb) foreach_alt_odb_##r(fn, cb)
-extern int foreach_alt_odb_the_repository(alt_odb_fn, void*);
+extern int foreach_alt_odb(struct repository *r, alt_odb_fn, void*);
 
 #endif /* OBJECT_STORE_H */
diff --git a/sha1_file.c b/sha1_file.c
index 452c8f0bbd..81bc1ab309 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -604,18 +604,18 @@ char *compute_alternate_path(const char *path, struct strbuf *err)
 	return ref_git;
 }
 
-int foreach_alt_odb_the_repository(alt_odb_fn fn, void *cb)
+int foreach_alt_odb(struct repository *r, alt_odb_fn fn, void *cb)
 {
 	struct alternate_object_database *ent;
-	int r = 0;
+	int ret = 0;
 
-	prepare_alt_odb(the_repository);
-	for (ent = the_repository->objects.alt_odb_list; ent; ent = ent->next) {
-		r = fn(ent, cb);
-		if (r)
+	prepare_alt_odb(r);
+	for (ent = r->objects.alt_odb_list; ent; ent = ent->next) {
+		ret = fn(ent, cb);
+		if (ret)
 			break;
 	}
-	return r;
+	return ret;
 }
 
 void prepare_alt_odb(struct repository *r)
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 28/39] pack: allow install_packed_git to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (26 preceding siblings ...)
  2017-08-30  7:11 ` [PATCH 27/39] object-store: allow foreach_alt_odb " Jonathan Nieder
@ 2017-08-30  7:11 ` Jonathan Nieder
  2017-08-30  7:12 ` [PATCH 29/39] pack: allow rearrange_packed_git " Jonathan Nieder
                   ` (11 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:11 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 6 +++---
 packfile.h | 3 +--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/packfile.c b/packfile.c
index 86c3964018..51af035965 100644
--- a/packfile.c
+++ b/packfile.c
@@ -664,13 +664,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
 	return p;
 }
 
-void install_packed_git_the_repository(struct packed_git *pack)
+void install_packed_git(struct repository *r, struct packed_git *pack)
 {
 	if (pack->pack_fd != -1)
 		pack_open_fds++;
 
-	pack->next = the_repository->objects.packed_git;
-	the_repository->objects.packed_git = pack;
+	pack->next = r->objects.packed_git;
+	r->objects.packed_git = pack;
 }
 
 void (*report_garbage)(unsigned seen_bits, const char *path);
diff --git a/packfile.h b/packfile.h
index 74f293c439..ba6f08be99 100644
--- a/packfile.h
+++ b/packfile.h
@@ -36,8 +36,7 @@ extern void (*report_garbage)(unsigned seen_bits, const char *path);
 extern void prepare_packed_git_the_repository(void);
 #define reprepare_packed_git(r) reprepare_packed_git_##r()
 extern void reprepare_packed_git_the_repository(void);
-#define install_packed_git(r, p) install_packed_git_##r(p)
-extern void install_packed_git_the_repository(struct packed_git *pack);
+extern void install_packed_git(struct repository *r, struct packed_git *pack);
 
 /*
  * Give a rough count of objects in the repository. This sacrifices accuracy
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 29/39] pack: allow rearrange_packed_git to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (27 preceding siblings ...)
  2017-08-30  7:11 ` [PATCH 28/39] pack: allow install_packed_git " Jonathan Nieder
@ 2017-08-30  7:12 ` Jonathan Nieder
  2017-08-30  7:12 ` [PATCH 30/39] pack: allow prepare_packed_git_mru " Jonathan Nieder
                   ` (10 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:12 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/packfile.c b/packfile.c
index 51af035965..977e714d9a 100644
--- a/packfile.c
+++ b/packfile.c
@@ -850,11 +850,10 @@ static int sort_pack(const void *a_, const void *b_)
 	return -1;
 }
 
-#define rearrange_packed_git(r) rearrange_packed_git_##r()
-static void rearrange_packed_git_the_repository(void)
+static void rearrange_packed_git(struct repository *r)
 {
-	the_repository->objects.packed_git = llist_mergesort(
-		the_repository->objects.packed_git, get_next_packed_git,
+	r->objects.packed_git = llist_mergesort(
+		r->objects.packed_git, get_next_packed_git,
 		set_next_packed_git, sort_pack);
 }
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 30/39] pack: allow prepare_packed_git_mru to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (28 preceding siblings ...)
  2017-08-30  7:12 ` [PATCH 29/39] pack: allow rearrange_packed_git " Jonathan Nieder
@ 2017-08-30  7:12 ` Jonathan Nieder
  2017-08-30  7:13 ` [PATCH 31/39] pack: allow prepare_packed_git_one " Jonathan Nieder
                   ` (9 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:12 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/packfile.c b/packfile.c
index 977e714d9a..9bb93ce256 100644
--- a/packfile.c
+++ b/packfile.c
@@ -857,14 +857,13 @@ static void rearrange_packed_git(struct repository *r)
 		set_next_packed_git, sort_pack);
 }
 
-#define prepare_packed_git_mru(r) prepare_packed_git_mru_##r()
-static void prepare_packed_git_mru_the_repository(void)
+static void prepare_packed_git_mru(struct repository *r)
 {
 	struct packed_git *p;
 
-	mru_clear(&the_repository->objects.packed_git_mru);
-	for (p = the_repository->objects.packed_git; p; p = p->next)
-		mru_append(&the_repository->objects.packed_git_mru, p);
+	mru_clear(&r->objects.packed_git_mru);
+	for (p = r->objects.packed_git; p; p = p->next)
+		mru_append(&r->objects.packed_git_mru, p);
 }
 
 void prepare_packed_git_the_repository(void)
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 31/39] pack: allow prepare_packed_git_one to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (29 preceding siblings ...)
  2017-08-30  7:12 ` [PATCH 30/39] pack: allow prepare_packed_git_mru " Jonathan Nieder
@ 2017-08-30  7:13 ` Jonathan Nieder
  2017-08-30  7:13 ` [PATCH 32/39] pack: allow prepare_packed_git " Jonathan Nieder
                   ` (8 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:13 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/packfile.c b/packfile.c
index 9bb93ce256..4652be0b6e 100644
--- a/packfile.c
+++ b/packfile.c
@@ -719,8 +719,8 @@ static void report_pack_garbage(struct string_list *list)
 	report_helper(list, seen_bits, first, list->nr);
 }
 
-#define prepare_packed_git_one(r, o, l) prepare_packed_git_one_##r(o, l)
-static void prepare_packed_git_one_the_repository(char *objdir, int local)
+static void prepare_packed_git_one(struct repository *r,
+				   char *objdir, int local)
 {
 	struct strbuf path = STRBUF_INIT;
 	size_t dirnamelen;
@@ -753,8 +753,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local)
 		base_len = path.len;
 		if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
 			/* Don't reopen a pack we already have. */
-			for (p = the_repository->objects.packed_git; p;
-			     p = p->next) {
+			for (p = r->objects.packed_git; p; p = p->next) {
 				size_t len;
 				if (strip_suffix(p->pack_name, ".pack", &len) &&
 				    len == base_len &&
@@ -767,7 +766,7 @@ static void prepare_packed_git_one_the_repository(char *objdir, int local)
 			     * corresponding .pack file that we can map.
 			     */
 			    (p = add_packed_git(path.buf, path.len, local)) != NULL)
-				install_packed_git(the_repository, p);
+				install_packed_git(r, p);
 		}
 
 		if (!report_garbage)
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 32/39] pack: allow prepare_packed_git to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (30 preceding siblings ...)
  2017-08-30  7:13 ` [PATCH 31/39] pack: allow prepare_packed_git_one " Jonathan Nieder
@ 2017-08-30  7:13 ` Jonathan Nieder
  2017-08-30  7:14 ` [PATCH 33/39] pack: allow reprepare_packed_git " Jonathan Nieder
                   ` (7 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:13 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 18 +++++++++---------
 packfile.h |  3 +--
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/packfile.c b/packfile.c
index 4652be0b6e..23a835f7fb 100644
--- a/packfile.c
+++ b/packfile.c
@@ -865,19 +865,19 @@ static void prepare_packed_git_mru(struct repository *r)
 		mru_append(&r->objects.packed_git_mru, p);
 }
 
-void prepare_packed_git_the_repository(void)
+void prepare_packed_git(struct repository *r)
 {
 	struct alternate_object_database *alt;
 
-	if (the_repository->objects.packed_git_initialized)
+	if (r->objects.packed_git_initialized)
 		return;
-	prepare_packed_git_one(the_repository, get_object_directory(), 1);
-	prepare_alt_odb(the_repository);
-	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next)
-		prepare_packed_git_one(the_repository, alt->path, 0);
-	rearrange_packed_git(the_repository);
-	prepare_packed_git_mru(the_repository);
-	the_repository->objects.packed_git_initialized = 1;
+	prepare_packed_git_one(r, r->objectdir, 1);
+	prepare_alt_odb(r);
+	for (alt = r->objects.alt_odb_list; alt; alt = alt->next)
+		prepare_packed_git_one(r, alt->path, 0);
+	rearrange_packed_git(r);
+	prepare_packed_git_mru(r);
+	r->objects.packed_git_initialized = 1;
 }
 
 void reprepare_packed_git_the_repository(void)
diff --git a/packfile.h b/packfile.h
index ba6f08be99..75be3cb877 100644
--- a/packfile.h
+++ b/packfile.h
@@ -32,8 +32,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
 #define PACKDIR_FILE_GARBAGE 4
 extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
-#define prepare_packed_git(r) prepare_packed_git_##r()
-extern void prepare_packed_git_the_repository(void);
+extern void prepare_packed_git(struct repository *r);
 #define reprepare_packed_git(r) reprepare_packed_git_##r()
 extern void reprepare_packed_git_the_repository(void);
 extern void install_packed_git(struct repository *r, struct packed_git *pack);
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 33/39] pack: allow reprepare_packed_git to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (31 preceding siblings ...)
  2017-08-30  7:13 ` [PATCH 32/39] pack: allow prepare_packed_git " Jonathan Nieder
@ 2017-08-30  7:14 ` Jonathan Nieder
  2017-08-30  7:14 ` [PATCH 34/39] pack: allow sha1_file_name " Jonathan Nieder
                   ` (6 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:14 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 packfile.c | 8 ++++----
 packfile.h | 3 +--
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/packfile.c b/packfile.c
index 23a835f7fb..67274d01fd 100644
--- a/packfile.c
+++ b/packfile.c
@@ -880,11 +880,11 @@ void prepare_packed_git(struct repository *r)
 	r->objects.packed_git_initialized = 1;
 }
 
-void reprepare_packed_git_the_repository(void)
+void reprepare_packed_git(struct repository *r)
 {
-	the_repository->objects.approximate_object_count_valid = 0;
-	the_repository->objects.packed_git_initialized = 0;
-	prepare_packed_git(the_repository);
+	r->objects.approximate_object_count_valid = 0;
+	r->objects.packed_git_initialized = 0;
+	prepare_packed_git(r);
 }
 
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
diff --git a/packfile.h b/packfile.h
index 75be3cb877..b3138816e7 100644
--- a/packfile.h
+++ b/packfile.h
@@ -33,8 +33,7 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
 extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
 extern void prepare_packed_git(struct repository *r);
-#define reprepare_packed_git(r) reprepare_packed_git_##r()
-extern void reprepare_packed_git_the_repository(void);
+extern void reprepare_packed_git(struct repository *r);
 extern void install_packed_git(struct repository *r, struct packed_git *pack);
 
 /*
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 34/39] pack: allow sha1_file_name to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (32 preceding siblings ...)
  2017-08-30  7:14 ` [PATCH 33/39] pack: allow reprepare_packed_git " Jonathan Nieder
@ 2017-08-30  7:14 ` Jonathan Nieder
  2017-08-30  7:15 ` [PATCH 35/39] pack: allow stat_sha1_file " Jonathan Nieder
                   ` (5 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:14 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 object-store.h | 3 +--
 sha1_file.c    | 4 ++--
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/object-store.h b/object-store.h
index 518da80367..fe2187fd65 100644
--- a/object-store.h
+++ b/object-store.h
@@ -60,8 +60,7 @@ struct packed_git {
  * The return value is a pointer to a statically allocated buffer that
  * is overwritten each time the function is called.
  */
-#define sha1_file_name(r, s) sha1_file_name_##r(s)
-extern const char *sha1_file_name_the_repository(const unsigned char *sha1);
+extern const char *sha1_file_name(struct repository *r, const unsigned char *sha1);
 #define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)
 extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);
 
diff --git a/sha1_file.c b/sha1_file.c
index 81bc1ab309..ac57eea0f2 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -254,12 +254,12 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
 	}
 }
 
-const char *sha1_file_name_the_repository(const unsigned char *sha1)
+const char *sha1_file_name(struct repository *r, const unsigned char *sha1)
 {
 	static struct strbuf buf = STRBUF_INIT;
 
 	strbuf_reset(&buf);
-	strbuf_addf(&buf, "%s/", get_object_directory());
+	strbuf_addf(&buf, "%s/", r->objectdir);
 
 	fill_sha1_path(&buf, sha1);
 	return buf.buf;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 35/39] pack: allow stat_sha1_file to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (33 preceding siblings ...)
  2017-08-30  7:14 ` [PATCH 34/39] pack: allow sha1_file_name " Jonathan Nieder
@ 2017-08-30  7:15 ` Jonathan Nieder
  2017-08-30  7:16 ` [PATCH 36/39] pack: allow open_sha1_file " Jonathan Nieder
                   ` (4 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:15 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index ac57eea0f2..282ed7bd1b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -822,19 +822,18 @@ int git_open_cloexec(const char *name, int flags)
  * Note that it may point to static storage and is only valid until another
  * call to sha1_file_name(), etc.
  */
-#define stat_sha1_file(r, s, st, p) stat_sha1_file_##r(s, st, p)
-static int stat_sha1_file_the_repository(const unsigned char *sha1,
-					 struct stat *st, const char **path)
+static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
+			  struct stat *st, const char **path)
 {
 	struct alternate_object_database *alt;
 
-	*path = sha1_file_name(the_repository, sha1);
+	*path = sha1_file_name(r, sha1);
 	if (!lstat(*path, st))
 		return 0;
 
-	prepare_alt_odb(the_repository);
+	prepare_alt_odb(r);
 	errno = ENOENT;
-	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
+	for (alt = r->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
 		if (!lstat(*path, st))
 			return 0;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 36/39] pack: allow open_sha1_file to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (34 preceding siblings ...)
  2017-08-30  7:15 ` [PATCH 35/39] pack: allow stat_sha1_file " Jonathan Nieder
@ 2017-08-30  7:16 ` Jonathan Nieder
  2017-08-30  7:16 ` [PATCH 37/39] pack: allow map_sha1_file_1 " Jonathan Nieder
                   ` (3 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:16 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 282ed7bd1b..930705f59b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -846,22 +846,21 @@ static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
  * Like stat_sha1_file(), but actually open the object and return the
  * descriptor. See the caveats on the "path" parameter above.
  */
-#define open_sha1_file(r, s, p) open_sha1_file_##r(s, p)
-static int open_sha1_file_the_repository(const unsigned char *sha1,
-					 const char **path)
+static int open_sha1_file(struct repository *r,
+			  const unsigned char *sha1, const char **path)
 {
 	int fd;
 	struct alternate_object_database *alt;
 	int most_interesting_errno;
 
-	*path = sha1_file_name(the_repository, sha1);
+	*path = sha1_file_name(r, sha1);
 	fd = git_open(*path);
 	if (fd >= 0)
 		return fd;
 	most_interesting_errno = errno;
 
-	prepare_alt_odb(the_repository);
-	for (alt = the_repository->objects.alt_odb_list; alt; alt = alt->next) {
+	prepare_alt_odb(r);
+	for (alt = r->objects.alt_odb_list; alt; alt = alt->next) {
 		*path = alt_sha1_path(alt, sha1);
 		fd = git_open(*path);
 		if (fd >= 0)
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 37/39] pack: allow map_sha1_file_1 to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (35 preceding siblings ...)
  2017-08-30  7:16 ` [PATCH 36/39] pack: allow open_sha1_file " Jonathan Nieder
@ 2017-08-30  7:16 ` Jonathan Nieder
  2017-08-30  7:16 ` [PATCH 38/39] pack: allow map_sha1_file " Jonathan Nieder
                   ` (2 subsequent siblings)
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:16 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 sha1_file.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index 930705f59b..7fc5ebf2af 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -876,10 +876,8 @@ static int open_sha1_file(struct repository *r,
  * Map the loose object at "path" if it is not NULL, or the path found by
  * searching for a loose object named "sha1".
  */
-#define map_sha1_file_1(r, p, s, si) map_sha1_file_1_##r(p, s, si)
-static void *map_sha1_file_1_the_repository(const char *path,
-					    const unsigned char *sha1,
-					    unsigned long *size)
+static void *map_sha1_file_1(struct repository *r, const char *path,
+			     const unsigned char *sha1, unsigned long *size)
 {
 	void *map;
 	int fd;
@@ -887,7 +885,7 @@ static void *map_sha1_file_1_the_repository(const char *path,
 	if (path)
 		fd = git_open(path);
 	else
-		fd = open_sha1_file(the_repository, sha1, &path);
+		fd = open_sha1_file(r, sha1, &path);
 	map = NULL;
 	if (fd >= 0) {
 		struct stat st;
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 38/39] pack: allow map_sha1_file to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (36 preceding siblings ...)
  2017-08-30  7:16 ` [PATCH 37/39] pack: allow map_sha1_file_1 " Jonathan Nieder
@ 2017-08-30  7:16 ` Jonathan Nieder
  2017-08-30  7:18 ` [PATCH 39/39] pack: allow sha1_loose_object_info " Jonathan Nieder
  2017-08-30 23:07 ` [PATCH 00/39] per-repository object store, part 1 Brandon Williams
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:16 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 object-store.h | 3 +--
 sha1_file.c    | 5 +++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/object-store.h b/object-store.h
index fe2187fd65..57b8d89738 100644
--- a/object-store.h
+++ b/object-store.h
@@ -61,8 +61,7 @@ struct packed_git {
  * is overwritten each time the function is called.
  */
 extern const char *sha1_file_name(struct repository *r, const unsigned char *sha1);
-#define map_sha1_file(r, s, sz) map_sha1_file_##r(s, sz)
-extern void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size);
+extern void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
 
 extern void prepare_alt_odb(struct repository *r);
 
diff --git a/sha1_file.c b/sha1_file.c
index 7fc5ebf2af..dc3c0b07ea 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -904,9 +904,10 @@ static void *map_sha1_file_1(struct repository *r, const char *path,
 	return map;
 }
 
-void *map_sha1_file_the_repository(const unsigned char *sha1, unsigned long *size)
+void *map_sha1_file(struct repository *r,
+		    const unsigned char *sha1, unsigned long *size)
 {
-	return map_sha1_file_1(the_repository, NULL, sha1, size);
+	return map_sha1_file_1(r, NULL, sha1, size);
 }
 
 static int unpack_sha1_short_header(git_zstream *stream,
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 39/39] pack: allow sha1_loose_object_info to handle arbitrary repositories
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (37 preceding siblings ...)
  2017-08-30  7:16 ` [PATCH 38/39] pack: allow map_sha1_file " Jonathan Nieder
@ 2017-08-30  7:18 ` Jonathan Nieder
  2017-08-30 23:07 ` [PATCH 00/39] per-repository object store, part 1 Brandon Williams
  39 siblings, 0 replies; 46+ messages in thread
From: Jonathan Nieder @ 2017-08-30  7:18 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller, brian m. carlson

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
That's the end of the series.  Thanks for reading.

 sha1_file.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/sha1_file.c b/sha1_file.c
index dc3c0b07ea..0f302a8c48 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1096,10 +1096,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
 	return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-#define sha1_loose_object_info(r, s, o, f) sha1_loose_object_info_##r(s, o, f)
-static int sha1_loose_object_info_the_repository(const unsigned char *sha1,
-						 struct object_info *oi,
-						 int flags)
+static int sha1_loose_object_info(struct repository *r,
+				  const unsigned char *sha1,
+				  struct object_info *oi, int flags)
 {
 	int status = 0;
 	unsigned long mapsize;
@@ -1123,14 +1122,14 @@ static int sha1_loose_object_info_the_repository(const unsigned char *sha1,
 	if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {
 		const char *path;
 		struct stat st;
-		if (stat_sha1_file(the_repository, sha1, &st, &path) < 0)
+		if (stat_sha1_file(r, sha1, &st, &path) < 0)
 			return -1;
 		if (oi->disk_sizep)
 			*oi->disk_sizep = st.st_size;
 		return 0;
 	}
 
-	map = map_sha1_file(the_repository, sha1, &mapsize);
+	map = map_sha1_file(r, sha1, &mapsize);
 	if (!map)
 		return -1;
 
-- 
2.14.1.581.gf28d330327


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer
  2017-08-30  6:48 ` [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer Jonathan Nieder
@ 2017-08-30 19:44   ` Jeff King
  2017-09-06 19:51     ` Junio C Hamano
  0 siblings, 1 reply; 46+ messages in thread
From: Jeff King @ 2017-08-30 19:44 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Stefan Beller, brian m. carlson

On Tue, Aug 29, 2017 at 11:48:27PM -0700, Jonathan Nieder wrote:

> The MRU cache that keeps track of recently used packs is represented
> using two global variables:
> 
> 	struct mru packed_git_mru_storage;
> 	struct mru *packed_git_mru = &packed_git_mru_storage;
> 
> Callers never assign to the packed_git_mru pointer, though, so we can
> simplify by eliminating it and using &packed_git_mru_storage (renamed
> to &packed_git_mru) directly.  This variable is only used by the
> packfile subsystem, making this a relatively uninvasive change (and
> any new unadapted callers would trigger a compile error).
> 
> Noticed while moving these globals to the object_store struct.

Sounds reasonable. I think I had originally wanted to hide the
implementation and make the MRU more opaque, hence exposing only the
pointer. But since I ended up just letting people directly walk over the
struct pointers to do iteration, it needs to expose the struct internals
anyway, and this layer of indirection isn't useful.

> ---
>  builtin/pack-objects.c |  4 ++--
>  cache.h                |  4 ++--
>  packfile.c             | 12 +++++-------
>  3 files changed, 9 insertions(+), 11 deletions(-)

The patch looks good to me.

As an aside, the mru code could probably be simplified a bit by reusing
the list implementation from list.h (both were added around the same
time, and it wasn't worth creating a dependency then, but I think list.h
is useful and here to stay at this point).

It's definitely not critical to put that into this already-large series,
though.  Maybe we can use Junio's #leftoverbits tag. :)

-Peff

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable
  2017-08-30  6:56 ` [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable Jonathan Nieder
@ 2017-08-30 22:40   ` Brandon Williams
  0 siblings, 0 replies; 46+ messages in thread
From: Brandon Williams @ 2017-08-30 22:40 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Stefan Beller, brian m. carlson

On 08/29, Jonathan Nieder wrote:
> From: Stefan Beller <sbeller@google.com>
> 
> Add a repository argument to allow the alt_odb_usable caller to be
> more specific about which repository to act on. This is a small
> mechanical change; it doesn't change the implementation to handle
> repositories other than the_repository yet.
> 
> Since the implementation does not yet work with other repositories,
> use a wrapper macro to enforce that the caller passes in
> the_repository as the first argument. It would be more appealing to
> use BUILD_ASSERT_OR_ZERO to enforce this, but that doesn't work
> because it requires a compile-time constant and common compilers like
> gcc 4.8.4 do not consider "r == the_repository" a compile-time
> constant.

Very clever trick :)

> 
> Signed-off-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
>  sha1_file.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/sha1_file.c b/sha1_file.c
> index 7c6ffd205a..1c757b44a3 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -280,7 +280,9 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
>  /*
>   * Return non-zero iff the path is usable as an alternate object database.
>   */
> -static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
> +#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)
> +static int alt_odb_usable_the_repository(struct strbuf *path,
> +					 const char *normalized_objdir)
>  {
>  	struct alternate_object_database *alt;
>  
> @@ -348,7 +350,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
>  	while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
>  		strbuf_setlen(&pathbuf, pathbuf.len - 1);
>  
> -	if (!alt_odb_usable(&pathbuf, normalized_objdir)) {
> +	if (!alt_odb_usable(the_repository, &pathbuf, normalized_objdir)) {
>  		strbuf_release(&pathbuf);
>  		return -1;
>  	}
> -- 
> 2.14.1.581.gf28d330327
> 

-- 
Brandon Williams

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 00/39] per-repository object store, part 1
  2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
                   ` (38 preceding siblings ...)
  2017-08-30  7:18 ` [PATCH 39/39] pack: allow sha1_loose_object_info " Jonathan Nieder
@ 2017-08-30 23:07 ` Brandon Williams
  39 siblings, 0 replies; 46+ messages in thread
From: Brandon Williams @ 2017-08-30 23:07 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Stefan Beller, brian m. carlson

On 08/29, Jonathan Nieder wrote:
> Hi,
> 
> Most of the credit for this series should go to Stefan Beller.  I just
> decided to pull the trigger on sending out what we have so far.
> 
> This series is about API.  It makes no functional change yet.
> 
> Today, when a git command wants to operate on some objects from another
> repository (e.g., a submodule), it has two choices:
> 
>  A. Use run_command to operate on that repository in a separate process.
> 
>  B. Use add_to_alternates_memory to pretend the repository is an
>     alternate.  This has a number of downsides.  Aside from aesthetics,
>     one particularly painful consequence is that as alternates
>     accumulate, the number of packs git has to check for objects
>     increases, which can cause significant slowdowns.
> 
> Brandon Williams's recent work to introduce "struct repository" points
> to a better way.  Encapsulating object access in struct repository
> would mean:
> 
>   i. The API for accessing objects in another repository becomes more
>      simple and familiar (instead of using the CLI or abusing alternates).
> 
>   ii. Operations on one repository do not interfere with another,
>       neither in semantics (e.g. replace objects do not work correctly
>       with the approach (B) above) nor performance (already described
>       above).
> 
>  iii. Resources associated with access to a repository could be freed
>       when done with that repo.
> 
>   iv. Thread-safe multiple readers to a single repository also become
>       straightforward, by using multiple repository objects for the same
>       repo.
> 
> This series is a small step in that direction.
> 
> At the end of this series, sha1_loose_object_info takes a repository
> argument and can be independently called for multiple repositories.
> Not incredibly useful on its own, but a future series will do the same
> for sha1_object_info, which will be enough to migrate a caller in
> submodule.c (which uses the object store for commit existence checks).
> 
> This series has a few phases:
> 
>  1. Patch 1 is a cleanup that made some of the later patches easier.
> 
>  2. Patches 2-6 create a struct object_store field inside struct
>     repository and move some globals to it.
> 
>  3. Patches 7-24 are mechanical changes that update some functions to
>     accept a repository argument. The only goal is to make the later
>     patches that teach these functions to actual handle a repository
>     other than the_repository easier to review.  The patches enforce
>     at compile time that no caller passes a repository other than
>     the_repository --- see patch 7 in particular for details on how
>     that works.
> 
>  4. Patches 25-39 update the implementations of those functions to
>     handle a repository other than the_repository.  This means the
>     safety check introduced in phase 3 goes away completely --- all
>     functions that gained a repository argument are safe to use with
>     a repository argument other than the_repository.
> 
> Patches 2-6 and 25-39 should be the most interesting to review.  I'd
> particularly appreciate if people can look over 25-39 carefully.  We
> were careful not to leave any calls to functions that assume they are
> operating on the_repository, but a triple-check is always welcome.
> 
> Thanks as well to brian m. carlson, who showed us how such a long and
> potentially tedius series can be made bearable for reviewers.
> 
> Thoughts of all kinds welcome, as always.

Just finished looking through the series.  Thanks for keeping each
commit very short and to the point, it made reviewing it much easier.  I
couldn't see anything wrong these transformations and I am very happy to
see this work getting done.

One thing that needs to be noted is that currently the object_store is
only really being used by the_repository so this series didn't need to
create any object_store_init() or object_store_clear() type functions.
So these types of functions will need to be added once submodules are
using their own object store, in their own struct repository.

> 
> Thanks,
> Jonathan Nieder (24):
>   pack: make packed_git_mru global a value instead of a pointer
>   object-store: move packed_git and packed_git_mru to object store
>     struct
>   pack: move prepare_packed_git_run_once to object store struct
>   pack: move approximate object count to object store struct
>   pack: add repository argument to install_packed_git
>   pack: add repository argument to prepare_packed_git_one
>   pack: add repository argument to rearrange_packed_git
>   pack: add repository argument to prepare_packed_git_mru
>   pack: add repository argument to prepare_packed_git
>   pack: add repository argument to reprepare_packed_git
>   pack: add repository argument to sha1_file_name
>   pack: add repository argument to map_sha1_file
>   pack: allow install_packed_git to handle arbitrary repositories
>   pack: allow rearrange_packed_git to handle arbitrary repositories
>   pack: allow prepare_packed_git_mru to handle arbitrary repositories
>   pack: allow prepare_packed_git_one to handle arbitrary repositories
>   pack: allow prepare_packed_git to handle arbitrary repositories
>   pack: allow reprepare_packed_git to handle arbitrary repositories
>   pack: allow sha1_file_name to handle arbitrary repositories
>   pack: allow stat_sha1_file to handle arbitrary repositories
>   pack: allow open_sha1_file to handle arbitrary repositories
>   pack: allow map_sha1_file_1 to handle arbitrary repositories
>   pack: allow map_sha1_file to handle arbitrary repositories
>   pack: allow sha1_loose_object_info to handle arbitrary repositories
> 
> Stefan Beller (15):
>   repository: introduce object store field
>   object-store: move alt_odb_list and alt_odb_tail to object store
>     struct
>   sha1_file: add repository argument to alt_odb_usable
>   sha1_file: add repository argument to link_alt_odb_entry
>   sha1_file: add repository argument to read_info_alternates
>   sha1_file: add repository argument to link_alt_odb_entries
>   sha1_file: add repository argument to stat_sha1_file
>   sha1_file: add repository argument to open_sha1_file
>   sha1_file: add repository argument to map_sha1_file_1
>   sha1_file: add repository argument to sha1_loose_object_info
>   object-store: add repository argument to prepare_alt_odb
>   object-store: add repository argument to foreach_alt_odb
>   sha1_file: allow alt_odb_usable to handle arbitrary repositories
>   object-store: allow prepare_alt_odb to handle arbitrary repositories
>   object-store: allow foreach_alt_odb to handle arbitrary repositories
> 
>  builtin/count-objects.c             |  10 ++-
>  builtin/fsck.c                      |  15 ++--
>  builtin/gc.c                        |   8 +-
>  builtin/index-pack.c                |   1 +
>  builtin/pack-objects.c              |  23 +++--
>  builtin/pack-redundant.c            |   8 +-
>  builtin/receive-pack.c              |   4 +-
>  builtin/submodule--helper.c         |   4 +-
>  bulk-checkin.c                      |   3 +-
>  cache.h                             |  50 ++---------
>  contrib/coccinelle/packed_git.cocci |  15 ++++
>  fast-import.c                       |  10 ++-
>  fetch-pack.c                        |   3 +-
>  http-backend.c                      |   8 +-
>  http-push.c                         |   1 +
>  http-walker.c                       |   4 +-
>  http.c                              |   9 +-
>  mru.h                               |   1 +
>  object-store.h                      |  71 ++++++++++++++++
>  pack-bitmap.c                       |   6 +-
>  pack-check.c                        |   1 +
>  pack-revindex.c                     |   1 +
>  packfile.c                          |  94 ++++++++++----------
>  packfile.h                          |   6 +-
>  reachable.c                         |   1 +
>  repository.c                        |   4 +-
>  repository.h                        |   7 ++
>  server-info.c                       |   8 +-
>  sha1_file.c                         | 165 ++++++++++++++++++++----------------
>  sha1_name.c                         |  11 ++-
>  streaming.c                         |   5 +-
>  transport.c                         |   4 +-
>  32 files changed, 344 insertions(+), 217 deletions(-)
>  create mode 100644 contrib/coccinelle/packed_git.cocci
>  create mode 100644 object-store.h
> 
> -- 
> 2.14.1.581.gf28d330327
> 

-- 
Brandon Williams

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer
  2017-08-30 19:44   ` Jeff King
@ 2017-09-06 19:51     ` Junio C Hamano
  0 siblings, 0 replies; 46+ messages in thread
From: Junio C Hamano @ 2017-09-06 19:51 UTC (permalink / raw)
  To: Jeff King; +Cc: Jonathan Nieder, git, Stefan Beller, brian m. carlson

Jeff King <peff@peff.net> writes:

> As an aside, the mru code could probably be simplified a bit by reusing
> the list implementation from list.h (both were added around the same
> time, and it wasn't worth creating a dependency then, but I think list.h
> is useful and here to stay at this point).
>
> It's definitely not critical to put that into this already-large series,
> though.  Maybe we can use Junio's #leftoverbits tag. :)

I had the same reaction while reading it; perhaps I should read the
responses from trusted reviewers first before reading the patches
myself ;-)

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories
  2017-08-30  7:08 ` [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories Jonathan Nieder
@ 2017-09-06 20:01   ` Junio C Hamano
  2017-09-06 21:59     ` Stefan Beller
  0 siblings, 1 reply; 46+ messages in thread
From: Junio C Hamano @ 2017-09-06 20:01 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git, Stefan Beller, brian m. carlson

Jonathan Nieder <jrnieder@gmail.com> writes:

> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  sha1_file.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/sha1_file.c b/sha1_file.c
> index e7c86e5363..b854cad970 100644
> --- a/sha1_file.c
> +++ b/sha1_file.c
> @@ -25,6 +25,7 @@
>  #include "repository.h"
>  #include "object-store.h"
>  #include "streaming.h"
> +#include "path.h"
>  #include "dir.h"
>  #include "mru.h"
>  #include "list.h"
> @@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
>  /*
>   * Return non-zero iff the path is usable as an alternate object database.
>   */
> -#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)
> -static int alt_odb_usable_the_repository(struct strbuf *path,
> -					 const char *normalized_objdir)
> +static int alt_odb_usable(struct repository *r, struct strbuf *path,
> +			  const char *normalized_objdir)

These token-pasting macros introduced in 07-24/39 were certainly
cute but they may be rather misleading and useless.  e.g. a natural
expectaion would be

	struct repository *r = &the_repository;
	prepare_alt_odb(r);

to work, but obviously it wouldn't.  And this step and later in
25-39/39 corrects them one by one.

I suspect that you used the token-pasting cuteness because you
thought that the callsite would not have to change in the later step
like 25/39 that removes the trick.  I also suspect that you thought
that it may be a good thing that prepare_alt_odb(r) does not work
immediately after 07/39, as the callee is not prepared.  But both of
these are misguided.

If you have two functions, A and B, that we want to update to
eventually take a "struct repository *" argument, and if A uses B in
its implementation, the endgame would be

	A(struct repository *r, ...)
	{
		...
		B(r, ...);
		...
	}

but with the ##r approach, the call to B in A in the initial
token-pasting phase would say B(the_repository, ...) so the call
will need to be changed in the step you update A's implementation to
take a caller-supplied respotory object anyway.  And the fact that a
function's first parameter is not the_repository (i.e. leaving B()'s
signature unchanged while it is not ready to take a repository) is
sufficient to mark that a function is not yet prepared to take a
caller-supplied repository object.

I found that this aspect of the structure of the series was somewhat
irritating in that (1) combining the earlier ##r thing with its fix
would have made the code that needs to be reviewed much cleaner, (2)
it wouldn't have made the patch that longer, and most importantly
(3) it is unclear why 24-7 != 39-25, i.e. it is hard to answer "is
there any ##r hack still remaining after this series?  if so why?"

The end-result of the whole series makes me think that it is going
in the right direction, though.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories
  2017-09-06 20:01   ` Junio C Hamano
@ 2017-09-06 21:59     ` Stefan Beller
  0 siblings, 0 replies; 46+ messages in thread
From: Stefan Beller @ 2017-09-06 21:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jonathan Nieder, git, brian m. carlson

On Wed, Sep 6, 2017 at 1:01 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
>> Signed-off-by: Stefan Beller <sbeller@google.com>
>> ---
>>  sha1_file.c | 16 +++++++++-------
>>  1 file changed, 9 insertions(+), 7 deletions(-)
>>
>> diff --git a/sha1_file.c b/sha1_file.c
>> index e7c86e5363..b854cad970 100644
>> --- a/sha1_file.c
>> +++ b/sha1_file.c
>> @@ -25,6 +25,7 @@
>>  #include "repository.h"
>>  #include "object-store.h"
>>  #include "streaming.h"
>> +#include "path.h"
>>  #include "dir.h"
>>  #include "mru.h"
>>  #include "list.h"
>> @@ -281,17 +282,18 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
>>  /*
>>   * Return non-zero iff the path is usable as an alternate object database.
>>   */
>> -#define alt_odb_usable(r, p, n) alt_odb_usable_##r(p, n)
>> -static int alt_odb_usable_the_repository(struct strbuf *path,
>> -                                      const char *normalized_objdir)
>> +static int alt_odb_usable(struct repository *r, struct strbuf *path,
>> +                       const char *normalized_objdir)
>
> These token-pasting macros introduced in 07-24/39 were certainly
> cute but they may be rather misleading and useless.  e.g. a natural
> expectaion would be
>
>         struct repository *r = &the_repository;
>         prepare_alt_odb(r);
>
> to work, but obviously it wouldn't.  And this step and later in
> 25-39/39 corrects them one by one.

Yes. The intent was to deliver patches that are easiest to review as
that is usually the crux with long series. To do that we came up with this
way:
* patches  07-24 can be reviewed easily by only looking at
   the textual replacement, no need to think about implications.
   It should be boring(in a good way) to review these.
* patches 25-39, that allow arbitrary repositories to be handled
   only need to be reviewed inside its function bounds, because
   each function call that takes a repository argument will be verified
   by the compiler, precisely because the above won't work!
   That way the reviewer can rely on the compile output
   that the conversion was done in the correct order and no
   small function was missed. All review attention can go into
   just looking at the one function that is converted in such a
   patch. no need to double check with other parts of the code.
   We discussed we'd send the patches 25-39 with --function-context.
   The follow ups will do so.

> I suspect that you used the token-pasting cuteness because you
> thought that the callsite would not have to change in the later step
> like 25/39 that removes the trick.

No. We did these two different phases to ease review specifically.

Note how the call site is the function itself, ( --function-context would
have been really neat here)


>  I also suspect that you thought
> that it may be a good thing that prepare_alt_odb(r) does not work
> immediately after 07/39, as the callee is not prepared.  But both of
> these are misguided.
>
> If you have two functions, A and B, that we want to update to
> eventually take a "struct repository *" argument, and if A uses B in
> its implementation, the endgame would be
>
>         A(struct repository *r, ...)
>         {
>                 ...
>                 B(r, ...);
>                 ...
>         }
>
> but with the ##r approach, the call to B in A in the initial
> token-pasting phase would say B(the_repository, ...) so the call
> will need to be changed in the step you update A's implementation to
> take a caller-supplied respotory object anyway.  And the fact that a
> function's first parameter is not the_repository (i.e. leaving B()'s
> signature unchanged while it is not ready to take a repository) is
> sufficient to mark that a function is not yet prepared to take a
> caller-supplied repository object.

The absence of a repository argument is not sufficient that a function
(or any function called by it) does not rely on some global state, which
needs to be put into the repository struct.

So when converting function A (above), the careful reviewer needs to
inspect B, C, D... if they touch global state. Using the current approach,
most functions (maybe just B and C here) would take a repository struct
already, and the compiler would yell if these were not ready for anything
except the_repository. So the reviewer only has to worry about D.

> I found that this aspect of the structure of the series was somewhat
> irritating in that (1) combining the earlier ##r thing with its fix
> would have made the code that needs to be reviewed much cleaner,

agreed.

> (2) it wouldn't have made the patch that longer,

but more complicated to review (and write actually; as it was easy
to reason about functions to be ready for conversion, not using
global state)

> and most importantly
> (3) it is unclear why 24-7 != 39-25, i.e. it is hard to answer "is
> there any ##r hack still remaining after this series?  if so why?"

Jonathan is currently OOO, but last week we continued developing this
series and ended up with ca. 90 patches in the series.

> The end-result of the whole series makes me think that it is going
> in the right direction, though.

We'll revisit if we can squash commits before sending out.

Thanks for the feedback,
Stefan

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2017-09-06 22:00 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-30  6:46 [PATCH 00/39] per-repository object store, part 1 Jonathan Nieder
2017-08-30  6:48 ` [PATCH 01/39] pack: make packed_git_mru global a value instead of a pointer Jonathan Nieder
2017-08-30 19:44   ` Jeff King
2017-09-06 19:51     ` Junio C Hamano
2017-08-30  6:52 ` [PATCH 02/39] repository: introduce object store field Jonathan Nieder
2017-08-30  6:53 ` [PATCH 03/39] object-store: move alt_odb_list and alt_odb_tail to object store Jonathan Nieder
2017-08-30  6:54 ` [PATCH 04/39] object-store: move packed_git and packed_git_mru " Jonathan Nieder
2017-08-30  6:54 ` [PATCH 05/39] pack: move prepare_packed_git_run_once " Jonathan Nieder
2017-08-30  6:55 ` [PATCH 06/39] pack: move approximate object count " Jonathan Nieder
2017-08-30  6:56 ` [PATCH 07/39] sha1_file: add repository argument to alt_odb_usable Jonathan Nieder
2017-08-30 22:40   ` Brandon Williams
2017-08-30  6:57 ` [PATCH 08/39] sha1_file: add repository argument to link_alt_odb_entry Jonathan Nieder
2017-08-30  6:58 ` [PATCH 09/39] sha1_file: add repository argument to read_info_alternates Jonathan Nieder
2017-08-30  6:58 ` [PATCH 10/39] sha1_file: add repository argument to link_alt_odb_entries Jonathan Nieder
2017-08-30  6:59 ` [PATCH 11/39] sha1_file: add repository argument to stat_sha1_file Jonathan Nieder
2017-08-30  6:59 ` [PATCH 12/39] sha1_file: add repository argument to open_sha1_file Jonathan Nieder
2017-08-30  7:00 ` [PATCH 13/39] sha1_file: add repository argument to map_sha1_file_1 Jonathan Nieder
2017-08-30  7:01 ` [PATCH 14/39] sha1_file: add repository argument to sha1_loose_object_info Jonathan Nieder
2017-08-30  7:01 ` [PATCH 15/39] object-store: add repository argument to prepare_alt_odb Jonathan Nieder
2017-08-30  7:02 ` [PATCH 16/39] object-store: add repository argument to foreach_alt_odb Jonathan Nieder
2017-08-30  7:02 ` [PATCH 17/39] pack: add repository argument to install_packed_git Jonathan Nieder
2017-08-30  7:03 ` [PATCH 18/39] pack: add repository argument to prepare_packed_git_one Jonathan Nieder
2017-08-30  7:03 ` [PATCH 19/39] pack: add repository argument to rearrange_packed_git Jonathan Nieder
2017-08-30  7:04 ` [PATCH 20/39] pack: add repository argument to prepare_packed_git_mru Jonathan Nieder
2017-08-30  7:05 ` [PATCH 21/39] pack: add repository argument to prepare_packed_git Jonathan Nieder
2017-08-30  7:06 ` [PATCH 22/39] pack: add repository argument to reprepare_packed_git Jonathan Nieder
2017-08-30  7:06 ` [PATCH 23/39] pack: add repository argument to sha1_file_name Jonathan Nieder
2017-08-30  7:07 ` [PATCH 24/39] pack: add repository argument to map_sha1_file Jonathan Nieder
2017-08-30  7:08 ` [PATCH 25/39] sha1_file: allow alt_odb_usable to handle arbitrary repositories Jonathan Nieder
2017-09-06 20:01   ` Junio C Hamano
2017-09-06 21:59     ` Stefan Beller
2017-08-30  7:10 ` [PATCH 26/39] object-store: allow prepare_alt_odb " Jonathan Nieder
2017-08-30  7:11 ` [PATCH 27/39] object-store: allow foreach_alt_odb " Jonathan Nieder
2017-08-30  7:11 ` [PATCH 28/39] pack: allow install_packed_git " Jonathan Nieder
2017-08-30  7:12 ` [PATCH 29/39] pack: allow rearrange_packed_git " Jonathan Nieder
2017-08-30  7:12 ` [PATCH 30/39] pack: allow prepare_packed_git_mru " Jonathan Nieder
2017-08-30  7:13 ` [PATCH 31/39] pack: allow prepare_packed_git_one " Jonathan Nieder
2017-08-30  7:13 ` [PATCH 32/39] pack: allow prepare_packed_git " Jonathan Nieder
2017-08-30  7:14 ` [PATCH 33/39] pack: allow reprepare_packed_git " Jonathan Nieder
2017-08-30  7:14 ` [PATCH 34/39] pack: allow sha1_file_name " Jonathan Nieder
2017-08-30  7:15 ` [PATCH 35/39] pack: allow stat_sha1_file " Jonathan Nieder
2017-08-30  7:16 ` [PATCH 36/39] pack: allow open_sha1_file " Jonathan Nieder
2017-08-30  7:16 ` [PATCH 37/39] pack: allow map_sha1_file_1 " Jonathan Nieder
2017-08-30  7:16 ` [PATCH 38/39] pack: allow map_sha1_file " Jonathan Nieder
2017-08-30  7:18 ` [PATCH 39/39] pack: allow sha1_loose_object_info " Jonathan Nieder
2017-08-30 23:07 ` [PATCH 00/39] per-repository object store, part 1 Brandon Williams

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.