Commit 709768a8379b12e62cc8d03b2795d46dc482cb3b

Chris Hescock 2016-12-09T15:59:52

Don't fetch objects we don't need in local transport. Hide all local refs in the revwalk. Packbuilder should not add hidden trees or blobs.

diff --git a/src/pack-objects.c b/src/pack-objects.c
index 9f62322..8ca6403 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -1641,7 +1641,7 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
 	if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
 		return error;
 
-	if (obj->seen)
+	if (obj->seen || obj->uninteresting)
 		return 0;
 
 	obj->seen = 1;
@@ -1665,6 +1665,10 @@ int insert_tree(git_packbuilder *pb, git_tree *tree)
 
 			break;
 		case GIT_OBJ_BLOB:
+			if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
+				return error;
+			if (obj->uninteresting)
+				continue;
 			name = git_tree_entry_name(entry);
 			if ((error = git_packbuilder_insert(pb, entry_id, name)) < 0)
 				return error;
diff --git a/src/transports/local.c b/src/transports/local.c
index 4eae9de..9ec6ab6 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -503,6 +503,21 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v
 	return error;
 }
 
+static int foreach_reference_cb(git_reference *reference, void *payload)
+{
+	git_revwalk *walk = (git_revwalk *)payload;
+
+	int error = git_revwalk_hide(walk, git_reference_target(reference));
+	/* The reference is in the local repository, so the target may not
+	 * exist on the remote.  It also may not be a commit. */
+	if (error == GIT_ENOTFOUND || error == GITERR_INVALID) {
+		giterr_clear();
+		error = 0;
+	}
+
+	return error;
+}
+
 static int local_download_pack(
 		git_transport *transport,
 		git_repository *repo,
@@ -542,11 +557,6 @@ static int local_download_pack(
 		if (git_object_type(obj) == GIT_OBJ_COMMIT) {
 			/* Revwalker includes only wanted commits */
 			error = git_revwalk_push(walk, &rhead->oid);
-			if (!error && !git_oid_iszero(&rhead->loid)) {
-				error = git_revwalk_hide(walk, &rhead->loid);
-				if (error == GIT_ENOTFOUND)
-					error = 0;
-			}
 		} else {
 			/* Tag or some other wanted object. Add it on its own */
 			error = git_packbuilder_insert_recur(pack, &rhead->oid, rhead->name);
@@ -556,6 +566,9 @@ static int local_download_pack(
 			goto cleanup;
 	}
 
+	if ((error = git_reference_foreach(repo, foreach_reference_cb, walk)))
+		goto cleanup;
+
 	if ((error = git_packbuilder_insert_walk(pack, walk)))
 		goto cleanup;