Skip to content

Commit e228c17

Browse files
dschogitster
authored andcommitted
Remove the line length limit for graft files
Support for grafts predates Git's strbuf, and hence it is understandable that there was a hard-coded line length limit of 1023 characters (which was chosen a bit awkwardly, given that it is *exactly* one byte short of aligning with the 41 bytes occupied by a commit name and the following space or new-line character). While regular commit histories hardly win comprehensibility in general if they merge more than twenty-two branches in one go, it is not Git's business to limit grafts in such a way. In this particular developer's case, the use case that requires substantially longer graft lines to be supported is the visualization of the commits' order implied by their changes: commits are considered to have an implicit relationship iff exchanging them in an interactive rebase would result in merge conflicts. Thusly implied branches tend to be very shallow in general, and the resulting thicket of implied branches is usually very wide; It is actually quite common that *most* of the commits in a topic branch have not even one implied parent, so that a final merge commit has about as many implied parents as there are commits in said branch. [jc: squashed in tests by Jonathan] Signed-off-by: Johannes Schindelin <[email protected]> Reviewed-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5512ac5 commit e228c17

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

builtin/blame.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,17 +1804,17 @@ static int prepare_lines(struct scoreboard *sb)
18041804
static int read_ancestry(const char *graft_file)
18051805
{
18061806
FILE *fp = fopen(graft_file, "r");
1807-
char buf[1024];
1807+
struct strbuf buf = STRBUF_INIT;
18081808
if (!fp)
18091809
return -1;
1810-
while (fgets(buf, sizeof(buf), fp)) {
1810+
while (!strbuf_getwholeline(&buf, fp, '\n')) {
18111811
/* The format is just "Commit Parent1 Parent2 ...\n" */
1812-
int len = strlen(buf);
1813-
struct commit_graft *graft = read_graft_line(buf, len);
1812+
struct commit_graft *graft = read_graft_line(buf.buf, buf.len);
18141813
if (graft)
18151814
register_commit_graft(graft, 0);
18161815
}
18171816
fclose(fp);
1817+
strbuf_release(&buf);
18181818
return 0;
18191819
}
18201820

commit.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,19 @@ struct commit_graft *read_graft_line(char *buf, int len)
196196
static int read_graft_file(const char *graft_file)
197197
{
198198
FILE *fp = fopen(graft_file, "r");
199-
char buf[1024];
199+
struct strbuf buf = STRBUF_INIT;
200200
if (!fp)
201201
return -1;
202-
while (fgets(buf, sizeof(buf), fp)) {
202+
while (!strbuf_getwholeline(&buf, fp, '\n')) {
203203
/* The format is just "Commit Parent1 Parent2 ...\n" */
204-
int len = strlen(buf);
205-
struct commit_graft *graft = read_graft_line(buf, len);
204+
struct commit_graft *graft = read_graft_line(buf.buf, buf.len);
206205
if (!graft)
207206
continue;
208207
if (register_commit_graft(graft, 1))
209-
error("duplicate graft data: %s", buf);
208+
error("duplicate graft data: %s", buf.buf);
210209
}
211210
fclose(fp);
211+
strbuf_release(&buf);
212212
return 0;
213213
}
214214

t/annotate-tests.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,27 @@ test_expect_success 'blame evil merge' '
116116
check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1
117117
'
118118

119+
test_expect_success 'blame huge graft' '
120+
test_when_finished "git checkout branch2" &&
121+
test_when_finished "rm -f .git/info/grafts" &&
122+
graft= &&
123+
for i in 0 1 2
124+
do
125+
for j in 0 1 2 3 4 5 6 7 8 9
126+
do
127+
git checkout --orphan "$i$j" &&
128+
printf "%s\n" "$i" "$j" >file &&
129+
test_tick &&
130+
GIT_AUTHOR_NAME=$i$j [email protected] \
131+
git commit -a -m "$i$j" &&
132+
commit=$(git rev-parse --verify HEAD) &&
133+
graft="$graft$commit "
134+
done
135+
done &&
136+
printf "%s " $graft >.git/info/grafts &&
137+
check_count -h 00 01 1 10 1
138+
'
139+
119140
test_expect_success 'setup incomplete line' '
120141
echo "incomplete" | tr -d "\\012" >>file &&
121142
GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="[email protected]" \

t/t6101-rev-parse-parents.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ test_expect_success 'setup' '
2020
test_commit start2 &&
2121
git checkout master &&
2222
git merge -m next start2 &&
23-
test_commit final
23+
test_commit final &&
24+
25+
test_seq 40 |
26+
while read i
27+
do
28+
git checkout --orphan "b$i" &&
29+
test_tick &&
30+
git commit --allow-empty -m "$i" &&
31+
commit=$(git rev-parse --verify HEAD) &&
32+
printf "$commit " >>.git/info/grafts
33+
done
2434
'
2535

2636
test_expect_success 'start is valid' '
@@ -79,6 +89,10 @@ test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' '
7989
test_cmp expect actual
8090
'
8191

92+
test_expect_success 'large graft octopus' '
93+
test_cmp_rev_output b31 "git rev-parse --verify b1^30"
94+
'
95+
8296
test_expect_success 'repack for next test' '
8397
git repack -a -d
8498
'

0 commit comments

Comments
 (0)