Bug in reflog of length 0x2BFF
Hi,
I encountered a strange bug concerning the reflog. I suspect some kind of out-of-bounds access. The symptom is:
%git rev-parse 'master@{52}'
warning: Log for ref refs/heads/master has gap after Thu, 1 Jan 1970 00:00:01 +0000.
0000000000000000000000000000000000000036
Try the following:
git init gitbug
cd gitbug
git commit --allow-empty -m a
cp ../reflog.bad .git/logs/refs/heads/master git rev-parse 'master@{52}'
The source of cp is the attached file. This is from a reflog of stash.
I just replaced all stuff by dummy values. This does not seem to affect the bug. Sorry, it must be this long.
Some observations:
* If you change the length of any line starting at line 3, the symptom vanishes.
(The XXXXX at the line ends are free-form text.)
* Starting at line three, there are 0x2BFF bytes till the end of file. Is there some dynamically growing buffer, which at some point reaches
the size 0x2C00?
* Changing the length of the first two lines has no effect. Is the file read backwards?
* It happens at least with git 2.1.2 (amd64) and 2.2.0 (ia32).
* 2.0.2 (amd64) and 2.1.0 (amd64) seem not to have this bug.
Any ideas?
Christoph
0000000000000000000000000000000000000037 0000000000000000000000000000000000000036 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 X
0000000000000000000000000000000000000036 0000000000000000000000000000000000000035 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 X
0000000000000000000000000000000000000035 0000000000000000000000000000000000000034 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000034 0000000000000000000000000000000000000033 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXX
0000000000000000000000000000000000000033 0000000000000000000000000000000000000032 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000032 0000000000000000000000000000000000000031 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000031 0000000000000000000000000000000000000030 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000030 000000000000000000000000000000000000002f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002f 000000000000000000000000000000000000002e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002e 000000000000000000000000000000000000002d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002d 000000000000000000000000000000000000002c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002c 000000000000000000000000000000000000002b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002b 000000000000000000000000000000000000002a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000002a 0000000000000000000000000000000000000029 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000029 0000000000000000000000000000000000000028 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000028 0000000000000000000000000000000000000027 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000027 0000000000000000000000000000000000000026 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000026 0000000000000000000000000000000000000025 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000025 0000000000000000000000000000000000000024 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000024 0000000000000000000000000000000000000023 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000023 0000000000000000000000000000000000000022 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000022 0000000000000000000000000000000000000021 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000021 0000000000000000000000000000000000000020 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000020 000000000000000000000000000000000000001f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001f 000000000000000000000000000000000000001e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001e 000000000000000000000000000000000000001d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001d 000000000000000000000000000000000000001c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001c 000000000000000000000000000000000000001b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001b 000000000000000000000000000000000000001a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000001a 0000000000000000000000000000000000000019 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000019 0000000000000000000000000000000000000018 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000018 0000000000000000000000000000000000000017 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000017 0000000000000000000000000000000000000016 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000016 0000000000000000000000000000000000000015 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000015 0000000000000000000000000000000000000014 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000014 0000000000000000000000000000000000000013 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000013 0000000000000000000000000000000000000012 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000012 0000000000000000000000000000000000000011 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000011 0000000000000000000000000000000000000010 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000010 000000000000000000000000000000000000000f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000f 000000000000000000000000000000000000000e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000e 000000000000000000000000000000000000000d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000d 000000000000000000000000000000000000000c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000c 000000000000000000000000000000000000000b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000b 000000000000000000000000000000000000000a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000000000000000000000a 0000000000000000000000000000000000000009 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000009 0000000000000000000000000000000000000008 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000008 0000000000000000000000000000000000000007 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000007 0000000000000000000000000000000000000006 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000006 0000000000000000000000000000000000000005 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000005 0000000000000000000000000000000000000004 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000004 0000000000000000000000000000000000000003 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000003 0000000000000000000000000000000000000002 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0000000000000000000000000000000000000002 0000000000000000000000000000000000000001 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Hi Christoph,
Quoted 3 lines · Christoph Mallon
% git rev-parse 'master@{52}'
warning: Log for ref refs/heads/master has gap after Thu, 1 Jan 1970 00:00:01 +0000. 0000000000000000000000000000000000000036
Can you say more? What output did you expect and how does this differ from it?
I tried, with git 2.2.0,
git init gitbug && cd gitbug && git commit --allow-empty -m a && wget http://tron.yamagi.org/zeug/reflog.bad && mv reflog.bad .git/logs/refs/heads/master && sha1sum .git/logs/refs/heads/master && git rev-parse 'master@{52}'
The output:
9ffe44715d0e542a60916255f144c74e6760ffd0 .git/logs/refs/heads/master 0000000000000000000000000000000000000035
Could you make a test script that illustrates and reproduces the problem? I.e., a patch to a file like t/t1410-reflog.sh, such that if I run
cd git make cd t ./t1410-reflog.sh
then I can reproduce the bug?
Thanks,
Jonathan
Hi Jonathan,
Am 02.12.14 00:35, schrieb Jonathan Nieder:
Quoted 7 lines
Quoted 3 lines · Christoph Mallon
% git rev-parse 'master@{52}'
warning: Log for ref refs/heads/master has gap after Thu, 1 Jan 1970 00:00:01 +0000. 0000000000000000000000000000000000000036Can you say more? What output did you expect and how does this differ from it?
sorry, I thought it is obvious that the warning should not be there. As far as I understand the code, this warning is shown, when the old commit id of one entry does not equal the new commit id of its predecessor. But this reflog file does not have such a gap.
Also the correct result ist 0...035, not 0...036.
I.e. one entry is erroneously skipped.
Quoted 9 lines
I tried, with git 2.2.0,
git init gitbug && cd gitbug && git commit --allow-empty -m a && wget http://tron.yamagi.org/zeug/reflog.bad && mv reflog.bad .git/logs/refs/heads/master && sha1sum .git/logs/refs/heads/master && git rev-parse 'master@{52}'
These steps look right.
Quoted 3 lines
The output:
9ffe44715d0e542a60916255f144c74e6760ffd0.git/logs/refs/heads/master
The checksum is fine.
Quoted 1 line
0000000000000000000000000000000000000035
You do not see the bug. |:
Quoted 3 lines
Could you make a test script that illustrates and reproduces the problem? I.e., a patch to a file like
t/t1410-reflog.sh[...]
http://tron.yamagi.org/zeug/0001-t1410-Test-erroneous-skipping-of-reflog-entries.patch
(also attached)
This test works for me at v2.0.4 and fails at v2.1.0 and up (v2.2.0, the current master).
Bisect says the symptom appears at 4207ed285f31ad3e04f08254237c0c1a1609642b.
Christoph
Quoted 1 line
From
82115da194adc42143b8603063e0a419fbbf4928Mon Sep 17 00:00:00 2001
From: Christoph Mallon <[email protected]>
Date: Tue, 2 Dec 2014 07:03:11 +0100
Subject: [PATCH] t1410: Test erroneous skipping of reflog entries.
--- t/t1410-reflog.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
t/t1410-reflog.sh +63 -0
@@ -287,4 +287,67 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' ' test_cmp expect actual ' +test_expect_success 'erroneous skipping of reflog entries' ' + git checkout -b reflogskip && + cat > .git/logs/refs/heads/reflogskip <<EOF && +0000000000000000000000000000000000000037 0000000000000000000000000000000000000036 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 X +0000000000000000000000000000000000000036 0000000000000000000000000000000000000035 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 X +0000000000000000000000000000000000000035 0000000000000000000000000000000000000034 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000034 0000000000000000000000000000000000000033 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXX +0000000000000000000000000000000000000033 0000000000000000000000000000000000000032 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000032 0000000000000000000000000000000000000031 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000031 0000000000000000000000000000000000000030 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000030 000000000000000000000000000000000000002f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002f 000000000000000000000000000000000000002e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002e 000000000000000000000000000000000000002d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002d 000000000000000000000000000000000000002c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002c 000000000000000000000000000000000000002b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002b 000000000000000000000000000000000000002a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000002a 0000000000000000000000000000000000000029 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000029 0000000000000000000000000000000000000028 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000028 0000000000000000000000000000000000000027 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000027 0000000000000000000000000000000000000026 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000026 0000000000000000000000000000000000000025 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000025 0000000000000000000000000000000000000024 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000024 0000000000000000000000000000000000000023 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000023 0000000000000000000000000000000000000022 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000022 0000000000000000000000000000000000000021 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000021 0000000000000000000000000000000000000020 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000020 000000000000000000000000000000000000001f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001f 000000000000000000000000000000000000001e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001e 000000000000000000000000000000000000001d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001d 000000000000000000000000000000000000001c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001c 000000000000000000000000000000000000001b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001b 000000000000000000000000000000000000001a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000001a 0000000000000000000000000000000000000019 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000019 0000000000000000000000000000000000000018 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000018 0000000000000000000000000000000000000017 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000017 0000000000000000000000000000000000000016 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000016 0000000000000000000000000000000000000015 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000015 0000000000000000000000000000000000000014 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000014 0000000000000000000000000000000000000013 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000013 0000000000000000000000000000000000000012 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000012 0000000000000000000000000000000000000011 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000011 0000000000000000000000000000000000000010 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000010 000000000000000000000000000000000000000f xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000f 000000000000000000000000000000000000000e xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000e 000000000000000000000000000000000000000d xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000d 000000000000000000000000000000000000000c xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000c 000000000000000000000000000000000000000b xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000b 000000000000000000000000000000000000000a xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +000000000000000000000000000000000000000a 0000000000000000000000000000000000000009 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000009 0000000000000000000000000000000000000008 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000008 0000000000000000000000000000000000000007 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000007 0000000000000000000000000000000000000006 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000006 0000000000000000000000000000000000000005 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000005 0000000000000000000000000000000000000004 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000004 0000000000000000000000000000000000000003 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000003 0000000000000000000000000000000000000002 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +0000000000000000000000000000000000000002 0000000000000000000000000000000000000001 xxxxxxxxxxxxxxxx <xxx@xxxxxxxxxxxxxxxxxxxxx> 0000000001 +0000 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +EOF + git rev-parse "@{52}" > actual 2>&1 && + echo "0000000000000000000000000000000000000035" > expect && + test_cmp expect actual +' + test_done
Signature · 1 line
2.1.2
Hi,
so I have installed git version 2.2.0 currently, because I was trying to reproduce "Bug in reflog of length 0x2BFF".
Now I was using git as a normal user, rebasing some stuff (incidentally the reflog improvements)
and an error occurred:
$ git rebase --continue error: Ref refs/heads/todo_sb13_ref-transactions-reflog-as-file is at c48602d0aaa11b9099440c647ac028604fde4b14 but expected d1bbdc6f161ae7550805d565cad1d930487dad34 fatal: update_ref failed for ref 'refs/heads/todo_sb13_ref-transactions-reflog-as-file': Cannot lock the ref 'refs/heads/todo_sb13_ref-transactions-reflog-as-file'.
So I think we definitely have a bug in the reflog code already in version 2.2.0.
Trying to reproduce the error did not yield success.
Thanks,
Stefan
Quoted 28 lines · Jonathan Nieder
Quoted 3 lines · Christoph Mallon
% git rev-parse 'master@{52}'
warning: Log for ref refs/heads/master has gap after Thu, 1 Jan 1970 00:00:01 +0000. 0000000000000000000000000000000000000036Can you say more? What output did you expect and how does this differ from it?
I tried, with git 2.2.0,
git init gitbug && cd gitbug && git commit --allow-empty -m a && wget http://tron.yamagi.org/zeug/reflog.bad && mv reflog.bad .git/logs/refs/heads/master && sha1sum .git/logs/refs/heads/master && git rev-parse 'master@{52}'The output:
9ffe44715d0e542a60916255f144c74e6760ffd0.git/logs/refs/heads/master 0000000000000000000000000000000000000035Could you make a test script that illustrates and reproduces the problem? I.e., a patch to a file like
t/t1410-reflog.sh, such that if I run
Quoted 6 lines
cd git make cd t ./t1410-reflog.shthen I can reproduce the bug?
Amen to that. I am getting the same thing.
Am 04.12.14 21:18, schrieb Junio C Hamano:
Quoted 5 lines
Quoted 4 lines · Jonathan Nieder
Could you make a test script that illustrates and reproduces the problem? I.e., a patch to a file like
t/t1410-reflog.sh, such that if I run
Quoted 8 lines
Quoted 6 lines
cd git make cd t ./t1410-reflog.shthen I can reproduce the bug?
Amen to that. I am getting the same thing.
I ran reproduce it reliably on multiple machines (OS X, FreeBSD, ia32, amd64), a friend of mine can, too.
I already sent a test-patch, here it is again:
http://tron.yamagi.org/zeug/0001-t1410-Test-erroneous-skipping-of-reflog-entries.patch Using this test, bisect reliably gives 4207ed285f31ad3e04f08254237c0c1a1609642b
as culprit.
It seems that Linux does not exhibit this particular behaviour. Maybe there are differences in memory allocation, which mask the symptom. Stefan Beller experienced some other sporadic bug regarding the reflog:
http://marc.info/?l=git&m=141748434801505&w=2
Quoted 11 lines · Christoph Mallon
Am 04.12.14 21:18, schrieb Junio C Hamano:
Quoted 10 lines
Quoted 9 lines · Jonathan Nieder
Could you make a test script that illustrates and reproduces the problem? I.e., a patch to a file like
t/t1410-reflog.sh, such that if I runcd git make cd t ./t1410-reflog.sh
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
then I can reproduce the bug?
Amen to that. I am getting the same thing.
I ran reproduce it reliably on multiple machines (OS X, FreeBSD, ia32, amd64), a friend of mine can, too.
Thanks, I was able to reproduce this easily on an OS X machine.
Does this patch fix your problem?
refs.c +1 -1
@@ -3052,7 +3052,7 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cint tz;/* old SP new SP name <email> SP time TAB msg LF */ - if (sb->len < 83 || sb->buf[sb->len - 1] != '\n' || + if (sb->len < 83 || get_sha1_hex(sb->buf, osha1) || sb->buf[40] != ' ' || get_sha1_hex(sb->buf + 41, nsha1) || sb->buf[81] != ' ' || !(email_end = strchr(sb->buf + 82, '>')) ||
I think the bug is in the reverse-reflog reader in for_each_reflog_ent_reverse. It reads BUFSIZ chunks of the file in reverse order, and then parses them individually. If the trailing newline for a line falls directly on the block boundary, we may not have it in our current block, and pass the line to show_one_reflog_ent without a trailing newline. That function is picky about making sure it got a full line.
So this is a long-standing bug in for_each_reflog_ent_reverse. It just showed up recently because we started using that function for read_ref_at_ent.
I haven't confirmed yet, but I suspect the problem shows up on OS X and FreeBSD but not Linux because of the definition of BUFSIZ (so it is really probably glibc versus BSD libc). The same bug exists on Linux, but you would need different input to stimulate the newline at the right spot.
The above is a workaround. I think the right solution is probably to teach for_each_reflog_ent_reverse to makes sure the trailing newline is included (either by tweaking the reverse code, or conditionally adding it to the parsed buffer).
-Peff
Quoted 6 lines · Jeff King
I think the bug is in the reverse-reflog reader in
for_each_reflog_ent_reverse. It reads BUFSIZ chunks of the file in reverse order, and then parses them individually. If the trailing newline for a line falls directly on the block boundary, we may not have it in our current block, and pass the line toshow_one_reflog_entwithout a trailing newline.
Ahh, thanks for helping spot it. A code that uses BUFSIZ explains why a single reproduction recipe is platform dependent.
Quoted 8 lines
So this is a long-standing bug in
for_each_reflog_ent_reverse. It just showed up recently because we started using that function forread_ref_at_ent.
...
The above is a workaround. I think the right solution is probably to teachfor_each_reflog_ent_reverseto makes sure the trailing newline is included (either by tweaking the reverse code, or conditionally adding it to the parsed buffer).
Sounds correct. Unfortunately I no longer remember how I decided to deal with a line that spans the block boundary in that piece of code X-<.
PATCH 1/1 for_each_reflog_ent_reverse: fix newlines on block boundaries
Quoted 11 lines · Junio C Hamano
Quoted 6 lines · Jeff King
I think the bug is in the reverse-reflog reader in
for_each_reflog_ent_reverse. It reads BUFSIZ chunks of the file in reverse order, and then parses them individually. If the trailing newline for a line falls directly on the block boundary, we may not have it in our current block, and pass the line toshow_one_reflog_entwithout a trailing newline.Ahh, thanks for helping spot it. A code that uses BUFSIZ explains why a single reproduction recipe is platform dependent.
It also makes writing portable tests annoying, but I think I managed it in the patch below. :)
Quoted 9 lines
Quoted 8 lines
So this is a long-standing bug in
for_each_reflog_ent_reverse. It just showed up recently because we started using that function forread_ref_at_ent.
...
The above is a workaround. I think the right solution is probably to teachfor_each_reflog_ent_reverseto makes sure the trailing newline is included (either by tweaking the reverse code, or conditionally adding it to the parsed buffer).
Quoted 3 lines
Sounds correct. Unfortunately I no longer remember how I decided to deal with a line that spans the block boundary in that piece of code X-<.
Here's my proposed fix.
-- >8 --
When we read a reflog file in reverse, we read whole chunks of BUFSIZ bytes, then loop over the buffer, parsing any lines we find. We find the beginning of each line by looking for the newline from the previous line. If we don't find one, we know that we are either at the beginning of the file, or that we have to read another block.
In the latter case, we stuff away what we have into a strbuf, read another block, and continue our parse. But we missed one case here. If we did find a newline, and it is at the beginning of the block, we must also stuff that newline into the strbuf, as it belongs to the block we are about to read.
The minimal fix here would be to add this special case to the conditional that checks whether we found a newline. But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and then at the end of each loop, stuff away any leftovers if necessary. That lets us fold this special-case in with the more common "we ended in the middle of a line" case.
---
I really needed this rearranging to figure out what the fix _should_ be. Now that I did that, I was able to write the above paragraph explaining what the minimal fix would be. And I can do that if we prefer. But I think the fact that I had to go through the untangling step first is an indication that maybe the end result is better. Of course that's all subjective. :)
I waffled on the test script between generating it on the fly (as below), and just including a complete 8K example that provokes the failure. I don't care about the size that much, but rather on which is more readable. My goal with showing the generation steps was to make it clear how we arrived there, but I fear it may have ended up too convoluted to do anyone any good. Opinions welcome.
refs.c | 47 ++++++++++++++++++++++++++++++++++++----------- t/t1410-reflog.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 11 deletions(-)
refs.c +36 -11
@@ -3404,24 +3404,49 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void bp =find_beginning_of_line (buf, scanp); -if (*bp !='\n' ) { -strbuf_splice (&sb,0 ,0 , buf, endp - buf); -if (pos) -break ;/* need to fill another block */ - scanp = buf -1 ;/* leave loop */ - }else { +if (*bp =='\n' ) {/* -* (bp + 1) thru endp is the beginning of the -* current line we have in sb +* The newline is the end of the previous line, +* so we know we have complete line starting +* at (bp + 1). Prefix it onto any prior data +* we collected for the line and process it. */ strbuf_splice (&sb,0 ,0 , bp +1 , endp - (bp +1 )); scanp = bp; endp = bp +1 ; + ret =show_one_reflog_ent (&sb, fn, cb_data); +strbuf_reset (&sb); +if (ret) +break ; + }else if (!pos) { +/* +* We are at the start of the buffer, and the +* start of the file; there is no previous +* line, and we have everything for this one. +* Process it, and we can end the loop. +*/ +strbuf_splice (&sb,0 ,0 , buf, endp - buf); + ret =show_one_reflog_ent (&sb, fn, cb_data); +strbuf_reset (&sb); +break ; } - ret =show_one_reflog_ent (&sb, fn, cb_data); -strbuf_reset (&sb); -if (ret) + +if (bp == buf) { +/* +* We are at the start of the buffer, and there +* is more file to read backwards. Which means +* we are in the middle of a line. Note that we +* may get here even if *bp was a newline; that +* just means we are at the exact end of the +* previous line, rather than some spot in the +* middle. +* +* Save away what we have to be combined with +* the data from the next read. +*/ +strbuf_splice (&sb,0 ,0 , buf, endp - buf);break ; + } } }
t/t1410-reflog.sh +30 -0
@@ -287,4 +287,34 @@ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' ' test_cmp expect actual ' +# Triggering the bug detected by this test requires a newline to fall +# exactly BUFSIZ-1 bytes from the end of the file. We don't know +# what that value is, since it's platform dependent. However, if +# we choose some value N, we also catch any D which divides N evenly +# (since we will read backwards in chunks of D). So we choose 8K, +# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). +# +# Each line is 114 characters, so we need 75 to still have a few before the +# last 8K. The 89-character padding on the final entry lines up our +# newline exactly. +test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' ' + git checkout -b reflogskip && + z38=00000000000000000000000000000000000000 && + ident="abc <xyz> 0000000001 +0000" && + for i in $(test_seq 1 75); do + printf "$z38%02d $z38%02d %s\t" $i $(($i+1)) "$ident" && + if test $i = 75; then + for j in $(test_seq 1 89); do + printf X + done + else + printf X + fi && + printf "\n" + done >.git/logs/refs/heads/reflogskip && + git rev-parse reflogskip@{73} >actual && + echo ${z38}03 >expect && + test_cmp expect actual +' + test_done
Signature · 1 line
2.2.0.390.gf60752d
PATCH 1/1 for_each_reflog_ent_reverse: turn leftover check into assertion
Quoted 8 lines · Jeff King
The minimal fix here would be to add this special case to the conditional that checks whether we found a newline. But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and then at the end of each loop, stuff away any leftovers if necessary. That lets us fold this special-case in with the more common "we ended in the middle of a line" case.
Quoted 8 lines
Signed-off-by Jeff King <[email protected]>---
I really needed this rearranging to figure out what the fix _should_ be. Now that I did that, I was able to write the above paragraph explaining what the minimal fix would be. And I can do that if we prefer. But I think the fact that I had to go through the untangling step first is an indication that maybe the end result is better. Of course that's all subjective. :)
I _think_ the patch below is also applicable to the code before my boundary-fixing patch. But the rearranging also made me more confident in it.
-- >8 --
Subject: for_each_reflog_ent_reverse: turn leftover check into assertion
Our loop should always process all lines, even if we hit the beginning of the file. We have a conditional after the loop ends to double-check that there is nothing left and to process it. But this should never happen, and is a sign of a logic bug in the loop. Let's turn it into a BUG assertion.
---
Of course I cannot say something like "this can never happen; the old code was wrong to handle this case" without a nagging feeling that I am missing something, so extra careful eyes are appreciated (and are why I would rather have an assert here than removing the code and silently dropping lines if I am wrong).
refs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
refs.c +1 -1
@@ -3451,7 +3451,7 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void }if (!ret && sb.len) - ret =show_one_reflog_ent (&sb, fn, cb_data); +die ("BUG: reverse reflog parser had leftover data" );fclose (logfp);strbuf_release (&sb);
Signature · 1 line
2.2.0.390.gf60752d
Re: [PATCH] for_each_reflog_ent_reverse: turn leftover check into assertion
Quoted 3 lines · Jeff King
I _think_ the patch below is also applicable to the code before my boundary-fixing patch. But the rearranging also made me more confident in it.
Yeah, thanks for a fix.
Quoted 33 lines
-- >8 --
Subject:for_each_reflog_ent_reverse: turn leftover check into assertionOur loop should always process all lines, even if we hit the beginning of the file. We have a conditional after the loop ends to double-check that there is nothing left and to process it. But this should never happen, and is a sign of a logic bug in the loop. Let's turn it into a BUG assertion.
Signed-off-by Jeff King <[email protected]>---
Of course I cannot say something like "this can never happen; the old code was wrong to handle this case" without a nagging feeling that I am missing something, so extra careful eyes are appreciated (and are why I would rather have an assert here than removing the code and silently dropping lines if I am wrong).refs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)refs.c +1
-1@@ -3451,7 +3451,7 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void }if (!ret && sb.len) - ret =show_one_reflog_ent (&sb, fn, cb_data); +die ("BUG: reverse reflog parser had leftover data" );fclose (logfp);strbuf_release (&sb);
Quoted 3 lines · Christoph Mallon
Quoted 1 line
Amen to that. I am getting the same thing.
I ran reproduce it reliably on multiple machines (OS X, FreeBSD, ia32,
Oh, I do not doubt you see a problem. I am just saying that I don't have an easy entry to the issue without it reproducing for me.
This commit seems to introduce the bug:4207ed285f31ad3e04f08254237c0c1a1609642b
So I am running a 3.13.0-40-generic x86_64 linux (so its's amd64) and git version 2.1.2
and I cannot reproduce the bug you are describing. :(
$ git rev-parse 'master@{52}'
0000000000000000000000000000000000000035What I noticed though is there are 2 linefeeds at the end of each line, is that intended or did it break during transmission?
Stefan
Am 01.12.14 19:53, schrieb Stefan Beller:
Quoted 3 lines
So I am running a 3.13.0-40-generic
x86_64linux (so its's amd64) and git version 2.1.2
and I cannot reproduce the bug you are describing. :(
):
I can reproduce it with
* OS X, i386 binary, git 2.2.0
* FreeBSD, amd64, git 2.1.0 and up (bisected it there)
* FreeBSD, amd64, git 2.1.2 (different machine)
I cannot reproduce it with
* Linux, amd64, git 2.1.0
Quoted 2 lines
$ git rev-parse 'master@{52}'
0000000000000000000000000000000000000035On a machine, where you see the bug, you get entry /0...036/. This btw causes havoc:
git stash list shows all entries, but e.g. git stash drop drops the wrong stash after @{52}.
Quoted 2 lines
What I noticed though is there are 2 linefeeds at the end of each line, is that intended or did it break during transmission?
That broke.
It should be a normal reflog file.
Try this:
http://tron.yamagi.org/zeug/reflog.bad
Still 4207ed285f31ad3e04f08254237c0c1a1609642b seems a plausible cause, because it's about reflogs.
Though I suspect the actual bug was introduced before, because this commit only uses machinery, which was added earlier.
Christoph