diff --git a/cache.h b/cache.h
index 4743f7ed9fb..c7565f6acb3 100644
--- a/cache.h
+++ b/cache.h
@@ -1283,14 +1283,16 @@ int for_each_loose_file_in_objdir_buf(struct strbuf *path,
 
 /*
  * Iterate over loose and packed objects in both the local
- * repository and any alternates repositories.
+ * repository and any alternates repositories (unless the
+ * LOCAL_ONLY flag is set).
  */
+#define FOR_EACH_OBJECT_LOCAL_ONLY 0x1
 typedef int each_packed_object_fn(const unsigned char *sha1,
 				  struct packed_git *pack,
 				  uint32_t pos,
 				  void *data);
-extern int for_each_loose_object(each_loose_object_fn, void *);
-extern int for_each_packed_object(each_packed_object_fn, void *);
+extern int for_each_loose_object(each_loose_object_fn, void *, unsigned flags);
+extern int for_each_packed_object(each_packed_object_fn, void *, unsigned flags);
 
 struct object_info {
 	/* Request */
diff --git a/reachable.c b/reachable.c
index a647267ae9c..69fa6851da8 100644
--- a/reachable.c
+++ b/reachable.c
@@ -142,10 +142,12 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
 	data.revs = revs;
 	data.timestamp = timestamp;
 
-	r = for_each_loose_object(add_recent_loose, &data);
+	r = for_each_loose_object(add_recent_loose, &data,
+				  FOR_EACH_OBJECT_LOCAL_ONLY);
 	if (r)
 		return r;
-	return for_each_packed_object(add_recent_packed, &data);
+	return for_each_packed_object(add_recent_packed, &data,
+				      FOR_EACH_OBJECT_LOCAL_ONLY);
 }
 
 void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
diff --git a/sha1_file.c b/sha1_file.c
index a41cc4f65fe..9711ef817d7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3418,7 +3418,7 @@ static int loose_from_alt_odb(struct alternate_object_database *alt,
 	return r;
 }
 
-int for_each_loose_object(each_loose_object_fn cb, void *data)
+int for_each_loose_object(each_loose_object_fn cb, void *data, unsigned flags)
 {
 	struct loose_alt_odb_data alt;
 	int r;
@@ -3428,6 +3428,9 @@ int for_each_loose_object(each_loose_object_fn cb, void *data)
 	if (r)
 		return r;
 
+	if (flags & FOR_EACH_OBJECT_LOCAL_ONLY)
+		return 0;
+
 	alt.cb = cb;
 	alt.data = data;
 	return foreach_alt_odb(loose_from_alt_odb, &alt);
@@ -3452,13 +3455,15 @@ static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn c
 	return r;
 }
 
-int for_each_packed_object(each_packed_object_fn cb, void *data)
+int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
 {
 	struct packed_git *p;
 	int r = 0;
 
 	prepare_packed_git();
 	for (p = packed_git; p; p = p->next) {
+		if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
+			continue;
 		r = for_each_object_in_pack(p, cb, data);
 		if (r)
 			break;