From: Ævar Arnfjörð Bjarmason Date: Mon, 29 Nov 2021 19:57:50 GMT Subject: [PATCH v3 10/10] cat-file: use GET_OID_ONLY_TO_DIE in --(textconv|filters) Message-ID: In-Reply-To: Change the cat_one_file() logic that calls get_oid_with_context() under --textconv and --filters to use the GET_OID_ONLY_TO_DIE flag, thus improving the error messaging emitted when e.g. is missing but is not. To service the "cat-file" use-case we need to introduce a new "GET_OID_REQUIRE_PATH" flag, otherwise it would exit early as soon as a valid "HEAD" was resolved, but in the "cat-file" case being changed we always need a valid revision and path. This arguably makes the ":" and ":" use cases worse, as we won't quote the component at the user anymore, but let's just use the existing logic "git log" et al use for now. We can improve the messaging for those cases as a follow-up for all callers. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/cat-file.c | 15 +++++---------- cache.h | 1 + object-name.c | 6 +++++- t/t8007-cat-file-textconv.sh | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 1d7f79184f0..b76f2a00046 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -73,14 +73,16 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, struct object_info oi = OBJECT_INFO_INIT; struct strbuf sb = STRBUF_INIT; unsigned flags = OBJECT_INFO_LOOKUP_REPLACE; + unsigned get_oid_flags = GET_OID_RECORD_PATH | GET_OID_ONLY_TO_DIE; const char *path = force_path; + if (!path && (opt == 'w' || opt == 'c')) + get_oid_flags |= GET_OID_REQUIRE_PATH; if (unknown_type) flags |= OBJECT_INFO_ALLOW_UNKNOWN_TYPE; - if (get_oid_with_context(the_repository, obj_name, - GET_OID_RECORD_PATH, - &oid, &obj_context)) + if (get_oid_with_context(the_repository, obj_name, get_oid_flags, &oid, + &obj_context)) die("Not a valid object name %s", obj_name); if (!path) @@ -112,9 +114,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, return !has_object_file(&oid); case 'w': - if (!path) - die("git cat-file --filters %s: must be " - "", obj_name); if (filter_object(path, obj_context.mode, &oid, &buf, &size)) @@ -122,10 +121,6 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, break; case 'c': - if (!path) - die("git cat-file --textconv %s: must be ", - obj_name); - if (textconv_object(the_repository, path, obj_context.mode, &oid, 1, &buf, &size)) break; diff --git a/cache.h b/cache.h index eba12487b99..788127a9869 100644 --- a/cache.h +++ b/cache.h @@ -1366,6 +1366,7 @@ struct object_context { #define GET_OID_FOLLOW_SYMLINKS 0100 #define GET_OID_RECORD_PATH 0200 #define GET_OID_ONLY_TO_DIE 04000 +#define GET_OID_REQUIRE_PATH 010000 #define GET_OID_DISAMBIGUATORS \ (GET_OID_COMMIT | GET_OID_COMMITTISH | \ diff --git a/object-name.c b/object-name.c index d44a8f3a7ca..e94ced3f170 100644 --- a/object-name.c +++ b/object-name.c @@ -1799,8 +1799,12 @@ static enum get_oid_result get_oid_with_context_1(struct repository *repo, oc->mode = S_IFINVALID; strbuf_init(&oc->symlink_path, 0); ret = get_oid_1(repo, name, namelen, oid, flags); - if (!ret) + if (!ret) { + if (flags & GET_OID_REQUIRE_PATH) + die(_(": required, only '%s' given"), name); return ret; + } + /* * tree:path --> object name of path in tree * :path -> object name of absolute path in index diff --git a/t/t8007-cat-file-textconv.sh b/t/t8007-cat-file-textconv.sh index 71ea2ac987e..b067983ba1c 100755 --- a/t/t8007-cat-file-textconv.sh +++ b/t/t8007-cat-file-textconv.sh @@ -29,7 +29,7 @@ test_expect_success 'usage: ' ' test_expect_success 'usage: :' ' cat >expect <<-\EOF && - fatal: Not a valid object name HEAD2:two.bin + fatal: invalid object name '\''HEAD2'\''. EOF test_must_fail git cat-file --textconv HEAD2:two.bin 2>actual && test_cmp expect actual @@ -37,7 +37,7 @@ test_expect_success 'usage: :' ' test_expect_success 'usage: :' ' cat >expect <<-\EOF && - fatal: Not a valid object name HEAD:two.bin + fatal: path '\''two.bin'\'' does not exist in '\''HEAD'\'' EOF test_must_fail git cat-file --textconv HEAD:two.bin 2>actual && test_cmp expect actual @@ -46,7 +46,7 @@ test_expect_success 'usage: :' ' test_expect_success 'usage: with no ' ' cat >expect <<-\EOF && - fatal: git cat-file --textconv HEAD: must be + fatal: : required, only '\''HEAD'\'' given EOF test_must_fail git cat-file --textconv HEAD 2>actual && test_cmp expect actual @@ -55,7 +55,7 @@ test_expect_success 'usage: with no ' ' test_expect_success 'usage: :' ' cat >expect <<-\EOF && - fatal: Not a valid object name HEAD2:one.bin + fatal: invalid object name '\''HEAD2'\''. EOF test_must_fail git cat-file --textconv HEAD2:one.bin 2>actual && test_cmp expect actual -- 2.34.1.841.gf15fb7e6f34