[RFC PATCH 2/6] tree-walk: Add three new gentle helpers

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

 



Add `get_tree_entry_gently()`, `find_tree_entry_gently()`
and `get_tree_entry_follow_symlinks_gently()`, which will
make `get_oid()` to be more gently.

Since `get_tree_entry()` is used in more than 20 places,
adding a new parameter will make this commit harder to read.
In every place it is called there will need to be an additional
0 parameter at the end of the call. The solution to avoid this is
to rename the function in `get_tree_entry_gently()` which gets
an additional `flags` variable. A new `get_tree_entry()`
will call `get_tree_entry_gently()` with `flags` being 0.
This way, no additional changes will be needed.

Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@xxxxxxxxx>
---
 sha1-name.c |   2 +-
 tree-walk.c | 108 +++++++++++++++++++++++++++++++++++++++++++---------
 tree-walk.h |   3 +-
 3 files changed, 94 insertions(+), 19 deletions(-)

diff --git a/sha1-name.c b/sha1-name.c
index 60d9ef3c7..d741e1129 100644
--- a/sha1-name.c
+++ b/sha1-name.c
@@ -1721,7 +1721,7 @@ static int get_oid_with_context_1(const char *name,
 			if (flags & GET_OID_FOLLOW_SYMLINKS) {
 				ret = get_tree_entry_follow_symlinks(&tree_oid,
 					filename, oid, &oc->symlink_path,
-					&oc->mode);
+					&oc->mode, flags);
 			} else {
 				ret = get_tree_entry(&tree_oid, filename, oid,
 						     &oc->mode);
diff --git a/tree-walk.c b/tree-walk.c
index 8f5090862..2925eaec2 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -491,7 +491,9 @@ struct dir_state {
 	struct object_id oid;
 };
 
-static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned *mode)
+static int find_tree_entry(struct tree_desc *t, const char *name,
+				  struct object_id *result, unsigned *mode,
+				  int flags)
 {
 	int namelen = strlen(name);
 	while (t->size) {
@@ -501,7 +503,11 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_
 
 		oid = tree_entry_extract(t, &entry, mode);
 		entrylen = tree_entry_len(&t->entry);
-		update_tree_entry(t);
+
+		if (!(flags & GET_OID_GENTLY))
+			update_tree_entry(t);
+		else if (update_tree_entry_gently(t))
+			return -1;
 		if (entrylen > namelen)
 			continue;
 		cmp = memcmp(name, entry, entrylen);
@@ -521,19 +527,28 @@ static int find_tree_entry(struct tree_desc *t, const char *name, struct object_
 			oidcpy(result, oid);
 			return 0;
 		}
-		return get_tree_entry(oid, name + entrylen, result, mode);
+		return get_tree_entry_gently(oid, name + entrylen, result, mode, flags);
 	}
 	return -1;
 }
 
-int get_tree_entry(const struct object_id *tree_oid, const char *name, struct object_id *oid, unsigned *mode)
+int get_tree_entry_gently(const struct object_id *tree_oid, const char *name,
+			  struct object_id *oid, unsigned *mode, int flags)
 {
 	int retval;
 	void *tree;
 	unsigned long size;
 	struct object_id root;
 
-	tree = read_object_with_reference(tree_oid, tree_type, &size, &root);
+	if (!(flags & GET_OID_GENTLY)) {
+		tree = read_object_with_reference(tree_oid, tree_type, &size, &root);
+	} else {
+		struct object_info oi = OBJECT_INFO_INIT;
+
+		oi.contentp = tree;
+		if (oid_object_info_extended(the_repository, tree_oid, &oi, 0) < 0)
+			return -1;
+	}
 	if (!tree)
 		return -1;
 
@@ -547,13 +562,27 @@ int get_tree_entry(const struct object_id *tree_oid, const char *name, struct ob
 		retval = -1;
 	} else {
 		struct tree_desc t;
-		init_tree_desc(&t, tree, size);
-		retval = find_tree_entry(&t, name, oid, mode);
+		if (!(flags & GET_OID_GENTLY)) {
+			init_tree_desc(&t, tree, size);
+		} else {
+			if (init_tree_desc_gently(&t, tree, size)) {
+				retval = -1;
+				goto done;
+			}
+		}
+		retval = find_tree_entry(&t, name, oid, mode, flags);
 	}
+done:
 	free(tree);
 	return retval;
 }
 
