[PATCH v2 0/2] [GSOC] cat-file: fix --batch report changed-type bug
From: ZheNing Hu via GitGitGadget <hidden>
Date: 2021-06-03 16:30:30
Change from last version:
1. Modified the test structure under the recommendation of Peff.
2. Use clearer and more concise commit message help by Peff.
ZheNing Hu (2):
[GSOC] cat-file: handle trivial --batch format with
--batch-all-objects
[GSOC] cat-file: merge two block into one
builtin/cat-file.c | 10 ++++------
t/t1006-cat-file.sh | 22 ++++++++++++++++++++++
2 files changed, 26 insertions(+), 6 deletions(-)
base-commit: 5d5b1473453400224ebb126bf3947e0a3276bdf5
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-967%2Fadlternative%2Fcat-file-batch-bug-fix-v2-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-967/adlternative/cat-file-batch-bug-fix-v2-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/967
Range-diff vs v1:
1: 495cd90dbaf4 ! 1: 4af3b958dd05 [GSOC] cat-file: fix --batch report changed-type bug
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- [GSOC] cat-file: fix --batch report changed-type bug
+ [GSOC] cat-file: handle trivial --batch format with --batch-all-objects
- When `--batch` used with `--batch-all-objects`,
- with some format atoms like %(objectname), %(rest)
- or even no atoms may cause Git exit and report
- "object xxx changed type!?".
+ The --batch code to print an object assumes we found out the type of
+ the object from calling oid_object_info_extended(). This is true for
+ the default format, but even in a custom format, we manually modify
+ the object_info struct to ask for the type.
- E.g. `git cat-file --batch="batman" --batch-all-objects`
+ This assumption was broken by 845de33a5b (cat-file: avoid noop calls
+ to sha1_object_info_extended, 2016-05-18). That commit skips the call
+ to oid_object_info_extended() entirely when --batch-all-objects is in
+ use, and the custom format does not include any placeholders that
+ require calling it.
- This is because we did not get the object type through
- oid_object_info_extended(), it's composed of two
- situations:
+ Or when the custom format only include placeholders like %(objectname) or
+ %(rest), oid_object_info_extended() will not get the type of the object.
- 1. Since object_info is empty, skip_object_info is
- set to true, We skipped collecting the object type.
+ This results in an error when we try to confirm that the type didn't
+ change:
- 2. The formatting atom like %(objectname) does not require
- oid_object_info_extended() to collect object types.
+ $ git cat-file --batch=batman --batch-all-objects
+ batman
+ fatal: object 000023961a0c02d6e21dc51ea3484ff71abf1c74 changed type!?
- The correct way to deal with it is to swap the order
- of setting skip_object_info and setting typep. This
- will ensure that we must get the type of the object
- when using --batch.
+ and also has other subtle effects (e.g., we'd fail to stream a blob,
+ since we don't realize it's a blob in the first place).
+
+ We can fix this by flipping the order of the setup. The check for "do
+ we need to get the object info" must come _after_ we've decided
+ whether we need to look up the type.
Helped-by: Jeff King [off-list ref]
Signed-off-by: ZheNing Hu [off-list ref]
@@ t/t1006-cat-file.sh: test_expect_success 'cat-file --unordered works' '
test_cmp expect actual
'
++test_expect_success 'set up object list for --batch-all-objects tests' '
++ git -C all-two cat-file --batch-all-objects --batch-check="%(objectname)" >objects
++'
++
+test_expect_success 'cat-file --batch="%(objectname)" with --batch-all-objects will work' '
-+ git -C all-two cat-file --batch-all-objects --batch-check="%(objectname)" >objects &&
+ git -C all-two cat-file --batch="%(objectname)" <objects >expect &&
+ git -C all-two cat-file --batch-all-objects --batch="%(objectname)" >actual &&
+ cmp expect actual
2: f02c1144d916 ! 2: 759451e784de [GSOC] cat-file: merge two block into one
@@ Metadata
Author: ZheNing Hu [off-list ref]
## Commit message ##
- [GSOC] cat-file: merge two block into one
+ [GSOC] cat-file: merge two block into one
- Because the two "if (opt->all_objects)" block
- are redundant, merge them into one, to provide
- better readability.
+ There are two "if (opt->all_objects)" blocks next
+ to each other, merge them into one to provide better
+ readability.
Helped-by: Jeff King [off-list ref]
Signed-off-by: ZheNing Hu [off-list ref]
--
gitgitgadget