Skip to content

Commit f90fca6

Browse files
abhishekkumar2718gitster
authored andcommitted
commit-graph: consolidate fill_commit_graph_info
Both fill_commit_graph_info() and fill_commit_in_graph() parse information present in commit data chunk. Let's simplify the implementation by calling fill_commit_graph_info() within fill_commit_in_graph(). fill_commit_graph_info() used to not load committer data from commit data chunk. However, with the upcoming switch to using corrected committer date as generation number v2, we will have to load committer date to compute generation number value anyway. e51217e (t5000: test tar files that overflow ustar headers, 30-06-2016) introduced a test 'generate tar with future mtime' that creates a commit with committer date of (2^36 + 1) seconds since EPOCH. The CDAT chunk provides 34-bits for storing committer date, thus committer time overflows into generation number (within CDAT chunk) and has undefined behavior. The test used to pass as fill_commit_graph_info() would not set struct member `date` of struct commit and load committer date from the object database, generating a tar file with the expected mtime. However, with corrected commit date, we will load the committer date from CDAT chunk (truncated to lower 34-bits to populate the generation number. Thus, Git sets date and generates tar file with the truncated mtime. The ustar format (the header format used by most modern tar programs) only has room for 11 (or 12, depending on some implementations) octal digits for the size and mtime of each file. As the CDAT chunk is overflow by 12-octal digits but not 11-octal digits, we split the existing tests to test both implementations separately and add a new explicit test for 11-digit implementation. To test the 11-octal digit implementation, we create a future commit with committer date of 2^34 - 1, which overflows 11-octal digits without overflowing 34-bits of the Commit Date chunks. To test the 12-octal digit implementation, the smallest committer date possible is 2^36 + 1, which overflows the CDAT chunk and thus commit-graph must be disabled for the test. Signed-off-by: Abhishek Kumar <[email protected]> Reviewed-by: Taylor Blau <[email protected]> Reviewed-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2f9bbb6 commit f90fca6

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

commit-graph.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -753,15 +753,24 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
753753
const unsigned char *commit_data;
754754
struct commit_graph_data *graph_data;
755755
uint32_t lex_index;
756+
uint64_t date_high, date_low;
756757

757758
while (pos < g->num_commits_in_base)
758759
g = g->base_graph;
759760

761+
if (pos >= g->num_commits + g->num_commits_in_base)
762+
die(_("invalid commit position. commit-graph is likely corrupt"));
763+
760764
lex_index = pos - g->num_commits_in_base;
761765
commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * lex_index;
762766

763767
graph_data = commit_graph_data_at(item);
764768
graph_data->graph_pos = pos;
769+
770+
date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
771+
date_low = get_be32(commit_data + g->hash_len + 12);
772+
item->date = (timestamp_t)((date_high << 32) | date_low);
773+
765774
graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
766775
}
767776

@@ -776,38 +785,22 @@ static int fill_commit_in_graph(struct repository *r,
776785
{
777786
uint32_t edge_value;
778787
uint32_t *parent_data_ptr;
779-
uint64_t date_low, date_high;
780788
struct commit_list **pptr;
781-
struct commit_graph_data *graph_data;
782789
const unsigned char *commit_data;
783790
uint32_t lex_index;
784791

785792
while (pos < g->num_commits_in_base)
786793
g = g->base_graph;
787794

788-
if (pos >= g->num_commits + g->num_commits_in_base)
789-
die(_("invalid commit position. commit-graph is likely corrupt"));
795+
fill_commit_graph_info(item, g, pos);
790796

791-
/*
792-
* Store the "full" position, but then use the
793-
* "local" position for the rest of the calculation.
794-
*/
795-
graph_data = commit_graph_data_at(item);
796-
graph_data->graph_pos = pos;
797797
lex_index = pos - g->num_commits_in_base;
798-
799798
commit_data = g->chunk_commit_data + (g->hash_len + 16) * lex_index;
800799

801800
item->object.parsed = 1;
802801

803802
set_commit_tree(item, NULL);
804803

805-
date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
806-
date_low = get_be32(commit_data + g->hash_len + 12);
807-
item->date = (timestamp_t)((date_high << 32) | date_low);
808-
809-
graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
810-
811804
pptr = &item->parents;
812805

813806
edge_value = get_be32(commit_data + g->hash_len);

t/t5000-tar-tree.sh

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,15 +431,33 @@ test_expect_success TAR_HUGE,LONG_IS_64BIT 'system tar can read our huge size' '
431431
test_cmp expect actual
432432
'
433433

434-
test_expect_success TIME_IS_64BIT 'set up repository with far-future commit' '
434+
test_expect_success TIME_IS_64BIT 'set up repository with far-future (2^34 - 1) commit' '
435+
rm -f .git/index &&
436+
echo foo >file &&
437+
git add file &&
438+
GIT_COMMITTER_DATE="@17179869183 +0000" \
439+
git commit -m "tempori parendum"
440+
'
441+
442+
test_expect_success TIME_IS_64BIT 'generate tar with far-future mtime' '
443+
git archive HEAD >future.tar
444+
'
445+
446+
test_expect_success TAR_HUGE,TIME_IS_64BIT,TIME_T_IS_64BIT 'system tar can read our future mtime' '
447+
echo 2514 >expect &&
448+
tar_info future.tar | cut -d" " -f2 >actual &&
449+
test_cmp expect actual
450+
'
451+
452+
test_expect_success TIME_IS_64BIT 'set up repository with far-far-future (2^36 + 1) commit' '
435453
rm -f .git/index &&
436454
echo content >file &&
437455
git add file &&
438-
GIT_COMMITTER_DATE="@68719476737 +0000" \
456+
GIT_TEST_COMMIT_GRAPH=0 GIT_COMMITTER_DATE="@68719476737 +0000" \
439457
git commit -m "tempori parendum"
440458
'
441459

442-
test_expect_success TIME_IS_64BIT 'generate tar with future mtime' '
460+
test_expect_success TIME_IS_64BIT 'generate tar with far-far-future mtime' '
443461
git archive HEAD >future.tar
444462
'
445463

0 commit comments

Comments
 (0)