[PATCH 3/3] cat-file: avoid verifying submodules' OIDs
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Submodules are strange creatures. They have OIDs, but the corresponding objects are not expected to be present in the current directory.
Let's teach `cat-file` about this: This command should not even attempt to look up those objects, let alone declare them "missing".
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Documentation/git-cat-file.txt | 5 +++++
builtin/cat-file.c | 32 ++++++++++++++++++++++++++------
t/t1006-cat-file.sh | 10 ++++++++++
3 files changed, 41 insertions(+), 6 deletions(-)
Show changes to 3 files +41 −6
Documentation/git-cat-file.txt, builtin/cat-file.c, t/t1006-cat-file.sh
diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt
index de29e6d79d9..69b50d2042f 100644
--- a/Documentation/git-cat-file.txt
+++ b/Documentation/git-cat-file.txt
@@ -412,6 +412,11 @@ Note also that multiple copies of an object may be present in the object
database; in this case, it is undefined which copy's size or delta base
will be reported.
+Submodules are handled specially in `git cat-file`, as the objects
+corresponding to the recorded OIDs are not expected to be present in the
+current repository. For that reason, submodules are reported as having
+type `submodule` and mode 1600000 and all other fields are zeroed out.
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 73bd78c0b63..c59ad682d1f 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -128,7 +128,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
switch (opt) {
case 't':
oi.type_name = &sb;
- if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
+ if (obj_context.mode == S_IFGITLINK)
+ strbuf_addstr(&sb, "submodule");
+ else if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
die("git cat-file: could not get object info");
if (sb.len) {
printf("%s\n", sb.buf);
@@ -319,17 +321,26 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
if (!data->mark_query)
strbuf_addstr(sb, oid_to_hex(&data->oid));
} else if (is_atom("objecttype", atom, len)) {
- if (data->mark_query)
+ if (data->mode == S_IFGITLINK) {
+ if (!data->mark_query)
+ strbuf_addstr(sb, "submodule");
+ } else if (data->mark_query)
data->info.typep = &data->type;
else
strbuf_addstr(sb, type_name(data->type));
} else if (is_atom("objectsize", atom, len)) {
- if (data->mark_query)
+ if (data->mode == S_IFGITLINK) {
+ if (!data->mark_query)
+ strbuf_addstr(sb, "0");
+ } else if (data->mark_query)
data->info.sizep = &data->size;
else
strbuf_addf(sb, "%"PRIuMAX , (uintmax_t)data->size);
} else if (is_atom("objectsize:disk", atom, len)) {
- if (data->mark_query)
+ if (data->mode == S_IFGITLINK) {
+ if (!data->mark_query)
+ strbuf_addstr(sb, "0");
+ } else if (data->mark_query)
data->info.disk_sizep = &data->disk_size;
else
strbuf_addf(sb, "%"PRIuMAX, (uintmax_t)data->disk_size);
@@ -448,7 +459,8 @@ static void print_default_format(struct strbuf *scratch, struct expand_data *dat
struct batch_options *opt)
{
strbuf_addf(scratch, "%s %s %"PRIuMAX"%c", oid_to_hex(&data->oid),
- type_name(data->type),
+ data->mode == S_IFGITLINK ?
+ "submodule" : type_name(data->type),
(uintmax_t)data->size, opt->output_delim);
}
@@ -470,7 +482,15 @@ static void batch_object_write(const char *obj_name,
if (use_mailmap)
data->info.typep = &data->type;
- if (pack)
+ if (data->mode == S_IFGITLINK) {
+ data->type = OBJ_BAD; /* `type_name()` does not know submodules */
+ data->size = 0;
+ data->disk_size = 0;
+ data->rest = NULL;
+ oidcpy(&data->delta_base_oid, null_oid());
+ memset(&data->info, 0, sizeof(data->info));
+ ret = 0; /* no info to look up */
+ } else if (pack)
ret = packed_object_info(the_repository, pack, offset,
&data->info);
else
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 6f25cc20ec6..3368b663ef3 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -1178,6 +1178,16 @@ test_expect_success 'cat-file --batch-check respects replace objects' '
test_cmp expect actual
'
+test_expect_success 'batch-command with a submodule' '
+ printf "160000 commit %0.*d\tsub\n" $(test_oid hexsz) 17 >tree-with-sub &&
+ tree=$(git mktree <tree-with-sub) &&
+ git cat-file --batch-check >actual <<-EOF &&
+ $tree:sub
+ EOF
+ printf "%0.*d submodule 0\n" $(test_oid hexsz) 17 >expect &&
+ test_cmp expect actual
+'
+
# Pull the entry for object with oid "$1" out of the output of
# "cat-file --batch", including its object content (which requires
# parsing and reading a set amount of bytes, hence perl).
--
gitgitgadget