Skip to content

Commit 8e182c5

Browse files
shejialuogitster
authored andcommitted
packed-backend: add check for object consistency
If there is nothing wrong when parsing the raw file "packed-refs", we could then iterate the "entries" to check the object consistency. There are two kinds of ref entry: one is the normal and another is peeled. For both situations, we need to use "parse_object" function to parse the object id to get the object. If the object does not exist, we will report an error to the user. Create a new function "packed_fsck_ref_oid" to do above then update the unit test to exercise the code. Mentored-by: Patrick Steinhardt <[email protected]> Mentored-by: Karthik Nayak <[email protected]> Signed-off-by: shejialuo <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c018836 commit 8e182c5

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

refs/packed-backend.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "../iterator.h"
1515
#include "../lockfile.h"
1616
#include "../chdir-notify.h"
17+
#include "../packfile.h"
1718
#include "../statinfo.h"
1819
#include "../worktree.h"
1920
#include "../wrapper.h"
@@ -1934,6 +1935,52 @@ static int packed_fsck_ref_main_line(struct fsck_options *o,
19341935
return ret;
19351936
}
19361937

1938+
static int packed_fsck_ref_oid(struct fsck_options *o, struct ref_store *ref_store,
1939+
struct fsck_packed_ref_entry **entries, int nr)
1940+
{
1941+
struct strbuf packed_entry = STRBUF_INIT;
1942+
struct fsck_ref_report report = { 0 };
1943+
struct object *obj;
1944+
int ret = 0;
1945+
1946+
for (int i = 0; i < nr; i++) {
1947+
struct fsck_packed_ref_entry *entry = entries[i];
1948+
1949+
strbuf_release(&packed_entry);
1950+
strbuf_addf(&packed_entry, "packed-refs line %d", entry->line_number);
1951+
report.path = packed_entry.buf;
1952+
1953+
if (is_promisor_object(ref_store->repo, &entry->oid))
1954+
continue;
1955+
1956+
obj = parse_object(ref_store->repo, &entry->oid);
1957+
if (!obj) {
1958+
ret |= fsck_report_ref(o, &report,
1959+
FSCK_MSG_BAD_PACKED_REF_ENTRY,
1960+
"'%s' is not a valid object",
1961+
oid_to_hex(&entry->oid));
1962+
}
1963+
if (entry->has_peeled) {
1964+
strbuf_reset(&packed_entry);
1965+
strbuf_addf(&packed_entry, "packed-refs line %d",
1966+
entry->line_number + 1);
1967+
report.path = packed_entry.buf;
1968+
1969+
obj = parse_object(ref_store->repo, &entry->peeled);
1970+
if (!obj) {
1971+
ret |= fsck_report_ref(o, &report,
1972+
FSCK_MSG_BAD_PACKED_REF_ENTRY,
1973+
"'%s' is not a valid object",
1974+
oid_to_hex(&entry->peeled));
1975+
}
1976+
}
1977+
1978+
}
1979+
1980+
strbuf_release(&packed_entry);
1981+
return ret;
1982+
}
1983+
19371984
static int packed_fsck_ref_content(struct fsck_options *o,
19381985
struct ref_store *ref_store,
19391986
const char *start, const char *eof)
@@ -1987,7 +2034,8 @@ static int packed_fsck_ref_content(struct fsck_options *o,
19872034
*/
19882035
if (ret)
19892036
o->safe_object_check = 0;
1990-
2037+
else
2038+
ret |= packed_fsck_ref_oid(o, ref_store, entries, entry_nr);
19912039

19922040
free_fsck_packed_ref_entries(entries, entry_nr);
19932041
return ret;

t/t0602-reffiles-fsck.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,4 +730,39 @@ test_expect_success 'packed-refs content should be checked' '
730730
test_cmp expect err
731731
'
732732

733+
test_expect_success 'packed-refs objects should be checked' '
734+
test_when_finished "rm -rf repo" &&
735+
git init repo &&
736+
cd repo &&
737+
test_commit default &&
738+
git tag -a annotated-tag-1 -m tag-1 &&
739+
740+
tag_1_oid=$(git rev-parse annotated-tag-1) &&
741+
742+
for non_existing_oid in "$(test_oid 001)" "$(test_oid 002)"
743+
do
744+
printf "# pack-refs with: peeled fully-peeled sorted \n" >.git/packed-refs &&
745+
printf "%s refs/heads/foo\n" "$non_existing_oid" >>.git/packed-refs &&
746+
test_must_fail git refs verify 2>err &&
747+
cat >expect <<-EOF &&
748+
error: packed-refs line 2: badPackedRefEntry: '\''$non_existing_oid'\'' is not a valid object
749+
EOF
750+
rm .git/packed-refs &&
751+
test_cmp expect err || return 1
752+
done &&
753+
754+
for non_existing_oid in "$(test_oid 001)" "$(test_oid 002)"
755+
do
756+
printf "# pack-refs with: peeled fully-peeled sorted \n" >.git/packed-refs &&
757+
printf "%s refs/tags/foo\n" "$tag_1_oid" >>.git/packed-refs &&
758+
printf "^$non_existing_oid\n" >>.git/packed-refs &&
759+
test_must_fail git refs verify 2>err &&
760+
cat >expect <<-EOF &&
761+
error: packed-refs line 3: badPackedRefEntry: '\''$non_existing_oid'\'' is not a valid object
762+
EOF
763+
rm .git/packed-refs &&
764+
test_cmp expect err || return 1
765+
done
766+
'
767+
733768
test_done

0 commit comments

Comments
 (0)