From: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
To: git@vger.kernel.org
Subject: [RFC PATCH 2/6] tree-walk: Add three new gentle helpers
Date: Tue, 17 Jul 2018 15:06:32 +0300 [thread overview]
Message-ID: <b1f385105f790cafc65c26699282919a2735d4bd.1531778417.git.ungureanupaulsebastian@gmail.com> (raw)
In-Reply-To: <cover.1531778417.git.ungureanupaulsebastian@gmail.com>
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@gmail.com>
---
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(¤t_tree_oid,
- tree_type, &size,
- &root);
+ if (!(flags & GET_OID_GENTLY)) {
+ tree = read_object_with_reference(¤t_tree_oid,
+ tree_type, &size,
+ &root);
+ } else {
+ struct object_info oi = OBJECT_INFO_INIT;
+
+ oi.contentp = tree;
+ if (oid_object_info_extended(the_repository,
+ ¤t_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,
- ¤t_tree_oid, mode);
+ ¤t_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(¤t_tree_oid, &type,
- &link_len);
+ if (!(flags & GET_OID_GENTLY)) {
+ contents = read_object_file(¤t_tree_oid,
+ &type, &link_len);
+ } else {
+ struct object_info oi = OBJECT_INFO_INIT;
+ oi.contentp = (void*) contents;
+
+ if (oid_object_info_extended(the_repository,
+ ¤t_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
next prev parent reply other threads:[~2018-07-17 12:08 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-17 12:06 [RFC PATCH 0/6] Add gentle alternative for `get_oid()` Paul-Sebastian Ungureanu
2018-07-17 12:06 ` [RFC PATCH 1/6] sha1-name: Add `GET_OID_GENTLY` flag Paul-Sebastian Ungureanu
2018-07-17 12:06 ` Paul-Sebastian Ungureanu [this message]
2018-07-17 18:55 ` [RFC PATCH 2/6] tree-walk: Add three new gentle helpers Junio C Hamano
2018-07-18 23:11 ` Paul-Sebastian Ungureanu
2018-07-17 12:06 ` [RFC PATCH 3/6] refs.c: Teach `read_ref_at()` to accept `GET_OID_GENTLY` flag Paul-Sebastian Ungureanu
2018-07-17 12:06 ` [RFC PATCH 4/6] sha1-name: Teach `get_oid_basic()` to be gentle Paul-Sebastian Ungureanu
2018-07-17 12:06 ` [RFC PATCH 5/6] sha1-name: Teach `get_oid_with_context[_1]()` " Paul-Sebastian Ungureanu
2018-07-17 19:13 ` Junio C Hamano
2018-07-18 23:14 ` Paul-Sebastian Ungureanu
2018-07-17 12:06 ` [RFC PATCH 6/6] sha1-name: Add gentle alternative for `get_oid()` Paul-Sebastian Ungureanu
2018-07-17 17:45 ` [RFC PATCH 0/6] " Duy Nguyen
2018-07-18 23:03 ` Paul-Sebastian Ungureanu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b1f385105f790cafc65c26699282919a2735d4bd.1531778417.git.ungureanupaulsebastian@gmail.com \
--to=ungureanupaulsebastian@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).