From patchwork Tue Feb 20 09:06:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563681 Received: from wfhigh6-smtp.messagingengine.com (wfhigh6-smtp.messagingengine.com [64.147.123.157]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5771660DDE for ; Tue, 20 Feb 2024 09:06:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419987; cv=none; b=GVsQzwWj+ODXgztYitkdGWBU1oQ1IKwj3iIpuxagPhg88vxT1qsaLJq5FLmSCBDVor5KqtiUwR4Y8Pm3MU9awcKWerVp/a/QNRdA+9qJU4Ebt0ugKz4yb8wrXWEnlIgSBfdqhN8cvsYn4xYz7ubjBLpeHazBkMswxRDdV8uBHBk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419987; c=relaxed/simple; bh=n8mvr86/X/TM8SXaacNf9sp06VOrX9f2zcyKwrYbFCU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=GRTYt0D9hTB0ahyg8HLDw1bw4MbTHVyfA/ipTBoF6k59dNINCRSQp8+EczqQwnN22Nn+2XstJEJhQoczI3wJwd//WFdZQmgDpQp2+PF5Nqh1ruZNI38noMJWwb44VI3rAQ5SlJCmTDwqghnuMXQrrRY29yN1pvupyAa9CL9JAp8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=I5RVAfbP; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Y9RkeEZp; arc=none smtp.client-ip=64.147.123.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="I5RVAfbP"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Y9RkeEZp" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfhigh.west.internal (Postfix) with ESMTP id 777951800081; Tue, 20 Feb 2024 04:06:25 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Tue, 20 Feb 2024 04:06:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708419984; x=1708506384; bh=eQ2wBbEoqS dnK5w3KA0gu9hDkEB80ZxuU+7XcyxTeHs=; b=I5RVAfbPtOBoUzSxmLlpkV4qwu tSr3LVaGAY2s3Si2TAoUGtk93eP2ghtDTE7jP5D2+FmB9koVfN8Y/p4nwmdoM7Gg cjEevpyz3vhdpALHRD0UMVrfltR6sAXfQdezfS1OajBdtCyvZBg+kvWUL1txsmik fEexs1H+aj4qSV5wfRSfn3OybFNai2Nk3aCv1I7CLjJZKnBYd1JktX7++8Za9/hz 3mzrYVNAmOc05KiiKB32J4DkjPu7s8cL61m0pJ6N1N80nclADJjXpVmZHFw0M/Z5 HLHUz8hUint36jsUHi137QWbJN1vUNBLXaDnk9+rDsQtpJBv5Y93f1tXG4Ng== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708419984; x=1708506384; bh=eQ2wBbEoqSdnK5w3KA0gu9hDkEB8 0ZxuU+7XcyxTeHs=; b=Y9RkeEZpro2LzW7HL79SIWenF2G1WdZ7+iqHgMPz8elh 2Kd1TLDImPFbwxsgT7UKzmpLiCrBMpezt5S64pgE0J5vHqEEIfHKDQd+fTKKkIdt kFJ37uh9pLJ/r8ypK46q2Nv+8m0aoyxxNzKaRDJk+2ZpH+JCfoJa9NnwpFdPXo6Q g3AsxL2r8ypCbdwCeurDkvpoPHgQT12nLjMBNV9yKXPHKVYub0BSLKH6y0yGELTl 8QnvZmMVZssKiyGh0kietWTNo73dtVXXa8m+6FHEOlZ5V5HSkUCkPOwaBJYGSkNa ZpVdm5y6sTJtx74lRZaWlgx18awqOj7KvZ/9OVol5g== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:24 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id ec88437e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:21 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:22 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 1/7] dir-iterator: pass name to `prepare_next_entry_data()` directly Message-ID: <12de25dfe24d61ef54e0ccc0ebd4cc69d73da50c.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: When adding the next directory entry for `struct dir_iterator` we pass the complete `struct dirent *` to `prepare_next_entry_data()` even though we only need the entry's name. Refactor the code to pass in the name, only. This prepares for a subsequent commit where we introduce the ability to iterate through dir entries in an ordered manner. Signed-off-by: Patrick Steinhardt --- dir-iterator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index 278b04243a..f58a97e089 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -94,15 +94,15 @@ static int pop_level(struct dir_iterator_int *iter) /* * Populate iter->base with the necessary information on the next iteration - * entry, represented by the given dirent de. Return 0 on success and -1 + * entry, represented by the given name. Return 0 on success and -1 * otherwise, setting errno accordingly. */ static int prepare_next_entry_data(struct dir_iterator_int *iter, - struct dirent *de) + const char *name) { int err, saved_errno; - strbuf_addstr(&iter->base.path, de->d_name); + strbuf_addstr(&iter->base.path, name); /* * We have to reset these because the path strbuf might have * been realloc()ed at the previous strbuf_addstr(). @@ -159,7 +159,7 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) if (is_dot_or_dotdot(de->d_name)) continue; - if (prepare_next_entry_data(iter, de)) { + if (prepare_next_entry_data(iter, de->d_name)) { if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC) goto error_out; continue; From patchwork Tue Feb 20 09:06:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563682 Received: from wfout6-smtp.messagingengine.com (wfout6-smtp.messagingengine.com [64.147.123.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 569D060DFC for ; Tue, 20 Feb 2024 09:06:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.149 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419992; cv=none; b=GQIB3Ku8gnMN/lArRhCQv00ZEe5qfQuW2d6blKRaUWIO2ES2lO6fqmj7IsFX+XPKtozBeUI8k0OdipqBNWcOZtAdiPgX/hpZzcij8Xe6ZANxZv1ROT4FtPa8jaay0izeRtHyuD87mZ7/aNgmGZi6FDTPSCKkp7ICQ7Ovlupcw18= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419992; c=relaxed/simple; bh=0lz8zuIdYdbMvgFrZUpKjAyAvf7UpX1RXhWdmyhMRJI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=ag8+jVC0GDF3OprDq1MOSgiD+B77v0k7vSVkps7rNFUc/ySVMuuBKlcgEiM+ICPY4s8ZtsnuOk6DK94Z+Fjc1N0q8TicoWvHLaMuqBvVNm/33x4ysSigPf3YMc04MDbUGoBKrPdkLEeWYx3Ee//UIV0dQLsTq9i9zDOzeeNOOk4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=qtRv09ZN; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=qlUino8F; arc=none smtp.client-ip=64.147.123.149 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="qtRv09ZN"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="qlUino8F" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfout.west.internal (Postfix) with ESMTP id 5BC821C0009F; Tue, 20 Feb 2024 04:06:29 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Tue, 20 Feb 2024 04:06:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708419988; x=1708506388; bh=iVX+VFP4f1 836w9OxLIdTwhcqgaBkj7n8lAv+1z0ggw=; b=qtRv09ZNPgKeBlxCrnVdV+L76E eBoeC941sOLYhxS3rKZ+tDoQ5yDQMfRGG4TNySBs/v8SFbcklD5p0dG7zfKYpZ9w 5mFIbQCPCmm7aYfGEJNyylJWBAPf8dPOk9KiPp9w382Ta3qBRY5EmRa77KVxOEFm 2MWs/dEmmR8P5nmdAYU1fwsl1iwWkXgpx8qETqBkuBLgIR9IKSQytDL4U8iGn8Gn jbfMTOTW8mZHrjBCbxgPlhr9E1XrgOL8T12yO5I469923EUmVoO7tc5hNq8eIL2m uPko/wqY/kGetJt9q5Y4a4OQ/iQzBDUd3NDiUfRlZTNaOaowBk9KElA4tH7w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708419988; x=1708506388; bh=iVX+VFP4f1836w9OxLIdTwhcqgaB kj7n8lAv+1z0ggw=; b=qlUino8FZZX5YbypxjwUmUBhpT7ftk8N1r7Ua8B2uRkE DJQSIEneqflfwSWf5i9tBifgjmSZ69+xeYMBIWZKq5EJonUU34Fn2qOZpqL4AxMP j7FtyBl1p6VGZsq56TfAKJxGQxRoDVApscM6tfUygGrxMJ1L532shTKgEGit6HdY tTKSKH3B3VGowHSmoP0ifhvP6i1tLHxqYw7yhbcIXvoUS9YuL16g9r2zKEFF8NPt umk92aOvc4VI2H+GSGbZFIFufBxe3kQN8rYJITro+5zUipDYd6SIkcIUJRCzNkM0 e3CD8Tvlur66oDBwuNoiFKOz2Sk/7gEtVwPBCezNuA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:28 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id d57836f2 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:25 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:26 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 2/7] dir-iterator: support iteration in sorted order Message-ID: <788afce189ce7ca7cb1ddc9706acb710ca73ee80.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The `struct dir_iterator` is a helper that allows us to iterate through directory entries. This iterator returns entries in the exact same order as readdir(3P) does -- or in other words, it guarantees no specific order at all. This is about to become problematic as we are introducing a new reflog subcommand to list reflogs. As the "files" backend uses the directory iterator to enumerate reflogs, returning reflog names and exposing them to the user would inherit the indeterministic ordering. Naturally, it would make for a terrible user interface to show a list with no discernible order. While this could be handled at a higher level by the new subcommand itself by collecting and ordering the reflogs, this would be inefficient because we would first have to collect all reflogs before we can sort them, which would introduce additional latency when there are many reflogs. Instead, introduce a new option into the directory iterator that asks for its entries to be yielded in lexicographical order. If set, the iterator will read all directory entries greedily and sort them before we start to iterate over them. While this will of course also incur overhead as we cannot yield the directory entries immediately, it should at least be more efficient than having to sort the complete list of reflogs as we only need to sort one directory at a time. This functionality will be used in a follow-up commit. Signed-off-by: Patrick Steinhardt --- dir-iterator.c | 99 +++++++++++++++++++++++++++++++++++++++++++------- dir-iterator.h | 3 ++ 2 files changed, 89 insertions(+), 13 deletions(-) diff --git a/dir-iterator.c b/dir-iterator.c index f58a97e089..de619846f2 100644 --- a/dir-iterator.c +++ b/dir-iterator.c @@ -2,10 +2,19 @@ #include "dir.h" #include "iterator.h" #include "dir-iterator.h" +#include "string-list.h" struct dir_iterator_level { DIR *dir; + /* + * The directory entries of the current level. This list will only be + * populated when the iterator is ordered. In that case, `dir` will be + * set to `NULL`. + */ + struct string_list entries; + size_t entries_idx; + /* * The length of the directory part of path at this level * (including a trailing '/'): @@ -43,6 +52,31 @@ struct dir_iterator_int { unsigned int flags; }; +static int next_directory_entry(DIR *dir, const char *path, + struct dirent **out) +{ + struct dirent *de; + +repeat: + errno = 0; + de = readdir(dir); + if (!de) { + if (errno) { + warning_errno("error reading directory '%s'", + path); + return -1; + } + + return 1; + } + + if (is_dot_or_dotdot(de->d_name)) + goto repeat; + + *out = de; + return 0; +} + /* * Push a level in the iter stack and initialize it with information from * the directory pointed by iter->base->path. It is assumed that this @@ -72,6 +106,35 @@ static int push_level(struct dir_iterator_int *iter) return -1; } + string_list_init_dup(&level->entries); + level->entries_idx = 0; + + /* + * When the iterator is sorted we read and sort all directory entries + * directly. + */ + if (iter->flags & DIR_ITERATOR_SORTED) { + struct dirent *de; + + while (1) { + int ret = next_directory_entry(level->dir, iter->base.path.buf, &de); + if (ret < 0) { + if (errno != ENOENT && + iter->flags & DIR_ITERATOR_PEDANTIC) + return -1; + continue; + } else if (ret > 0) { + break; + } + + string_list_append(&level->entries, de->d_name); + } + string_list_sort(&level->entries); + + closedir(level->dir); + level->dir = NULL; + } + return 0; } @@ -88,6 +151,7 @@ static int pop_level(struct dir_iterator_int *iter) warning_errno("error closing directory '%s'", iter->base.path.buf); level->dir = NULL; + string_list_clear(&level->entries, 0); return --iter->levels_nr; } @@ -139,27 +203,34 @@ int dir_iterator_advance(struct dir_iterator *dir_iterator) struct dirent *de; struct dir_iterator_level *level = &iter->levels[iter->levels_nr - 1]; + const char *name; strbuf_setlen(&iter->base.path, level->prefix_len); - errno = 0; - de = readdir(level->dir); - if (!de) { - if (errno) { - warning_errno("error reading directory '%s'", - iter->base.path.buf); + if (level->dir) { + int ret = next_directory_entry(level->dir, iter->base.path.buf, &de); + if (ret < 0) { if (iter->flags & DIR_ITERATOR_PEDANTIC) goto error_out; - } else if (pop_level(iter) == 0) { - return dir_iterator_abort(dir_iterator); + continue; + } else if (ret > 0) { + if (pop_level(iter) == 0) + return dir_iterator_abort(dir_iterator); + continue; } - continue; - } - if (is_dot_or_dotdot(de->d_name)) - continue; + name = de->d_name; + } else { + if (level->entries_idx >= level->entries.nr) { + if (pop_level(iter) == 0) + return dir_iterator_abort(dir_iterator); + continue; + } - if (prepare_next_entry_data(iter, de->d_name)) { + name = level->entries.items[level->entries_idx++].string; + } + + if (prepare_next_entry_data(iter, name)) { if (errno != ENOENT && iter->flags & DIR_ITERATOR_PEDANTIC) goto error_out; continue; @@ -188,6 +259,8 @@ int dir_iterator_abort(struct dir_iterator *dir_iterator) warning_errno("error closing directory '%s'", iter->base.path.buf); } + + string_list_clear(&level->entries, 0); } free(iter->levels); diff --git a/dir-iterator.h b/dir-iterator.h index 479e1ec784..6d438809b6 100644 --- a/dir-iterator.h +++ b/dir-iterator.h @@ -54,8 +54,11 @@ * and ITER_ERROR is returned immediately. In both cases, a meaningful * warning is emitted. Note: ENOENT errors are always ignored so that * the API users may remove files during iteration. + * + * - DIR_ITERATOR_SORTED: sort directory entries alphabetically. */ #define DIR_ITERATOR_PEDANTIC (1 << 0) +#define DIR_ITERATOR_SORTED (1 << 1) struct dir_iterator { /* The current path: */ From patchwork Tue Feb 20 09:06:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563683 Received: from wfout6-smtp.messagingengine.com (wfout6-smtp.messagingengine.com [64.147.123.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1464A60EE3 for ; Tue, 20 Feb 2024 09:06:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.149 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419995; cv=none; b=tSB4Eo82RWTtSJUF2kI5NveTk67sol8RZvOYY7ikbz7KsZQVEIlqdtpDhcmbz4xdAfQftbr/0Av0zySyRKCK36XEv7Xo+mvaeVDbVHBGAEHXSHigwCG9l5qwjvTDFoGhuDmI+IOtnpARHwjNzLy6+rhh0gE+kWx6g9fbjzrL/r8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708419995; c=relaxed/simple; bh=Fa5op0+yjRc9hfzxhhWzx9Xpr4dHzGhPob0JkO4R0AY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=T43ND6Qub76OGTe/YsYPm4DGOi0cAxbfwvq3i9Qrjbfl8CPmVATD4x3br6c2rW2LVx7n6fsC2QVk+iESSdrWjmifd7YWW/l34anMlUXFbliXB308FQ95QkWlwGxFtgLTvXBBcwt/dHG4LbrvZI0p0auaB9iewRLNOpj7d62D4is= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=pZqvHqaq; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=aRn9fRMS; arc=none smtp.client-ip=64.147.123.149 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="pZqvHqaq"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="aRn9fRMS" Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailfout.west.internal (Postfix) with ESMTP id 36EB81C000AD; Tue, 20 Feb 2024 04:06:33 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Tue, 20 Feb 2024 04:06:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708419992; x=1708506392; bh=EI8QJ8sSkF mZdbTHrCGrFE18VpOynePNIOs0ruYt3+0=; b=pZqvHqaq1yH2s0hKw+8yEBv1xv nMBSOI2zJVKvuv3aLQP4/sLe+xjOJJJq7lB8n8Syyu0Z8qPh3ala4Ge0cARhmJ9M EEK68JC1RKTCtXwRui+qDtcLx0yTovBgr+GcuhuN3EsCgmPpV5fnRCDfiCsx+sHw AnxgBGZ+Yv3fx67xCL9DeRnEF9T4cv3hrGFEpI8dj1/T/9mhQG2BU3X5rnHOyIf9 z9mY0/OJyRBpIQx0WDv1/QAIII87mvpzkOYSqQqPTaMwywXQCuE9OvIeSDw9gPHo jSp/xBS2YsfEqz0lfV56lKTbdE7eFlDQQq4HZQMy0aMqsiU17xqzOGrGkm4Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708419992; x=1708506392; bh=EI8QJ8sSkFmZdbTHrCGrFE18VpOy nePNIOs0ruYt3+0=; b=aRn9fRMSpxslvBSGpze8KEM5DokkYurTsVWOEvKG/a+W /mnc6fTzSIOw/YTepd72B3t7faKb2BGay2v/wwkSR5ZqqxepFItuhIjxDNlO3+tr zTjFhtYvuxGnmRnLcr2iambOVDK3PuW5e/B33EwuCAxh45NwIbyLdLc0XKcNAPm8 pzrejtR9x+GnSN0czcJBIU35jnBL9zhaMEnXmzDygcd5mt110rXnHswYzANuBF4z NieVE457/EqOjCT2Ma+/gMMip0S/0K/kahiesfO/CGjpkqQEG1/9e69jlcoWjXeM e0MWH9Y0SX1lA7eU7XxJbi6ofIt+C29rjGcw585iNw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:31 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 53703527 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:30 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:30 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 3/7] refs/files: sort reflogs returned by the reflog iterator Message-ID: <32b24a3d4b91a6073bb1a677080c74da828811a3.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We use a directory iterator to return reflogs via the reflog iterator. This iterator returns entries in the same order as readdir(3P) would and will thus yield reflogs with no discernible order. Set the new `DIR_ITERATOR_SORTED` flag that was introduced in the preceding commit so that the order is deterministic. While the effect of this can only been observed in a test tool, a subsequent commit will start to expose this functionality to users via a new `git reflog list` subcommand. Signed-off-by: Patrick Steinhardt --- refs/files-backend.c | 6 +++--- t/t0600-reffiles-backend.sh | 4 ++-- t/t1405-main-ref-store.sh | 2 +- t/t1406-submodule-ref-store.sh | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 75dcc21ecb..a7b7cdef36 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2193,7 +2193,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, strbuf_addf(&sb, "%s/logs", gitdir); - diter = dir_iterator_begin(sb.buf, 0); + diter = dir_iterator_begin(sb.buf, DIR_ITERATOR_SORTED); if (!diter) { strbuf_release(&sb); return empty_ref_iterator_begin(); @@ -2202,7 +2202,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0); + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 1); iter->dir_iterator = diter; iter->ref_store = ref_store; strbuf_release(&sb); @@ -2246,7 +2246,7 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st return reflog_iterator_begin(ref_store, refs->gitcommondir); } else { return merge_ref_iterator_begin( - 0, reflog_iterator_begin(ref_store, refs->base.gitdir), + 1, reflog_iterator_begin(ref_store, refs->base.gitdir), reflog_iterator_begin(ref_store, refs->gitcommondir), reflog_iterator_select, refs); } diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh index e6a5f1868f..4f860285cc 100755 --- a/t/t0600-reffiles-backend.sh +++ b/t/t0600-reffiles-backend.sh @@ -287,7 +287,7 @@ test_expect_success 'for_each_reflog()' ' mkdir -p .git/worktrees/wt/logs/refs/bisect && echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random && - $RWT for-each-reflog | cut -d" " -f 2- | sort >actual && + $RWT for-each-reflog | cut -d" " -f 2- >actual && cat >expected <<-\EOF && HEAD 0x1 PSEUDO-WT 0x0 @@ -297,7 +297,7 @@ test_expect_success 'for_each_reflog()' ' EOF test_cmp expected actual && - $RMAIN for-each-reflog | cut -d" " -f 2- | sort >actual && + $RMAIN for-each-reflog | cut -d" " -f 2- >actual && cat >expected <<-\EOF && HEAD 0x1 PSEUDO-MAIN 0x0 diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index 976bd71efb..cfb583f544 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -74,7 +74,7 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | sort -k2 | cut -d" " -f 2- >actual && + $RUN for-each-reflog | cut -d" " -f 2- >actual && cat >expected <<-\EOF && HEAD 0x1 refs/heads/main 0x0 diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh index e6a7f7334b..40332e23cc 100755 --- a/t/t1406-submodule-ref-store.sh +++ b/t/t1406-submodule-ref-store.sh @@ -63,7 +63,7 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | sort | cut -d" " -f 2- >actual && + $RUN for-each-reflog | cut -d" " -f 2- >actual && cat >expected <<-\EOF && HEAD 0x1 refs/heads/main 0x0 From patchwork Tue Feb 20 09:06:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563684 Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36EAA5FEE8 for ; Tue, 20 Feb 2024 09:06:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420001; cv=none; b=sXhPWDWTg2E3ah0fkkgu8p9KanQNR1dmaeiP4Jy5cB9mrgR2jmQ7mrre25zEhR8E4NfPQl2QdQBu1hHnb7mt0k2rfmDgSEjDDxKwdgu55zeViB9xf5oM9i3aPN/KRHbiZrbcS0ZxtNxYoz0csdX6x7woSubJ3YUeTlrbPKuK79U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420001; c=relaxed/simple; bh=27splBBxv+Rm1rrabkraoC3LsmhqeltPw9NRFGcqP9c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=CwCBi6fQoROfx2JGNA3mM/sHy3Gv97ELL0aa0nu568+MyjFNNLSACtg3uPcN6U0h69+A1bAzw0mCdDcYGCcom4OAYRoatX8foRGoVX7JB9rylL87dwCsC8of3ho/wH89m//Efx4iP4jLiV+LgnZ29W746t1FX1hgJXGeLDsFIBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ndHdETb4; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=bedp0OSo; arc=none smtp.client-ip=64.147.123.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ndHdETb4"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="bedp0OSo" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id 165093200A17; Tue, 20 Feb 2024 04:06:38 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Tue, 20 Feb 2024 04:06:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708419997; x=1708506397; bh=JKCrXjctYw f4q1bugWTdiTBEhwmZuIOZO3Q0GEXZAnQ=; b=ndHdETb4eyhpF4S4K7hgiSUnHL 6V+uC7/YxanoeLRyquSrbMJq1R91TWJ+GHm7jS9jKYMq4eFaVw33yZI6stAf03Sd JYZFbYzIXKm9/rqurdYG8PA6/5/ffTRkQ/NiNQa6bdrQU3l7Ox64W7wUktgIkxPT 52DuKZoq2VEHPsvJFWk7zw5X7OHw776HuoUIA8IsywBSBMVLhWv+7dhe8jIt0g2H ayPkrsfoSE6C5teOat/Hp8qGuXY0jscviqiD+YxgIYqZAqn6UxWHERmNWY5yyp8J nUUfJDCzm2x/yhPQ2jB4Qk0lD0j5dpMlj1IgXagjz7BtvQT8/UtGPsUA47cw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708419997; x=1708506397; bh=JKCrXjctYwf4q1bugWTdiTBEhwmZ uIOZO3Q0GEXZAnQ=; b=bedp0OSoN/u43JnhqazHRIUqxjx66rlLrxH4Tlfn6ik/ LXsC0zTXF6+aTNlifIFmS3xJlo2DpfL6QgOQ+ngefLEnzmfe8HyhsMB/yiKlOoNP yYpucWQNpPfTpECKT34nBn7p2nBESONk0Mbilo6bLrsSPPg9uHwdRXvrcz90jSNR dhEIMycP7aU43B1NPv3n8Tsn0OUq7pTSrqYYxzblnxboAmF7iTJzaq6/hybwu9pt GOMguQMBjLvqcoki9rrD9aJJ1d0rqFd26fzz7tbOCbelpVrMTw5WYODmBgnVU3UD yTcXhVlvA/jszdXys8xVO/aiuTqZ3PVb4H5YoohLfg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:36 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id d18f331f (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:34 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:34 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 4/7] refs: always treat iterators as ordered Message-ID: <4254f23fd40076857ec093365a8adbb860803a72.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: In the preceding commit we have converted the reflog iterator of the "files" backend to be ordered, which was the only remaining ref iterator that wasn't ordered. Refactor the ref iterator infrastructure so that we always assume iterators to be ordered, thus simplifying the code. Signed-off-by: Patrick Steinhardt --- refs.c | 4 ---- refs/debug.c | 3 +-- refs/files-backend.c | 7 +++---- refs/iterator.c | 26 ++++++++------------------ refs/packed-backend.c | 2 +- refs/ref-cache.c | 2 +- refs/refs-internal.h | 18 ++---------------- refs/reftable-backend.c | 8 ++++---- 8 files changed, 20 insertions(+), 50 deletions(-) diff --git a/refs.c b/refs.c index fff343c256..dc25606a82 100644 --- a/refs.c +++ b/refs.c @@ -1594,10 +1594,6 @@ struct ref_iterator *refs_ref_iterator_begin( if (trim) iter = prefix_ref_iterator_begin(iter, "", trim); - /* Sanity check for subclasses: */ - if (!iter->ordered) - BUG("reference iterator is not ordered"); - return iter; } diff --git a/refs/debug.c b/refs/debug.c index 634681ca44..c7531b17f0 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -181,7 +181,6 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator) trace_printf_key(&trace_refs, "iterator_advance: %s (0)\n", diter->iter->refname); - diter->base.ordered = diter->iter->ordered; diter->base.refname = diter->iter->refname; diter->base.oid = diter->iter->oid; diter->base.flags = diter->iter->flags; @@ -222,7 +221,7 @@ debug_ref_iterator_begin(struct ref_store *ref_store, const char *prefix, drefs->refs->be->iterator_begin(drefs->refs, prefix, exclude_patterns, flags); struct debug_ref_iterator *diter = xcalloc(1, sizeof(*diter)); - base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable, 1); + base_ref_iterator_init(&diter->base, &debug_ref_iterator_vtable); diter->iter = res; trace_printf_key(&trace_refs, "ref_iterator_begin: \"%s\" (0x%x)\n", prefix, flags); diff --git a/refs/files-backend.c b/refs/files-backend.c index a7b7cdef36..51d57d98d2 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -879,8 +879,7 @@ static struct ref_iterator *files_ref_iterator_begin( CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable, - overlay_iter->ordered); + base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable); iter->iter0 = overlay_iter; iter->repo = ref_store->repo; iter->flags = flags; @@ -2202,7 +2201,7 @@ static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable); iter->dir_iterator = diter; iter->ref_store = ref_store; strbuf_release(&sb); @@ -2246,7 +2245,7 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st return reflog_iterator_begin(ref_store, refs->gitcommondir); } else { return merge_ref_iterator_begin( - 1, reflog_iterator_begin(ref_store, refs->base.gitdir), + reflog_iterator_begin(ref_store, refs->base.gitdir), reflog_iterator_begin(ref_store, refs->gitcommondir), reflog_iterator_select, refs); } diff --git a/refs/iterator.c b/refs/iterator.c index 6b680f610e..f9a9a808e0 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -25,11 +25,9 @@ int ref_iterator_abort(struct ref_iterator *ref_iterator) } void base_ref_iterator_init(struct ref_iterator *iter, - struct ref_iterator_vtable *vtable, - int ordered) + struct ref_iterator_vtable *vtable) { iter->vtable = vtable; - iter->ordered = !!ordered; iter->refname = NULL; iter->oid = NULL; iter->flags = 0; @@ -74,7 +72,7 @@ struct ref_iterator *empty_ref_iterator_begin(void) struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter)); struct ref_iterator *ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable); return ref_iterator; } @@ -207,7 +205,6 @@ static struct ref_iterator_vtable merge_ref_iterator_vtable = { }; struct ref_iterator *merge_ref_iterator_begin( - int ordered, struct ref_iterator *iter0, struct ref_iterator *iter1, ref_iterator_select_fn *select, void *cb_data) { @@ -222,7 +219,7 @@ struct ref_iterator *merge_ref_iterator_begin( * references through only if they exist in both iterators. */ - base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered); + base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable); iter->iter0 = iter0; iter->iter1 = iter1; iter->select = select; @@ -271,12 +268,9 @@ struct ref_iterator *overlay_ref_iterator_begin( } else if (is_empty_ref_iterator(back)) { ref_iterator_abort(back); return front; - } else if (!front->ordered || !back->ordered) { - BUG("overlay_ref_iterator requires ordered inputs"); } - return merge_ref_iterator_begin(1, front, back, - overlay_iterator_select, NULL); + return merge_ref_iterator_begin(front, back, overlay_iterator_select, NULL); } struct prefix_ref_iterator { @@ -315,16 +309,12 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) if (cmp > 0) { /* - * If the source iterator is ordered, then we + * As the source iterator is ordered, we * can stop the iteration as soon as we see a * refname that comes after the prefix: */ - if (iter->iter0->ordered) { - ok = ref_iterator_abort(iter->iter0); - break; - } else { - continue; - } + ok = ref_iterator_abort(iter->iter0); + break; } if (iter->trim) { @@ -396,7 +386,7 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered); + base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable); iter->iter0 = iter0; iter->prefix = xstrdup(prefix); diff --git a/refs/packed-backend.c b/refs/packed-backend.c index a499a91c7e..4e826c05ff 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1111,7 +1111,7 @@ static struct ref_iterator *packed_ref_iterator_begin( CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable); if (exclude_patterns) populate_excluded_jump_list(iter, snapshot, exclude_patterns); diff --git a/refs/ref-cache.c b/refs/ref-cache.c index a372a00941..9f9797209a 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -486,7 +486,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, CALLOC_ARRAY(iter, 1); ref_iterator = &iter->base; - base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable, 1); + base_ref_iterator_init(ref_iterator, &cache_ref_iterator_vtable); ALLOC_GROW(iter->levels, 10, iter->levels_alloc); iter->levels_nr = 1; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 83e0f0bba3..1e8a9f9f13 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -312,13 +312,6 @@ enum do_for_each_ref_flags { */ struct ref_iterator { struct ref_iterator_vtable *vtable; - - /* - * Does this `ref_iterator` iterate over references in order - * by refname? - */ - unsigned int ordered : 1; - const char *refname; const struct object_id *oid; unsigned int flags; @@ -390,11 +383,9 @@ typedef enum iterator_selection ref_iterator_select_fn( * Iterate over the entries from iter0 and iter1, with the values * interleaved as directed by the select function. The iterator takes * ownership of iter0 and iter1 and frees them when the iteration is - * over. A derived class should set `ordered` to 1 or 0 based on - * whether it generates its output in order by reference name. + * over. */ struct ref_iterator *merge_ref_iterator_begin( - int ordered, struct ref_iterator *iter0, struct ref_iterator *iter1, ref_iterator_select_fn *select, void *cb_data); @@ -423,8 +414,6 @@ struct ref_iterator *overlay_ref_iterator_begin( * As an convenience to callers, if prefix is the empty string and * trim is zero, this function returns iter0 directly, without * wrapping it. - * - * The resulting ref_iterator is ordered if iter0 is. */ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, const char *prefix, @@ -435,14 +424,11 @@ struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0, /* * Base class constructor for ref_iterators. Initialize the * ref_iterator part of iter, setting its vtable pointer as specified. - * `ordered` should be set to 1 if the iterator will iterate over - * references in order by refname; otherwise it should be set to 0. * This is meant to be called only by the initializers of derived * classes. */ void base_ref_iterator_init(struct ref_iterator *iter, - struct ref_iterator_vtable *vtable, - int ordered); + struct ref_iterator_vtable *vtable); /* * Base class destructor for ref_iterators. Destroy the ref_iterator diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index a14f2ad7f4..70a16dfb9e 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -479,7 +479,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_ int ret; iter = xcalloc(1, sizeof(*iter)); - base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable, 1); + base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable); iter->prefix = prefix; iter->base.oid = &iter->oid; iter->flags = flags; @@ -575,7 +575,7 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto * single iterator. */ worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, flags); - return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base, + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, iterator_select, NULL); } @@ -1723,7 +1723,7 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl int ret; iter = xcalloc(1, sizeof(*iter)); - base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable, 1); + base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable); iter->refs = refs; iter->base.oid = &iter->oid; @@ -1758,7 +1758,7 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store * worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack); - return merge_ref_iterator_begin(1, &worktree_iter->base, &main_iter->base, + return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, iterator_select, NULL); } From patchwork Tue Feb 20 09:06:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563685 Received: from wfout6-smtp.messagingengine.com (wfout6-smtp.messagingengine.com [64.147.123.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3E7C62146 for ; Tue, 20 Feb 2024 09:06:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.149 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420004; cv=none; b=mNbkqfe0iakpJH4wLoNEUM/414Sh4qTJFZlrck0B75lxEfRQzpU2fhH/mFTzOzCePTHu9/xyCMcSGbNeqatV8NE5jb7zJ82iNKKDOj0Et43+nVicun1xkjvFbTV33h952uGYcJ1T4FoDKyqmLHJYXYRXkju259/nk4+zskLkwCY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420004; c=relaxed/simple; bh=Gvz/qCwq0k8EBjt5nZvIvl4ov1DVxzY3hhZDMzdnfwU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=FWav6ArZ5cB08pR/Pu9ozwJUbCd94NveBO7hWyXBLkH7ILK1BDMVJ7hjekk0bvtU6vVXB0wb2f3rJGutyYOrhAQ8reO4LVu1aNYPkdpiJiMujp6eEMqQCBZ7VllXWVjpzJaBY/8PLzEIVLLf4TQLSjnW+LhcRe1/KSZNf+YzF28= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=M4HDw0EG; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=hzVYxulC; arc=none smtp.client-ip=64.147.123.149 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="M4HDw0EG"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="hzVYxulC" Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailfout.west.internal (Postfix) with ESMTP id E779E1C00095; Tue, 20 Feb 2024 04:06:41 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Tue, 20 Feb 2024 04:06:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708420001; x=1708506401; bh=MDW4MsVM2Z MCvM709H8pwuvaLhrBXH0VlkWz1p2CpFI=; b=M4HDw0EGIpfUGgs/gKp0l4vnYm QCjeZ1KE3lv8ZdmMZsWGZmwnElPpMB+/vb9i+82tRiLQBF0MS6e2ptb/29TIKvoB lVPX9Tfpgp4i8lUtNHN0G2SycrrTittNkW964gUvi4qQb2C1LJGsTwJiTjhJ1a04 3bVxOFo3sgds0dxmDzcfIUKvREmQjynHRXz25nULPI1IKEzgFgGFCsp52jEH85d4 dAHI68Up6Yk22/YOIk0sHUH8bgvhp/Y3tBsNC0l1WJ41GlB9FSrXEWChFA5YcuHO knORs4x6lIF7d1fFbYlX4x3d/An0MNFLiLfxurRrQhRXJjjEVzExDPR8s5kw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708420001; x=1708506401; bh=MDW4MsVM2ZMCvM709H8pwuvaLhrB XH0VlkWz1p2CpFI=; b=hzVYxulCYybQfaTkE/pnjT7y6G9L92wVCWPS5F2jcq2x r6zPf6tlMMlw9uBfhshIt5CPb5vsnzWOPbLM4lUl+xKdBQWbqG6djRijslLD9ka4 HPm02ACb49gU/KM/bqSmWKVYHKyMg8dompgK4ECq21Arg9ayw6hthj1Mw/UNq0iU b+ZOnzBb9dHkxbhtMKUUVjrOXmqHH6cxgaIMtWZu/DqobO5PbzMlMFykKqxulkx2 +XPqXGW7kedrL8njchsO6vu7xPV8OtOofLoseCJi6cBdAWuGOiwzg7KxdlUGa8qS 4BLF2F9yU6Jed20YVQa3mg/yyBss78uZJBqSFW7NmQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:40 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 2afaf932 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:38 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:39 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 5/7] refs: drop unused params from the reflog iterator callback Message-ID: <240334df6c7d0e95f67fdeddb8b8a381a59245fa.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The ref and reflog iterators share much of the same underlying code to iterate over the corresponding entries. This results in some weird code because the reflog iterator also exposes an object ID as well as a flag to the callback function. Neither of these fields do refer to the reflog though -- they refer to the corresponding ref with the same name. This is quite misleading. In practice at least the object ID cannot really be implemented in any other way as a reflog does not have a specific object ID in the first place. This is further stressed by the fact that none of the callbacks except for our test helper make use of these fields. Split up the infrastucture so that ref and reflog iterators use separate callback signatures. This allows us to drop the nonsensical fields from the reflog iterator. Note that internally, the backends still use the same shared infra to iterate over both types. As the backends should never end up being called directly anyway, this is not much of a problem and thus kept as-is for simplicity's sake. Signed-off-by: Patrick Steinhardt --- builtin/fsck.c | 4 +--- builtin/reflog.c | 3 +-- refs.c | 23 +++++++++++++++++++---- refs.h | 11 +++++++++-- refs/files-backend.c | 8 +------- refs/reftable-backend.c | 8 +------- revision.c | 4 +--- t/helper/test-ref-store.c | 18 ++++++++++++------ t/t0600-reffiles-backend.sh | 24 ++++++++++++------------ t/t1405-main-ref-store.sh | 8 ++++---- t/t1406-submodule-ref-store.sh | 8 ++++---- 11 files changed, 65 insertions(+), 54 deletions(-) diff --git a/builtin/fsck.c b/builtin/fsck.c index a7cf94f67e..f892487c9b 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -509,9 +509,7 @@ static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid return 0; } -static int fsck_handle_reflog(const char *logname, - const struct object_id *oid UNUSED, - int flag UNUSED, void *cb_data) +static int fsck_handle_reflog(const char *logname, void *cb_data) { struct strbuf refname = STRBUF_INIT; diff --git a/builtin/reflog.c b/builtin/reflog.c index a5a4099f61..3a0c4d4322 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -60,8 +60,7 @@ struct worktree_reflogs { struct string_list reflogs; }; -static int collect_reflog(const char *ref, const struct object_id *oid UNUSED, - int flags UNUSED, void *cb_data) +static int collect_reflog(const char *ref, void *cb_data) { struct worktree_reflogs *cb = cb_data; struct worktree *worktree = cb->worktree; diff --git a/refs.c b/refs.c index dc25606a82..f9261267f0 100644 --- a/refs.c +++ b/refs.c @@ -2512,18 +2512,33 @@ int refs_verify_refname_available(struct ref_store *refs, return ret; } -int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data) +struct do_for_each_reflog_help { + each_reflog_fn *fn; + void *cb_data; +}; + +static int do_for_each_reflog_helper(struct repository *r UNUSED, + const char *refname, + const struct object_id *oid UNUSED, + int flags, + void *cb_data) +{ + struct do_for_each_reflog_help *hp = cb_data; + return hp->fn(refname, hp->cb_data); +} + +int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data) { struct ref_iterator *iter; - struct do_for_each_ref_help hp = { fn, cb_data }; + struct do_for_each_reflog_help hp = { fn, cb_data }; iter = refs->be->reflog_iterator_begin(refs); return do_for_each_repo_ref_iterator(the_repository, iter, - do_for_each_ref_helper, &hp); + do_for_each_reflog_helper, &hp); } -int for_each_reflog(each_ref_fn fn, void *cb_data) +int for_each_reflog(each_reflog_fn fn, void *cb_data) { return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data); } diff --git a/refs.h b/refs.h index 303c5fac4d..895579aeb7 100644 --- a/refs.h +++ b/refs.h @@ -534,12 +534,19 @@ int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_dat /* youngest entry first */ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data); +/* + * The signature for the callback function for the {refs_,}for_each_reflog() + * functions below. The memory pointed to by the refname argument is only + * guaranteed to be valid for the duration of a single callback invocation. + */ +typedef int each_reflog_fn(const char *refname, void *cb_data); + /* * Calls the specified function for each reflog file until it returns nonzero, * and returns the value. Reflog file order is unspecified. */ -int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data); -int for_each_reflog(each_ref_fn fn, void *cb_data); +int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data); +int for_each_reflog(each_reflog_fn fn, void *cb_data); #define REFNAME_ALLOW_ONELEVEL 1 #define REFNAME_REFSPEC_PATTERN 2 diff --git a/refs/files-backend.c b/refs/files-backend.c index 51d57d98d2..48cc60d71b 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2115,10 +2115,8 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store, struct files_reflog_iterator { struct ref_iterator base; - struct ref_store *ref_store; struct dir_iterator *dir_iterator; - struct object_id oid; }; static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) @@ -2129,8 +2127,6 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) int ok; while ((ok = dir_iterator_advance(diter)) == ITER_OK) { - int flags; - if (!S_ISREG(diter->st.st_mode)) continue; if (diter->basename[0] == '.') @@ -2140,14 +2136,12 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) if (!refs_resolve_ref_unsafe(iter->ref_store, diter->relative_path, 0, - &iter->oid, &flags)) { + NULL, NULL)) { error("bad ref for %s", diter->path.buf); continue; } iter->base.refname = diter->relative_path; - iter->base.oid = &iter->oid; - iter->base.flags = flags; return ITER_OK; } diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 70a16dfb9e..5247e09d58 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1637,7 +1637,6 @@ struct reftable_reflog_iterator { struct reftable_ref_store *refs; struct reftable_iterator iter; struct reftable_log_record log; - struct object_id oid; char *last_name; int err; }; @@ -1648,8 +1647,6 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) (struct reftable_reflog_iterator *)ref_iterator; while (!iter->err) { - int flags; - iter->err = reftable_iterator_next_log(&iter->iter, &iter->log); if (iter->err) break; @@ -1663,7 +1660,7 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) continue; if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->log.refname, - 0, &iter->oid, &flags)) { + 0, NULL, NULL)) { error(_("bad ref for %s"), iter->log.refname); continue; } @@ -1671,8 +1668,6 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) free(iter->last_name); iter->last_name = xstrdup(iter->log.refname); iter->base.refname = iter->log.refname; - iter->base.oid = &iter->oid; - iter->base.flags = flags; break; } @@ -1725,7 +1720,6 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl iter = xcalloc(1, sizeof(*iter)); base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable); iter->refs = refs; - iter->base.oid = &iter->oid; ret = refs->err; if (ret) diff --git a/revision.c b/revision.c index 2424c9bd67..ac45c6d8f2 100644 --- a/revision.c +++ b/revision.c @@ -1686,9 +1686,7 @@ static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid, return 0; } -static int handle_one_reflog(const char *refname_in_wt, - const struct object_id *oid UNUSED, - int flag UNUSED, void *cb_data) +static int handle_one_reflog(const char *refname_in_wt, void *cb_data) { struct all_refs_cb *cb = cb_data; struct strbuf refname = STRBUF_INIT; diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 702ec1f128..7a0f6cac53 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -221,15 +221,21 @@ static int cmd_verify_ref(struct ref_store *refs, const char **argv) return ret; } +static int each_reflog(const char *refname, void *cb_data UNUSED) +{ + printf("%s\n", refname); + return 0; +} + static int cmd_for_each_reflog(struct ref_store *refs, const char **argv UNUSED) { - return refs_for_each_reflog(refs, each_ref, NULL); + return refs_for_each_reflog(refs, each_reflog, NULL); } -static int each_reflog(struct object_id *old_oid, struct object_id *new_oid, - const char *committer, timestamp_t timestamp, - int tz, const char *msg, void *cb_data UNUSED) +static int each_reflog_ent(struct object_id *old_oid, struct object_id *new_oid, + const char *committer, timestamp_t timestamp, + int tz, const char *msg, void *cb_data UNUSED) { printf("%s %s %s %" PRItime " %+05d%s%s", oid_to_hex(old_oid), oid_to_hex(new_oid), committer, timestamp, tz, @@ -241,14 +247,14 @@ static int cmd_for_each_reflog_ent(struct ref_store *refs, const char **argv) { const char *refname = notnull(*argv++, "refname"); - return refs_for_each_reflog_ent(refs, refname, each_reflog, refs); + return refs_for_each_reflog_ent(refs, refname, each_reflog_ent, refs); } static int cmd_for_each_reflog_ent_reverse(struct ref_store *refs, const char **argv) { const char *refname = notnull(*argv++, "refname"); - return refs_for_each_reflog_ent_reverse(refs, refname, each_reflog, refs); + return refs_for_each_reflog_ent_reverse(refs, refname, each_reflog_ent, refs); } static int cmd_reflog_exists(struct ref_store *refs, const char **argv) diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh index 4f860285cc..56a3196b83 100755 --- a/t/t0600-reffiles-backend.sh +++ b/t/t0600-reffiles-backend.sh @@ -287,23 +287,23 @@ test_expect_success 'for_each_reflog()' ' mkdir -p .git/worktrees/wt/logs/refs/bisect && echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random && - $RWT for-each-reflog | cut -d" " -f 2- >actual && + $RWT for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-WT 0x0 - refs/bisect/wt-random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 + HEAD + PSEUDO-WT + refs/bisect/wt-random + refs/heads/main + refs/heads/wt-main EOF test_cmp expected actual && - $RMAIN for-each-reflog | cut -d" " -f 2- >actual && + $RMAIN for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - PSEUDO-MAIN 0x0 - refs/bisect/random 0x0 - refs/heads/main 0x0 - refs/heads/wt-main 0x0 + HEAD + PSEUDO-MAIN + refs/bisect/random + refs/heads/main + refs/heads/wt-main EOF test_cmp expected actual ' diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index cfb583f544..3eee758bce 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -74,11 +74,11 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | cut -d" " -f 2- >actual && + $RUN for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - refs/heads/main 0x0 - refs/heads/new-main 0x0 + HEAD + refs/heads/main + refs/heads/new-main EOF test_cmp expected actual ' diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh index 40332e23cc..c01f0f14a1 100755 --- a/t/t1406-submodule-ref-store.sh +++ b/t/t1406-submodule-ref-store.sh @@ -63,11 +63,11 @@ test_expect_success 'verify_ref(new-main)' ' ' test_expect_success 'for_each_reflog()' ' - $RUN for-each-reflog | cut -d" " -f 2- >actual && + $RUN for-each-reflog >actual && cat >expected <<-\EOF && - HEAD 0x1 - refs/heads/main 0x0 - refs/heads/new-main 0x0 + HEAD + refs/heads/main + refs/heads/new-main EOF test_cmp expected actual ' From patchwork Tue Feb 20 09:06:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563686 Received: from wfout6-smtp.messagingengine.com (wfout6-smtp.messagingengine.com [64.147.123.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B64395F554 for ; Tue, 20 Feb 2024 09:06:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.149 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420009; cv=none; b=nz2b6Lslv2MeWm/fG3DOZ0NtGLIRMCRPJ7oF514cRGmKeB/FFHm7Ckj1XOozLH8hu8A/jyvbEO7x3M0SygYmClHOsCL7FxoGKkiSSyBtERmHpVR2hKWTlLwkZZah8YIgssxeOISh4+1d2xmn4l04HHJvjrWfLp+KkZ8Egj7xIWM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420009; c=relaxed/simple; bh=4U0Du7RuKPhNCkZfjheXWtJB/Dhxm+ijOZvL+g7/MPY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Cs8+LhMHDpApUwD/AG7ySuPTbxpllwGV0+1lU5pb2XQymUPV8/0cZkSZyKAmuuGvsrvHG+4b/ECFU4uiP2yJI9EOf9303B6qTgt4wtvbSoKMmRjQhwfUS11VvYdSHimrWu0W0V45NYT0Kg6eS/2YMp5NLWXGYzJ4pEtGtG0VZgQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ntB7cFk7; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VCI7sn7M; arc=none smtp.client-ip=64.147.123.149 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ntB7cFk7"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VCI7sn7M" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfout.west.internal (Postfix) with ESMTP id BFE281C00096; Tue, 20 Feb 2024 04:06:46 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Tue, 20 Feb 2024 04:06:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708420006; x=1708506406; bh=1P2fekKHlu WRGEtM4D5bbxqudF6kwIO9Eb7+LxzUMcE=; b=ntB7cFk7c5Ep9HQj44T2dgESwD taaYZ+OR+bv1FvyV43PtAGeuG0bJwD/WfnBzyyEXzwf0NDGq99FEPNzcBom1dY7B bQcKyrdtzdAHuXEjXt3+Ao8R6ceK3JlRmIkmUXdQdKyjxkOsfW/WpELUV5S9WLaV mZKDp+TfInLcBOPUh4d1CNJWJUK0u1SXOyKSspEaA21M/5MqSgOrYf/ZmuM36pk5 eDIk8lYcsReRLhVOY0VJKwkWsh90ZKoyThiSrVU1lNUIKHy+cX7taCTkjA00RPri jY4vxBKqLc9t/YGT3QGanYmT0K19krbLa+7RcKEdKD4Zx00wi7FMQHoYHHCw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708420006; x=1708506406; bh=1P2fekKHluWRGEtM4D5bbxqudF6k wIO9Eb7+LxzUMcE=; b=VCI7sn7M+m1wxTD/m5QPAeipbptlNkwyNc1oeAtIhU7+ xXvuMt/5DaQxi7RRsmDxnOox9XDP4MXMZDfjWfBhGif8itx9seqG+dBigBoLdGhn YGsucpntiJHXANp4Co8Kj8DPRIj+iG3lUAQIQ4l39z56ltJRxyNKZGbae7KbdPv7 n8D3uuMhAIr0gg8KD4nroKSfdPtm/xEjIifNzT3wvoMKdMLduOylSoX6XmEqgTR5 itdONR8kAN1cemUQ0tzfn8amo1XPs6b3KYGKMhJhoJgwSfz5Sx2KwuxscbBD+4CC lL3hdFD+NgtrMsg67D3/0RBFjlD8o1o423mIvYdOuw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:45 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 2386328e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:42 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:43 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 6/7] refs: stop resolving ref corresponding to reflogs Message-ID: <7928661318a635022b65db543bd551018057c11f.1708418805.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The reflog iterator tries to resolve the corresponding ref for every reflog that it is about to yield. Historically, this was done due to multiple reasons: - It ensures that the refname is safe because we end up calling `check_refname_format()`. Also, non-conformant refnames are skipped altogether. - The iterator used to yield the resolved object ID as well as its flags to the callback. This info was never used though, and the corresponding parameters were dropped in the preceding commit. - When a ref is corrupt then the reflog is not emitted at all. We're about to introduce a new `git reflog list` subcommand that will print all reflogs that the refdb knows about. Skipping over reflogs whose refs are corrupted would be quite counterproductive in this case as the user would have no way to learn about reflogs which may still exist in their repository to help and rescue such a corrupted ref. Thus, the only remaining reason for why we'd want to resolve the ref is to verify its refname. Refactor the code to call `check_refname_format()` directly instead of trying to resolve the ref. This is significantly more efficient given that we don't have to hit the object database anymore to list reflogs. And second, it ensures that we end up showing reflogs of broken refs, which will help to make the reflog more useful. Note that this really only impacts the case where the corresponding ref is corrupt. Reflogs for nonexistent refs would have been returned to the caller beforehand already as we did not pass `RESOLVE_REF_READING` to the function, and thus `refs_resolve_ref_unsafe()` would have returned successfully in that case. Signed-off-by: Patrick Steinhardt --- refs/files-backend.c | 12 ++---------- refs/reftable-backend.c | 6 ++---- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/refs/files-backend.c b/refs/files-backend.c index 48cc60d71b..4726b04baa 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2129,17 +2129,9 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) while ((ok = dir_iterator_advance(diter)) == ITER_OK) { if (!S_ISREG(diter->st.st_mode)) continue; - if (diter->basename[0] == '.') + if (check_refname_format(diter->basename, + REFNAME_ALLOW_ONELEVEL)) continue; - if (ends_with(diter->basename, ".lock")) - continue; - - if (!refs_resolve_ref_unsafe(iter->ref_store, - diter->relative_path, 0, - NULL, NULL)) { - error("bad ref for %s", diter->path.buf); - continue; - } iter->base.refname = diter->relative_path; return ITER_OK; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 5247e09d58..f3200a1886 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -1659,11 +1659,9 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) if (iter->last_name && !strcmp(iter->log.refname, iter->last_name)) continue; - if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->log.refname, - 0, NULL, NULL)) { - error(_("bad ref for %s"), iter->log.refname); + if (check_refname_format(iter->log.refname, + REFNAME_ALLOW_ONELEVEL)) continue; - } free(iter->last_name); iter->last_name = xstrdup(iter->log.refname); From patchwork Tue Feb 20 09:06:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13563687 Received: from wfout6-smtp.messagingengine.com (wfout6-smtp.messagingengine.com [64.147.123.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83B855EE8B for ; Tue, 20 Feb 2024 09:06:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.149 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420013; cv=none; b=VnrCEfP7hLdAg05vrNaBKcLz6f6+cz1arlsUw3WaAevLaT2eBAPa88FpFfudyazmTSAb1NavtHU1c2Ibzuio1WhisXBedH7SFn7hCDbsyBnjLEuFJe6jc3pp4L0DyTIMy2r0/3D3OEkBzB0LSjxA1mRWBuumlIUdCIgQ8/CUSIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708420013; c=relaxed/simple; bh=f5qhfs8EYx8TvcQVPQI4SWHJkQ90FkKF9J8gCdpe8YM=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Nea31zv7gaiqXF9Ns4oLnqvrOrVTJv1ny38lIvMkOejQSQ1HGNXeKJmYj57MPwOLKQGPmsZ7bY8ogBLQ817/58LOvKSokDKl6Hvugn/shLnpnSlftaFILNXErFLDcsJf9oUOX0XXQAxwIvvedEpee1tngjD3svMhfM1x0tOEVb4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=k4gJxb78; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=l9D0eYVW; arc=none smtp.client-ip=64.147.123.149 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="k4gJxb78"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="l9D0eYVW" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailfout.west.internal (Postfix) with ESMTP id 9BE671C00096; Tue, 20 Feb 2024 04:06:50 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Tue, 20 Feb 2024 04:06:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1708420010; x=1708506410; bh=J+pKgn089x Osq03zjCOKqO/bD+74mPT7v03KgMpJ6yM=; b=k4gJxb78zeSflzKIXS8A+aRQup Zh8ZtwYKbWF7pGeTBpb0fI9wWOyWSFkBJciwkvDfEf/UWPSx4K0tMx5LNIIafrBZ FMVAFegQ2eLw1COdy3haBWepCR+pgisCIewRjwtWevTrVz9kYB3Jkzvvi0rKL1Fs tputTYeKy0VsvoGfFdAWDeKqcHMShOXErT2jNtfZQcjIeLjnQ3eb9o7cuag6A0p4 QO0rCaY8i3DwxKuu/twWzXkx6JyMOOluDPCingucWsUA/HFkOKglmx9UaIu+jpS9 vHfADfqcB5TcMcczfYHDsY0QzKG5s3sfw+sQ37FT+pglbXfn7OZQ4OWzphwg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1708420010; x=1708506410; bh=J+pKgn089xOsq03zjCOKqO/bD+74 mPT7v03KgMpJ6yM=; b=l9D0eYVWzwWFum/ZNZNIXlBMmAgqpnjmCrQ4HMVptDGq X51aqGcL43XZit9VDWbSthL5BWfqoEeSQB1SjkI6gLVtcoRIcOb62udMrushO9hP y+9l1AXscl1NGKpJgz1wGgeS4cdRoPylp0BMGd6RO3wRWSfGQZlrFri20pLnrBLY c0TujQNcRtsdFoQMxugU+6Clv6rJErkizLQr7Zz3prXP3/jmhAjUlBaqhiTMNwQO 1rYAC7jx7Ma42FOaB9E/9umSaVGrPQfIM7Z67TvTd/Cg5DAPjRB7dXKtYoXWuWzO 4W5hhkU9o2gNVBW4nDG5St6+k93Zjz55KJoaHPBg6A== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrfedtucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpeffhffvvefukfhfgggtuggjsehgtderredttd dvnecuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdr ihhmqeenucggtffrrghtthgvrhhnpeeukedtvedtffevleejtefgheehieegkeeluddvfe efgeehgfeltddtheejleffteenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhep mhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 20 Feb 2024 04:06:49 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id d0f04304 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Tue, 20 Feb 2024 09:02:47 +0000 (UTC) Date: Tue, 20 Feb 2024 10:06:47 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Junio C Hamano Subject: [PATCH v2 7/7] builtin/reflog: introduce subcommand to list reflogs Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: While the git-reflog(1) command has subcommands to show reflog entries or check for reflog existence, it does not have any subcommands that would allow the user to enumerate all existing reflogs. This makes it quite hard to discover which reflogs a repository has. While this can be worked around with the "files" backend by enumerating files in the ".git/logs" directory, users of the "reftable" backend don't enjoy such a luxury. Introduce a new subcommand `git reflog list` that lists all reflogs the repository knows of to fill this gap. Signed-off-by: Patrick Steinhardt --- Documentation/git-reflog.txt | 3 ++ builtin/reflog.c | 34 ++++++++++++++++++ t/t1410-reflog.sh | 69 ++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index ec64cbff4c..a929c52982 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -10,6 +10,7 @@ SYNOPSIS -------- [verse] 'git reflog' [show] [] [] +'git reflog list' 'git reflog expire' [--expire=