git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
From: Max Kirillov <max@max630.net>
To: Git List <git@vger.kernel.org>, Eric Sunshine <sunshine@sunshineco.com>
Cc: Max Kirillov <max@max630.net>, Michael Haggerty <mhagger@alum.mit.edu>
Subject: [PATCH v2] pack-refs: fail on falsely sorted packed-refs
Date: Fri,  8 Feb 2019 23:22:21 +0200
Message-ID: <20190208212221.31670-1-max@max630.net> (raw)
In-Reply-To: <CAPig+cTn2gURyQgWHZQMNf2cZ+zwFhbH1Q4iPmbwuvYjMrPZPg@mail.gmail.com>

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, though it is listed by commands which output
the references list.

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>
---
Fixed the notes
 refs/packed-backend.c               | 18 ++++++++++++++++++
 t/t3212-pack-refs-broken-sorting.sh | 26 ++++++++++++++++++++++++++
 2 files changed, 44 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..c89a5eb899 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,21 @@ 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);
+				strbuf_release(&prev_ref);
+				goto error;
+			}
+
+			strbuf_init(&prev_ref, 0);
+			strbuf_addstr(&prev_ref, iter->refname);
+		}
+
 		if (i >= updates->nr) {
 			cmp = -1;
 		} else {
@@ -1240,6 +1256,8 @@ static int write_with_updates(struct packed_ref_store *refs,
 		}
 	}
 
+	strbuf_release(&prev_ref);
+
 	if (ok != ITER_DONE) {
 		strbuf_addstr(err, "unable to write packed-refs file: "
 			      "error iterating over old contents");
diff --git a/t/t3212-pack-refs-broken-sorting.sh b/t/t3212-pack-refs-broken-sorting.sh
new file mode 100755
index 0000000000..a44785c8fc
--- /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) || return 1
+	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' '
+	test_must_fail git show-ref --verify --quiet refs/heads/b00
+'
+
+test_expect_success 'subsequent pack-refs fails' '
+	test_must_fail git pack-refs --all
+'
+
+test_done
-- 
2.19.0.1202.g68e1e8f04e


  parent reply index

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-30 23:13 [RFC PATCH] " Max Kirillov
2019-01-30 23:31 ` Eric Sunshine
2019-01-31  8:21   ` Max Kirillov
2019-02-08 21:22   ` Max Kirillov [this message]
2019-02-08 21:40     ` [PATCH v2] " 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 publically 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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190208212221.31670-1-max@max630.net \
    --to=max@max630.net \
    --cc=git@vger.kernel.org \
    --cc=mhagger@alum.mit.edu \
    --cc=sunshine@sunshineco.com \
    /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

git@vger.kernel.org list mirror (unofficial, one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox