@@ -475,14 +475,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);
@@ -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) {
@@ -559,9 +559,17 @@ struct dir_state {
struct object_id oid;
};
+static 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);
+
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 +593,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)
+static 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 +633,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 +705,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 +783,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;
}
@@ -171,12 +171,19 @@ 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 a pointer to an
+ * appropriate variable to fill in (NULL won't do!):
+ *
+ * get_tree_entry_mode(): unsigned int mode
+ * get_tree_entry_type(): 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 *);
/**
* Generate the full pathname of a tree entry based from the root of the
Add a get_tree_entry_type() helper function to compliment the existing get_tree_entry(), and a static get_tree_entry_all() which it uses internally. 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 the new get_tree_entry_type(). The get_tree_entry_all() function itself will be made non-static in a subsequent commit. I'm leaving its argument list indented accordingly to reduce churn when I do so. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- archive.c | 8 ++++---- match-trees.c | 10 +++++----- tree-walk.c | 54 ++++++++++++++++++++++++++++++++++++++++----------- tree-walk.h | 11 +++++++++-- 4 files changed, 61 insertions(+), 22 deletions(-)