rev-list: add print-info action to print missing object path

Missing objects identified through git-rev-list(1) can be printed by
setting the `--missing=print` option. Additional information about the
missing object, such as its path and type, may be present in its
containing object.

Add the `print-info` missing action for the `--missing` option that,
when set, prints additional insight about the missing object inferred
from its containing object. Each line of output for a missing object is
in the form: `?<oid> [<token>=<value>]...`. The `<token>=<value>` pairs
containing additional information are separated from each other by a SP.
The value is encoded in a token specific fashion, but SP or LF contained
in value are always expected to be represented in such a way that the
resulting encoded value does not have either of these two problematic
bytes. This format is kept generic so it can be extended in the future
to support additional information.

For now, only a missing object path info is implemented. It follows the
form `path=<path>` and specifies the full path to the object from the
top-level tree. A path containing SP or special characters is enclosed
in double-quotes in the C style as needed. In a subsequent commit,
missing object type info will also be added.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Acked-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Justin Tobler
2025-02-04 18:41:46 -06:00
committed by Junio C Hamano
parent bc204b7427
commit c6d896bcfd
3 changed files with 152 additions and 17 deletions

View File

@ -145,4 +145,56 @@ do
done
done
for obj in "HEAD~1" "HEAD^{tree}" "HEAD:foo" "HEAD:foo/bar" "HEAD:baz baz"
do
test_expect_success "--missing=print-info with missing '$obj'" '
test_when_finished rm -rf missing-info &&
git init missing-info &&
(
cd missing-info &&
git commit --allow-empty -m first &&
mkdir foo &&
echo bar >foo/bar &&
echo baz >"baz baz" &&
echo bat >bat\" &&
git add -A &&
git commit -m second &&
oid="$(git rev-parse "$obj")" &&
path=".git/objects/$(test_oid_to_path $oid)" &&
case $obj in
HEAD:foo)
path_info=" path=foo"
;;
HEAD:foo/bar)
path_info=" path=foo/bar"
;;
"HEAD:baz baz")
path_info=" path=\"baz baz\""
;;
"HEAD:bat\"")
path_info=" path=\"bat\\\"\""
;;
esac &&
# Before the object is made missing, we use rev-list to
# get the expected oids.
git rev-list --objects --no-object-names \
HEAD ^"$obj" >expect.raw &&
echo "?$oid$path_info" >>expect.raw &&
mv "$path" "$path.hidden" &&
git rev-list --objects --no-object-names \
--missing=print-info HEAD >actual.raw &&
sort actual.raw >actual &&
sort expect.raw >expect &&
test_cmp expect actual
)
'
done
test_done