[PATCH 10/32] rev-list: support traversing in narrow repository mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In this mode, only trees within revs->narrow_prefix is traversed. This
narrows down the whole repository to the given subtree. This mode will
be used by upload-pack/pack-objects to create a narrow pack, and by
all git operations in narrow repository (i.e. $GIT_DIR/narrow exists).

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx>
---
 list-objects.c |   36 +++++++++++++++++++++++++++++++++---
 revision.h     |    4 +++-
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/list-objects.c b/list-objects.c
index 8953548..7014926 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -61,12 +61,15 @@ static void process_tree(struct rev_info *revs,
 			 struct tree *tree,
 			 show_object_fn show,
 			 struct name_path *path,
-			 const char *name)
+			 const char *name,
+			 const char *subtree)
 {
 	struct object *obj = &tree->object;
 	struct tree_desc desc;
 	struct name_entry entry;
 	struct name_path me;
+	const char *slash = NULL;
+	int subtree_len;
 
 	if (!revs->tree_objects)
 		return;
@@ -82,13 +85,34 @@ static void process_tree(struct rev_info *revs,
 	me.elem = name;
 	me.elem_len = strlen(name);
 
+	if (subtree) {
+		slash = strchr(subtree, '/');
+		subtree_len = slash ? slash - subtree : strlen(subtree);
+	}
+
 	init_tree_desc(&desc, tree->buffer, tree->size);
 
 	while (tree_entry(&desc, &entry)) {
+		/*
+		 * FIXME, does not follow tree rename
+		 * some sort of rename hints would be nice
+		 * (because diff machinery should not be used
+		 * here for detecting renames)
+		 */
+		if (!subtree)
+			; 	/* no subtree restriction, go on */
+		else if (S_ISDIR(entry.mode) &&
+			 !strncmp(entry.path, subtree, subtree_len) &&
+			 entry.path[subtree_len] == '\0')
+			;	/* inside subtree, go on */
+		else
+			continue; /* stop */
+
 		if (S_ISDIR(entry.mode))
 			process_tree(revs,
 				     lookup_tree(entry.sha1),
-				     show, &me, entry.path);
+				     show, &me, entry.path,
+				     slash ? slash+1 : NULL);
 		else if (S_ISGITLINK(entry.mode))
 			process_gitlink(revs, entry.sha1,
 					show, &me, entry.path);
@@ -147,6 +171,11 @@ void traverse_commit_list(struct rev_info *revs,
 	int i;
 	struct commit *commit;
 
+	if (get_narrow_prefix() && !revs->narrow_tree) {
+		revs->narrow_tree = 1;
+		revs->narrow_prefix = get_narrow_prefix();
+	}
+
 	while ((commit = get_revision(revs)) != NULL) {
 		add_pending_tree(revs, commit->tree);
 		show_commit(commit, data);
@@ -164,7 +193,8 @@ void traverse_commit_list(struct rev_info *revs,
 		}
 		if (obj->type == OBJ_TREE) {
 			process_tree(revs, (struct tree *)obj, show_object,
-				     NULL, name);
+				     NULL, name,
+				     revs->narrow_tree ? revs->narrow_prefix : NULL);
 			continue;
 		}
 		if (obj->type == OBJ_BLOB) {
diff --git a/revision.h b/revision.h
index 36fdf22..ccdf28a 100644
--- a/revision.h
+++ b/revision.h
@@ -33,6 +33,7 @@ struct rev_info {
 
 	/* Basic information */
 	const char *prefix;
+	const char *narrow_prefix;
 	const char *def;
 	void *prune_data;
 	unsigned int early_output;
@@ -68,7 +69,8 @@ struct rev_info {
 			cherry_pick:1,
 			bisect:1,
 			ancestry_path:1,
-			first_parent_only:1;
+			first_parent_only:1,
+			narrow_tree:1;
 
 	/* Diff flags */
 	unsigned int	diff:1,
-- 
1.7.1.rc1.69.g24c2f7

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]