Re: [PATCH 22/30] tree-walk.h API: Add get_tree_entry_type()
- From
Elijah Newren <newren@gmail.com>
- Date
- Mar 9, 2021, 17:56 UTC
- Message-ID
- <CABPp-BExOo7b3OEMrCmCjAzrxf2iaSP-s75Ay6ZheTjmA5bWxQ@mail.gmail.com>
- In-Reply-To
- <20210308150650.18626-23-avarab@gmail.com>
On Mon, Mar 8, 2021 at 7:07 AM Ævar Arnfjörð Bjarmason <avarab@gmail.com> wrote:
Show 5 quoted lines
>
> Add a get_tree_entry_type() helper function to compliment the existing
> get_tree_entry(). Move those users of get_tree_entry_type() who didn't
> care about the mode specifically, but just want to know whether the
> tree entry is one of OBJ_{BLOB,COMMIT,TREE} over to it.You added not one but two new functions (get_tree_entry_all() is the other); should probably call out both in the commit message.
Show 50 quoted lines
>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
> archive.c | 8 ++++----
> blame.c | 8 ++++----
> match-trees.c | 10 +++++-----
> tree-walk.c | 47 ++++++++++++++++++++++++++++++++++++-----------
> tree-walk.h | 15 +++++++++++++--
> 5 files changed, 62 insertions(+), 26 deletions(-)
>
> diff --git a/archive.c b/archive.c
> index 95fa759e1fb..bc8f1c7546f 100644
> --- a/archive.c
> +++ b/archive.c
> @@ -479,14 +479,14 @@ static void parse_treeish_arg(const char **argv,
>
> if (prefix) {
> struct object_id tree_oid;
> - unsigned short mode;
> + enum object_type object_type;
> int err;
>
> - err = get_tree_entry_mode(ar_args->repo,
> + err = get_tree_entry_type(ar_args->repo,
> &tree->object.oid,
> prefix, &tree_oid,
> - &mode);
> - if (err || !S_ISDIR(mode))
> + &object_type);
> + if (err || object_type != OBJ_TREE)
> die(_("current working directory is untracked"));
>
> tree = parse_tree_indirect(&tree_oid);
> diff --git a/blame.c b/blame.c
> index 9e0543e13d4..4944582dc3c 100644
> --- a/blame.c
> +++ b/blame.c
> @@ -101,11 +101,11 @@ static void verify_working_tree_path(struct repository *r,
> for (parents = work_tree->parents; parents; parents = parents->next) {
> const struct object_id *commit_oid = &parents->item->object.oid;
> struct object_id blob_oid;
> - unsigned short mode;
> - int ret = get_tree_entry_mode(r, commit_oid, path, &blob_oid,
> - &mode);
> + enum object_type object_type;
> + int ret = get_tree_entry_type(r, commit_oid, path, &blob_oid,
> + &object_type);
>
> - if (!ret && oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB)
> + if (!ret && object_type == OBJ_BLOB)Testing my understanding -- does this mean that even before your patch that the oid_object_info() call wasn't needed? In particular, we could have replaced it with something like (!S_ISGITLNK(mode) && (S_ISREG(mode) || S_ISLNK(mode)))?
Show 142 quoted lines
> return;
> }
>
> diff --git a/match-trees.c b/match-trees.c
> index 4f02768c01e..ce3f811ec04 100644
> --- a/match-trees.c
> +++ b/match-trees.c
> @@ -317,17 +317,17 @@ void shift_tree_by(struct repository *r,
> const char *shift_prefix)
> {
> struct object_id sub1, sub2;
> - unsigned short tmp;
> + enum object_type tmp;
> unsigned candidate = 0;
>
> /* Can hash2 be a tree at shift_prefix in tree hash1? */
> - if (!get_tree_entry_mode(r, hash1, shift_prefix, &sub1, &tmp) &&
> - S_ISDIR(tmp))
> + if (!get_tree_entry_type(r, hash1, shift_prefix, &sub1, &tmp) &&
> + tmp == OBJ_TREE)
> candidate |= 1;
>
> /* Can hash1 be a tree at shift_prefix in tree hash2? */
> - if (!get_tree_entry_mode(r, hash2, shift_prefix, &sub2, &tmp) &&
> - S_ISDIR(tmp))
> + if (!get_tree_entry_type(r, hash2, shift_prefix, &sub2, &tmp) &&
> + tmp == OBJ_TREE)
> candidate |= 2;
>
> if (candidate == 3) {
> diff --git a/tree-walk.c b/tree-walk.c
> index 7819ff3e0ec..0ad3d80593e 100644
> --- a/tree-walk.c
> +++ b/tree-walk.c
> @@ -561,7 +561,8 @@ struct dir_state {
>
> static int find_tree_entry(struct repository *r, struct tree_desc *t,
> const char *name, struct object_id *result,
> - unsigned short *mode)
> + unsigned short *mode,
> + enum object_type *object_type)
> {
> int namelen = strlen(name);
> while (t->size) {
> @@ -585,23 +586,24 @@ static int find_tree_entry(struct repository *r, struct tree_desc *t,
> }
> if (name[entrylen] != '/')
> continue;
> - if (!S_ISDIR(*mode))
> + if (*object_type != OBJ_TREE)
> break;
> if (++entrylen == namelen) {
> oidcpy(result, &oid);
> return 0;
> }
> - return get_tree_entry_mode(r, &oid, name + entrylen, result,
> - mode);
> + return get_tree_entry_all(r, &oid, name + entrylen, result,
> + mode, object_type);
> }
> return -1;
> }
>
> -int get_tree_entry_mode(struct repository *r,
> - const struct object_id *tree_oid,
> - const char *name,
> - struct object_id *oid,
> - unsigned short *mode)
> +int get_tree_entry_all(struct repository *r,
> + const struct object_id *tree_oid,
> + const char *name,
> + struct object_id *oid,
> + unsigned short *mode,
> + enum object_type *object_type)
> {
> int retval;
> void *tree;
> @@ -624,12 +626,34 @@ int get_tree_entry_mode(struct repository *r,
> struct tree_desc t;
> init_tree_desc(&t, tree, size);
> retval = find_tree_entry(r, &t, name, oid,
> - mode);
> + mode, object_type);
> }
> free(tree);
> return retval;
> }
>
> +int get_tree_entry_mode(struct repository *r,
> + const struct object_id *tree_oid,
> + const char *name,
> + struct object_id *oid,
> + unsigned short *mode)
> +{
> + enum object_type object_type;
> + return get_tree_entry_all(r, tree_oid, name, oid,
> + mode, &object_type);
> +}
> +
> +int get_tree_entry_type(struct repository *r,
> + const struct object_id *tree_oid,
> + const char *name,
> + struct object_id *oid,
> + enum object_type *object_type)
> +{
> + unsigned short mode;
> + return get_tree_entry_all(r, tree_oid, name, oid,
> + &mode, object_type);
> +}
> +
> /*
> * 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
> @@ -674,6 +698,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r,
> int find_result;
> char *first_slash;
> char *remainder = NULL;
> + enum object_type object_type;
>
> if (!t.buffer) {
> void *tree;
> @@ -751,7 +776,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r,
> /* Look up the first (or only) path component in the tree. */
> find_result = find_tree_entry(r, &t, namebuf.buf,
> ¤t_tree_oid,
> - mode);
> + mode, &object_type);
> if (find_result) {
> goto done;
> }
> diff --git a/tree-walk.h b/tree-walk.h
> index eb9b9de6ccc..5db38fcb575 100644
> --- a/tree-walk.h
> +++ b/tree-walk.h
> @@ -171,12 +171,23 @@ struct traverse_info {
> * Find an entry in a tree given a pathname and the sha1 of a tree to
> * search. Returns 0 if the entry is found and -1 otherwise.
> *
> - * The third and fourth parameters are set to the entry's sha1 and
> - * mode respectively.
> + * There are variants of this function depending on what fields in the
> + * "struct name_entry" you'd like. You always need to pointer to ans/to pointer to an/a pointer to an/ ?
Show 21 quoted lines
> + * appropriate variable to fill in (NULL won't do!): > + * > + * get_tree_entry_mode(): unsigned int mode > + * get_tree_entry_type(): enum object_type > + * get_tree_entry_all(): unsigned int mode, enum object_type > */ > int get_tree_entry_mode(struct repository *, const struct object_id *, const char *, > struct object_id *, > unsigned short *); > +int get_tree_entry_type(struct repository *, const struct object_id *, const char *, > + struct object_id *, > + enum object_type *); > +int get_tree_entry_all(struct repository *, const struct object_id *, const char *, > + struct object_id *, > + unsigned short *, enum object_type *); > > /** > * Generate the full pathname of a tree entry based from the root of the > -- > 2.31.0.rc0.126.g04f22c5b82 >