From: Max Kirillov <max@max630.net>
To: Michael Haggerty <mhagger@alum.mit.edu>
Cc: Max Kirillov <max@max630.net>, git@vger.kernel.org
Subject: [RFC PATCH] pack-refs: fail on falsely sorted packed-refs
Date: Thu, 31 Jan 2019 01:13:59 +0200 [thread overview]
Message-ID: <20190130231359.23978-1-max@max630.net> (raw)
If packed-refs is marked as sorted but not really sorted it causes
very hard to comprehend misbehavior of reference resolving - a reference
is reported as not found.
As the scope of the issue is not clear, make it visible by failing
pack-refs command - the one which would not suffer performance penalty
to verify the sortedness - when it encounters not really sorted existing
data.
Signed-off-by: Max Kirillov <max@max630.net>
---
I happened to have a not really sorted packed-refs file. As you might guess,
it was quite wtf-ing experience. It worked, mostly, but there was one branch
which just did not resolve, regardless of existing and being presented in
for-each-refs output.
I don't know where the corruption came from. I should admit it could even be a manual
editing but last time I did it (in that reporitory) was several years ago so it is unlikely.
I am not sure what should be the proper fix. I did a minimal detection, so that
it does not go unnoticed. Probably next step would be either fixing in `git fsck` call.
refs/packed-backend.c | 15 +++++++++++++++
t/t3212-pack-refs-broken-sorting.sh | 26 ++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100755 t/t3212-pack-refs-broken-sorting.sh
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index c01c7f5901..505f4535b5 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1088,6 +1088,7 @@ static int write_with_updates(struct packed_ref_store *refs,
FILE *out;
struct strbuf sb = STRBUF_INIT;
char *packed_refs_path;
+ struct strbuf prev_ref = STRBUF_INIT;
if (!is_lock_file_locked(&refs->lock))
BUG("write_with_updates() called while unlocked");
@@ -1137,6 +1138,20 @@ static int write_with_updates(struct packed_ref_store *refs,
struct ref_update *update = NULL;
int cmp;
+ if (iter)
+ {
+ if (prev_ref.len && strcmp(prev_ref.buf, iter->refname) > 0)
+ {
+ strbuf_addf(err, "broken sorting in packed-refs: '%s' > '%s'",
+ prev_ref.buf,
+ iter->refname);
+ goto error;
+ }
+
+ strbuf_init(&prev_ref, 0);
+ strbuf_addstr(&prev_ref, iter->refname);
+ }
+
if (i >= updates->nr) {
cmp = -1;
} else {
diff --git a/t/t3212-pack-refs-broken-sorting.sh b/t/t3212-pack-refs-broken-sorting.sh
new file mode 100755
index 0000000000..37a98a6fb1
--- /dev/null
+++ b/t/t3212-pack-refs-broken-sorting.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test_description='tests for the falsely sorted refs'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ git commit --allow-empty -m commit &&
+ for num in $(test_seq 10)
+ do
+ git branch b$(printf "%02d" $num) || break
+ done &&
+ git pack-refs --all &&
+ head_object=$(git rev-parse HEAD) &&
+ printf "$head_object refs/heads/b00\\n" >>.git/packed-refs &&
+ git branch b11
+'
+
+test_expect_success 'off-order branch not found' '
+ ! git show-ref --verify --quiet refs/heads/b00
+'
+
+test_expect_success 'subsequent pack-refs fails' '
+ ! git pack-refs --all
+'
+
+test_done
--
2.19.0.1202.g68e1e8f04e
next reply other threads:[~2019-01-30 23:21 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-30 23:13 Max Kirillov [this message]
2019-01-30 23:31 ` [RFC PATCH] pack-refs: fail on falsely sorted packed-refs Eric Sunshine
2019-01-31 8:21 ` Max Kirillov
2019-02-08 21:22 ` [PATCH v2] " Max Kirillov
2019-02-08 21:40 ` Eric Sunshine
2019-02-13 4:24 ` Max Kirillov
[not found] ` <CAMy9T_EX_L80-V4zD626nFCxw6qa90+pZwcbd6wHw9ZHcj2rNA@mail.gmail.com>
2019-02-13 4:23 ` Max Kirillov
2019-02-13 10:08 ` [RFC PATCH] " Ævar Arnfjörð Bjarmason
2019-02-13 10:56 ` SZEDER Gábor
2019-02-23 7:10 ` Max Kirillov
2019-02-14 6:06 ` Jeff King
2019-02-23 7:09 ` Max Kirillov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190130231359.23978-1-max@max630.net \
--to=max@max630.net \
--cc=git@vger.kernel.org \
--cc=mhagger@alum.mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).