[PATCH v2 0/3] refs/reftable: fix on-disk representation of reflog timezones
- From
Patrick Steinhardt <ps@pks.im>
- Date
- Oct 1, 2026, 05:38 UTC
- Message-ID
- <20261001-pks-reftables-fix-timezone-format-v2-0-a4fd1f7cd21a@pks.im>
- In-Reply-To
- <20260929-pks-reftables-fix-timezone-format-v1-0-3df105a95ed1@pks.im>
Hi,
it was reported [1] that the way we store reflog timezones with the reftable format has a mismatch with the reftable specification. While the spec says that reftables should be stored as a signed offset in minutes, we store them in the "[+-]HHMM" format that we typically use in commit headers, for example.
This patch series fixes this bug by making our on-disk representation match the specification. This will of course make us reinterpret old reftables. But ultimately, the fallout caused by this change is somewhat limited as we only ever use reflog timezones for display purposes. So yes, we'll display a wrong timezone. But it's not used as part of any kind of computations.
The series is built on top of v2.56.0.
Changes in v2:
- Improve readability of one of the converted sites that now use
`minutes_to_tz()`.
- Improve test coverage.
- Link to v1: https://patch.msgid.link/20260929-pks-reftables-fix-timezone-format-v1-0-3df105a95ed1@pks.imThanks!
Patrick
[1]: <85f7daa8-d60b-4348-ac2f-b1a68628af7b@app.fastmail.com>
---
Patrick Steinhardt (3):
date: add helpers to convert between "+HHMM" timezones and minutes
t/helper: fix segfault in "dump-reftable -t"
refs/reftable: fix on-disk representation of reflog timezonesapply.c | 3 ++- date.c | 25 +++++++++++++++++-------- date.h | 9 +++++++++ refs/reftable-backend.c | 7 ++++--- strbuf.c | 3 +-- t/helper/test-reftable.c | 13 +++++++++++-- t/t0610-reftable-basics.sh | 35 +++++++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 16 deletions(-)
Range-diff versus v1:
1: 91b9739506 ! 1: 4f950cf7de date: add helpers to convert between "+HHMM" timezones and minutes
@@ date.c: static int local_time_tzoffset(time_t t, struct tm *tm)
offset /= 60; /* in minutes */
- offset = (offset % 60) + ((offset / 60) * 100);
- return offset * eastwest;
-+ return minutes_to_tz(offset * eastwest);
++ return minutes_to_tz(offset) * eastwest;
}
/*
2: 112e414c34 = 2: 9ef28821a3 t/helper: fix segfault in "dump-reftable -t"
3: 26eee10d6a ! 3: c66e467554 refs/reftable: fix on-disk representation of reflog timezones
@@ t/t0610-reftable-basics.sh: test_expect_success 'reflog: renaming branch writes
+ cd repo &&
+ GIT_COMMITTER_DATE="1234567890 -1200" git commit --allow-empty -m min &&
+ GIT_COMMITTER_DATE="1234567890 +0530" git commit --allow-empty -m east &&
-+ GIT_COMMITTER_DATE="1234567890 -0800" git commit --allow-empty -m west &&
++ GIT_COMMITTER_DATE="1234567890 -0830" git commit --allow-empty -m west &&
+ GIT_COMMITTER_DATE="1234567890 +1400" git commit --allow-empty -m max &&
+
+ # The reftable format specifies the timezone as the offset from
@@ t/t0610-reftable-basics.sh: test_expect_success 'reflog: renaming branch writes
+ sed -n "s/^log{refs\/heads\/main([0-9]*) .* 1234567890 //p" dump >actual &&
+ cat >expect <<-\EOF &&
+ 840
-+ -480
++ -510
+ 330
+ -720
+ EOF
@@ t/t0610-reftable-basics.sh: test_expect_success 'reflog: renaming branch writes
+ test-tool ref-store main for-each-reflog-ent refs/heads/main >entries &&
+ test_grep "1234567890 -1200 commit (initial): min" entries &&
+ test_grep "1234567890 +0530 commit: east" entries &&
-+ test_grep "1234567890 -0800 commit: west" entries &&
++ test_grep "1234567890 -0830 commit: west" entries &&
+ test_grep "1234567890 +1400 commit: max" entries
+ )
+'--- base-commit: a018953688f1b10bddf91bff8747068f5f4746a4 change-id: 20260929-pks-reftables-fix-timezone-format-93ecd0e7a1d1