diff --git a/blob.c b/blob.c
index 182718aba9f..b233e0daa2f 100644
--- a/blob.c
+++ b/blob.c
@@ -2,17 +2,31 @@
#include "blob.h"
#include "repository.h"
#include "alloc.h"
+#include "object-store.h"
const char *blob_type = "blob";
-struct blob *lookup_blob(struct repository *r, const struct object_id *oid)
+struct blob *lookup_blob_type(struct repository *r,
+ const struct object_id *oid,
+ enum object_type type)
{
struct object *obj = lookup_object(r, oid);
if (!obj)
return create_object(r, oid, alloc_blob_node(r));
+ if (type != OBJ_NONE &&
+ obj->type != OBJ_NONE) {
+ enum object_type want = OBJ_BLOB;
+ if (oid_is_type_or_error(oid, obj->type, &want))
+ return NULL;
+ }
return object_as_type(obj, OBJ_BLOB, 0);
}
+struct blob *lookup_blob(struct repository *r, const struct object_id *oid)
+{
+ return lookup_blob_type(r, oid, OBJ_NONE);
+}
+
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
{
item->object.parsed = 1;diff --git a/blob.h b/blob.h
index 16648720557..066a2effcbf 100644
--- a/blob.h
+++ b/blob.h
@@ -10,6 +10,9 @@ struct blob {
};
struct blob *lookup_blob(struct repository *r, const struct object_id *oid);
+struct blob *lookup_blob_type(struct repository *r,
+ const struct object_id *oid,
+ enum object_type type);
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size);
diff --git a/commit.c b/commit.c
index b3701003678..ab6cee1e8c3 100644
--- a/commit.c
+++ b/commit.c
@@ -57,14 +57,26 @@ struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref
return c;
}
-struct commit *lookup_commit(struct repository *r, const struct object_id *oid)
+struct commit *lookup_commit_type(struct repository *r, const struct object_id *oid,
+ enum object_type type)
{
struct object *obj = lookup_object(r, oid);
if (!obj)
return create_object(r, oid, alloc_commit_node(r));
+ if (type != OBJ_NONE &&
+ obj->type != OBJ_NONE) {
+ enum object_type want = OBJ_COMMIT;
+ if (oid_is_type_or_error(oid, obj->type, &want))
+ return NULL;
+ }
return object_as_type(obj, OBJ_COMMIT, 0);
}
+struct commit *lookup_commit(struct repository *r, const struct object_id *oid)
+{
+ return lookup_commit_type(r, oid, OBJ_NONE);
+}
+
struct commit *lookup_commit_reference_by_name(const char *name)
{
struct object_id oid;diff --git a/commit.h b/commit.h
index df42eb434f3..9def4f3f19d 100644
--- a/commit.h
+++ b/commit.h
@@ -64,6 +64,8 @@ void add_name_decoration(enum decoration_type type, const char *name, struct obj
const struct name_decoration *get_name_decoration(const struct object *obj);
struct commit *lookup_commit(struct repository *r, const struct object_id *oid);
+struct commit *lookup_commit_type(struct repository *r, const struct object_id *oid,
+ enum object_type type);
struct commit *lookup_commit_reference(struct repository *r,
const struct object_id *oid);
struct commit *lookup_commit_reference_gently(struct repository *r,
diff --git a/object.c b/object.c
index 0f60743e61f..60037422488 100644
--- a/object.c
+++ b/object.c
@@ -230,14 +230,14 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id
obj = NULL;
if (type == OBJ_BLOB) {
- struct blob *blob = lookup_blob(r, oid);
+ struct blob *blob = lookup_blob_type(r, oid, type);
if (blob) {
if (parse_blob_buffer(blob, buffer, size))
return NULL;
obj = &blob->object;
}
} else if (type == OBJ_TREE) {
- struct tree *tree = lookup_tree(r, oid);
+ struct tree *tree = lookup_tree_type(r, oid, type);
if (tree) {
obj = &tree->object;
if (!tree->buffer)@@ -249,7 +249,7 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id
}
}
} else if (type == OBJ_COMMIT) {
- struct commit *commit = lookup_commit(r, oid);
+ struct commit *commit = lookup_commit_type(r, oid, type);
if (commit) {
if (parse_commit_buffer(r, commit, buffer, size, 1))
return NULL;@@ -260,7 +260,7 @@ struct object *parse_object_buffer(struct repository *r, const struct object_id
obj = &commit->object;
}
} else if (type == OBJ_TAG) {
- struct tag *tag = lookup_tag(r, oid);
+ struct tag *tag = lookup_tag_type(r, oid, type);
if (tag) {
if (parse_tag_buffer(r, tag, buffer, size))
return NULL;diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh
index 2ea1982b9ed..4a6b3cc3b01 100755
--- a/t/t6102-rev-list-unexpected-objects.sh
+++ b/t/t6102-rev-list-unexpected-objects.sh
@@ -156,14 +156,14 @@ test_expect_success 'setup unexpected non-tag tag' '
test_expect_success 'traverse unexpected incorrectly typed tag (to commit & tag)' '
test_must_fail git rev-list --objects $tag_tag_commit 2>err &&
cat >expected <<-EOF &&
- error: object $commit is a tag, not a commit
+ error: object $commit is a commit, not a tag
fatal: bad object $commit
EOF
test_cmp expected err &&
test_must_fail git rev-list --objects $commit_tag_tag 2>err &&
cat >expected <<-EOF &&
- error: object $tag_commit is a commit, not a tag
+ error: object $tag_commit is a tag, not a commit
fatal: bad object $tag_commit
EOF
test_cmp expected err
@@ -172,14 +172,14 @@ test_expect_success 'traverse unexpected incorrectly typed tag (to commit & tag)
test_expect_success 'traverse unexpected incorrectly typed tag (to tree)' '
test_must_fail git rev-list --objects $tag_tag_tree 2>err &&
cat >expected <<-EOF &&
- error: object $tree is a tag, not a tree
+ error: object $tree is a tree, not a tag
fatal: bad object $tree
EOF
test_cmp expected err &&
test_must_fail git rev-list --objects $commit_tag_tree 2>err &&
cat >expected <<-EOF &&
- error: object $tree is a commit, not a tree
+ error: object $tree is a tree, not a commit
fatal: bad object $tree
EOF
test_cmp expected err
@@ -188,14 +188,14 @@ test_expect_success 'traverse unexpected incorrectly typed tag (to tree)' '
test_expect_success 'traverse unexpected incorrectly typed tag (to blob)' '
test_must_fail git rev-list --objects $tag_tag_blob 2>err &&
cat >expected <<-EOF &&
- error: object $blob is a tag, not a blob
+ error: object $blob is a blob, not a tag
fatal: bad object $blob
EOF
test_cmp expected err &&
test_must_fail git rev-list --objects $commit_tag_blob 2>err &&
cat >expected <<-EOF &&
- error: object $blob is a commit, not a blob
+ error: object $blob is a blob, not a commit
fatal: bad object $blob
EOF
test_cmp expected err
@@ -204,14 +204,14 @@ test_expect_success 'traverse unexpected incorrectly typed tag (to blob)' '
test_expect_success 'traverse unexpected non-tag tag (tree seen to blob)' '
test_must_fail git rev-list --objects $tree $commit_tag_blob 2>err &&
cat >expected <<-EOF &&
- error: object $blob is a commit, not a blob
+ error: object $blob is a blob, not a commit
fatal: bad object $blob
EOF
test_cmp expected err &&
test_must_fail git rev-list --objects $tree $tag_tag_blob 2>err &&
cat >expected <<-EOF &&
- error: object $blob is a tag, not a blob
+ error: object $blob is a blob, not a tag
fatal: bad object $blob
EOF
test_cmp expected err
diff --git a/tag.c b/tag.c
index 3e18a418414..0ef87897b29 100644
--- a/tag.c
+++ b/tag.c
@@ -99,14 +99,26 @@ struct object *deref_tag_noverify(struct object *o)
return o;
}
-struct tag *lookup_tag(struct repository *r, const struct object_id *oid)
+struct tag *lookup_tag_type(struct repository *r, const struct object_id *oid,
+ enum object_type type)
{
struct object *obj = lookup_object(r, oid);
if (!obj)
return create_object(r, oid, alloc_tag_node(r));
+ if (type != OBJ_NONE &&
+ obj->type != OBJ_NONE) {
+ enum object_type want = OBJ_TAG;
+ if (oid_is_type_or_error(oid, obj->type, &want))
+ return NULL;
+ }
return object_as_type(obj, OBJ_TAG, 0);
}
+struct tag *lookup_tag(struct repository *r, const struct object_id *oid)
+{
+ return lookup_tag_type(r, oid, OBJ_NONE);
+}
+
static timestamp_t parse_tag_date(const char *buf, const char *tail)
{
const char *dateptr;diff --git a/tag.h b/tag.h
index 3ce8e721924..42bd3e64011 100644
--- a/tag.h
+++ b/tag.h
@@ -12,6 +12,8 @@ struct tag {
timestamp_t date;
};
struct tag *lookup_tag(struct repository *r, const struct object_id *oid);
+struct tag *lookup_tag_type(struct repository *r, const struct object_id *oid,
+ enum object_type type);
int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, unsigned long size);
int parse_tag(struct tag *item);
void release_tag_memory(struct tag *t);diff --git a/tree.c b/tree.c
index d9b1c70b28a..895c66420e8 100644
--- a/tree.c
+++ b/tree.c
@@ -195,14 +195,26 @@ int read_tree(struct repository *r, struct tree *tree, int stage,
return 0;
}
-struct tree *lookup_tree(struct repository *r, const struct object_id *oid)
+struct tree *lookup_tree_type(struct repository *r, const struct object_id *oid,
+ enum object_type type)
{
struct object *obj = lookup_object(r, oid);
if (!obj)
return create_object(r, oid, alloc_tree_node(r));
+ if (type != OBJ_NONE &&
+ obj->type != OBJ_NONE) {
+ enum object_type want = OBJ_TREE;
+ if (oid_is_type_or_error(oid, obj->type, &want))
+ return NULL;
+ }
return object_as_type(obj, OBJ_TREE, 0);
}
+struct tree *lookup_tree(struct repository *r, const struct object_id *oid)
+{
+ return lookup_tree_type(r, oid, OBJ_NONE);
+}
+
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
{
if (item->object.parsed)diff --git a/tree.h b/tree.h
index 3eb0484cbf2..49bd44f79b3 100644
--- a/tree.h
+++ b/tree.h
@@ -15,6 +15,8 @@ struct tree {
extern const char *tree_type;
struct tree *lookup_tree(struct repository *r, const struct object_id *oid);
+struct tree *lookup_tree_type(struct repository *r, const struct object_id *oid,
+ enum object_type type);
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size);
--
2.31.1.442.g6c06c9fe35c