+int get_tree_entry(const struct object_id *tree_oid, const char *name,
+		   struct object_id *oid, unsigned *mode)
+{
+	return get_tree_entry_gently(tree_oid, name, oid, mode, 0);
+}
+
 /*
  * This is Linux's built-in max for the number of symlinks to follow.
  * That limit, of course, does not affect git, but it's a reasonable
@@ -576,7 +605,7 @@ int get_tree_entry(const struct object_id *tree_oid, const char *name, struct ob
  * See the code for enum follow_symlink_result for a description of
  * the return values.
  */
-enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode)
+enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode, int flags)
 {
 	int retval = MISSING_OBJECT;
 	struct dir_state *parents = NULL;
@@ -600,9 +629,21 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 			void *tree;
 			struct object_id root;
 			unsigned long size;
-			tree = read_object_with_reference(&current_tree_oid,
-							  tree_type, &size,
-							  &root);
+			if (!(flags & GET_OID_GENTLY)) {
+				tree = read_object_with_reference(&current_tree_oid,
+								  tree_type, &size,
+								  &root);
+			} else {
+				struct object_info oi = OBJECT_INFO_INIT;
+
+				oi.contentp = tree;
+				if (oid_object_info_extended(the_repository,
+				    &current_tree_oid, &oi, 0) < 0) {
+					retval = MISSING_OBJECT;
+					goto done;
+				}
+			}
+
 			if (!tree)
 				goto done;
 
@@ -622,7 +663,14 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 				goto done;
 
 			/* descend */
-			init_tree_desc(&t, tree, size);
+			if (!(flags & GET_OID_GENTLY)) {
+				init_tree_desc(&t, tree, size);
+			} else {
+				if (init_tree_desc_gently(&t, tree, size)) {
+					retval = MISSING_OBJECT;
+					goto done;
+				}
+			}
 		}
 
 		/* Handle symlinks to e.g. a//b by removing leading slashes */
@@ -656,7 +704,15 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 			free(parent->tree);
 			parents_nr--;
 			parent = &parents[parents_nr - 1];
-			init_tree_desc(&t, parent->tree, parent->size);
+			if (!(flags & GET_OID_GENTLY)) {
+				init_tree_desc(&t, parent->tree, parent->size);
+			} else {
+				if (init_tree_desc_gently(&t, parent->tree,
+				    parent->size)) {
+					retval = MISSING_OBJECT;
+					goto done;
+				}
+			}
 			strbuf_remove(&namebuf, 0, remainder ? 3 : 2);
 			continue;
 		}
@@ -670,7 +726,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 
 		/* Look up the first (or only) path component in the tree. */
 		find_result = find_tree_entry(&t, namebuf.buf,
-					      &current_tree_oid, mode);
+					      &current_tree_oid, mode, flags);
 		if (find_result) {
 			goto done;
 		}
@@ -713,8 +769,19 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 			 */
 			retval = DANGLING_SYMLINK;
 
-			contents = read_object_file(&current_tree_oid, &type,
-						    &link_len);
+			if (!(flags & GET_OID_GENTLY)) {
+				contents = read_object_file(&current_tree_oid,
+							    &type, &link_len);
+			} else {
+				struct object_info oi = OBJECT_INFO_INIT;
+				oi.contentp = (void*) contents;
+
+				if (oid_object_info_extended(the_repository,
+				    &current_tree_oid, &oi, 0) < 0) {
+					retval = MISSING_OBJECT;
+					goto done;
+				}
+			}
 
 			if (!contents)
 				goto done;
@@ -735,7 +802,14 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tre
 			contents_start = contents;
 
 			parent = &parents[parents_nr - 1];
-			init_tree_desc(&t, parent->tree, parent->size);
+			if (!(flags & GET_OID_GENTLY)) {
+				init_tree_desc(&t, parent->tree, parent->size);
+			} else {
+				if (init_tree_desc_gently(&t, parent->tree, parent->size)) {
+					retval = MISSING_OBJECT;
+					goto done;
+				}
+			}
 			strbuf_splice(&namebuf, 0, len,
 				      contents_start, link_len);
 			if (remainder)
diff --git a/tree-walk.h b/tree-walk.h
index 805f58f00..6f043af6e 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -64,7 +64,7 @@ enum follow_symlinks_result {
 		       */
 };
 
-enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode);
+enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode, int flags);
 
 struct traverse_info {
 	const char *traverse_path;
@@ -79,6 +79,7 @@ struct traverse_info {
 	int show_all_errors;
 };
 
+int get_tree_entry_gently(const struct object_id *, const char *, struct object_id *, unsigned *, int);
 int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned *);
 extern char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n);
 extern void setup_traverse_info(struct traverse_info *info, const char *base);
-- 
2.18.0.rc2.184.ga79db55c2.dirty




[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]

  Powered by Linux