All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: Thomas Bachem via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, Phillip Wood <phillip.wood@dunelm.org.uk>,
	Junio C Hamano <gitster@pobox.com>,
	Phillip Wood <phillip.wood123@gmail.com>,
	Thomas Bachem <mail@thomasbachem.com>
Subject: Re: [PATCH v4 1/2] rerere: wait for MERGE_RR.lock, and let the gc skip it
Date: Mon, 28 Sep 2026 10:18:14 +0200	[thread overview]
Message-ID: <aroixgCkqbmKErng@pks.im> (raw)
In-Reply-To: <8a7a74d6aa359844a49593538ef6178cd1b02031.1789373061.git.gitgitgadget@gmail.com>

On Mon, Sep 14, 2026 at 08:04:20AM +0000, Thomas Bachem via GitGitGadget wrote:
> diff --git a/Documentation/git-rerere.adoc b/Documentation/git-rerere.adoc
> index 4e6ab9a27c..4df653367e 100644
> --- a/Documentation/git-rerere.adoc
> +++ b/Documentation/git-rerere.adoc
> @@ -70,7 +70,9 @@ occurred a long time ago.  By default, unresolved conflicts older
>  than 15 days and resolved conflicts older than 60
>  days are pruned.  These defaults are controlled via the
>  `gc.rerereUnresolved` and `gc.rerereResolved` configuration
> -variables respectively.
> +variables respectively.  If another process holds the rerere lock,
> +for example a merge or rebase that is recording a conflict, `gc`
> +does nothing and says so.

Do we maybe want to drop these examples? I don't feel like they add any
value.

> diff --git a/rerere.c b/rerere.c
> index 3d3bd0db16..7d44f3937c 100644
> --- a/rerere.c
> +++ b/rerere.c
> @@ -33,6 +33,9 @@ static int rerere_enabled = -1;
>  /* automatically update cleanly resolved paths to the index */
>  static int rerere_autoupdate;
>  
> +/* how long to wait for MERGE_RR.lock, in milliseconds */
> +static int rerere_lock_timeout_ms = 1000;
> +
>  #define RR_HAS_POSTIMAGE 1
>  #define RR_HAS_PREIMAGE 2
>  struct rerere_dir {
> @@ -850,6 +853,8 @@ static void git_rerere_config(void)
>  {
>  	repo_config_get_bool(the_repository, "rerere.enabled", &rerere_enabled);
>  	repo_config_get_bool(the_repository, "rerere.autoupdate", &rerere_autoupdate);
> +	repo_config_get_int(the_repository, "rerere.locktimeout",
> +			    &rerere_lock_timeout_ms);
>  	repo_config(the_repository, git_default_config, NULL);
>  }
>  
> @@ -882,12 +887,34 @@ int setup_rerere(struct repository *r, struct string_list *merge_rr, int flags)
>  
>  	if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
>  		rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
> -	if (flags & RERERE_READONLY)
> +	if ((flags & RERERE_READONLY) && (flags & RERERE_NOWAIT))
> +		BUG("RERERE_READONLY takes no lock, so RERERE_NOWAIT does not apply");
> +	if (flags & RERERE_READONLY) {
>  		fd = 0;
> -	else
> -		fd = repo_hold_lock_file_for_update(r, &write_lock,
> -						    git_path_merge_rr(r),
> -						    LOCK_DIE_ON_ERROR);
> +	} else {
> +		const char *path = git_path_merge_rr(r);
> +		int lock_flags = LOCK_DIE_ON_ERROR;
> +		long timeout_ms = rerere_lock_timeout_ms;

Here you're using a `long` whereas `rerere_lock_timeout_ms` is an `int`.
Of course we'd ideally use a `long` consistently as that's also what
`repo_hold_lock_file_for_update_timeout()` accepts. But I guess the
reason you didn't is that we don't have `repo_config_get_long()`. So I
guess this is good enough for now.

> @@ -1211,7 +1238,7 @@ void rerere_gc(struct repository *r, struct string_list *rr)
>  	timestamp_t cutoff_resolve = now - 60 * 86400;
>  	struct strbuf buf = STRBUF_INIT;
>  
> -	if (setup_rerere(r, rr, 0) < 0)
> +	if (setup_rerere(r, rr, RERERE_NOWAIT) < 0)
>  		return;
>  
>  	repo_config_get_expiry_in_days(the_repository, "gc.rerereresolved",

I'm not a 100% sold on this change. There's two different scenarios
under which we want to perform garbage collection:

  - As part of auto-maintenance, triggered by Git automatically. Here
    I'm fully aligned that it makes sense to just silently ignore the
    case where we couldn't acquire the lock, as auto-maintenance is done
    on a best-effort basis anyway.

  - As part of `git rerere gc`, which is invoked manually by the user.
    Here I'm less so, as the user has explicitly asked us to garbage
    collect. Sure, we print a warning now, but the exit code does not
    signal that we failed garbage collecting.

So I'd argue that we should discern those two use cases. I think that in
the second use case, we'd probably want to use a timeout and if we fail
to acquire the lock, we should make `git rerere gc` fail with a non-zero
exit code.

Patrick

  reply	other threads:[~2026-09-28  8:18 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-02  8:31 [PATCH] rerere: keep a background gc from killing a rebase Thomas Bachem via GitGitGadget
2026-09-02 13:27 ` Phillip Wood
2026-09-02 15:07   ` Thomas Bachem
2026-09-03 13:50     ` Phillip Wood
2026-09-03  7:40 ` Patrick Steinhardt
2026-09-03  8:11   ` Thomas Bachem
2026-09-03  8:32     ` Patrick Steinhardt
2026-09-03 12:12       ` Thomas Bachem
2026-09-03 13:50       ` Phillip Wood
2026-09-04  7:44 ` [PATCH v2] " Thomas Bachem via GitGitGadget
2026-09-04 15:21   ` Phillip Wood
2026-09-04 15:55     ` Thomas Bachem
2026-09-07 10:07       ` Phillip Wood
2026-09-04 17:06     ` Junio C Hamano
2026-09-04 18:17       ` Thomas Bachem
2026-09-04 15:51 ` [PATCH v3] " Thomas Bachem via GitGitGadget
2026-09-04 19:08   ` Junio C Hamano
2026-09-05  5:41     ` Thomas Bachem
2026-09-05 16:10       ` Junio C Hamano
2026-09-06 10:29         ` Thomas Bachem
2026-09-07  7:41   ` Patrick Steinhardt
2026-09-14  8:04 ` [PATCH v4 0/2] rerere: wait for MERGE_RR.lock, and go on at a conflict Thomas Bachem via GitGitGadget
2026-09-14  8:04   ` [PATCH v4 1/2] rerere: wait for MERGE_RR.lock, and let the gc skip it Thomas Bachem via GitGitGadget
2026-09-28  8:18     ` Patrick Steinhardt [this message]
2026-09-14  8:04   ` [PATCH v4 2/2] rerere: go on at a conflict when the lock stays busy Thomas Bachem via GitGitGadget
2026-09-28  8:18     ` Patrick Steinhardt
2026-09-28 11:58 ` [PATCH v5 0/3] rerere: wait for MERGE_RR.lock, and go on at a conflict Thomas Bachem via GitGitGadget
2026-09-28 11:58   ` [PATCH v5 1/3] rerere: wait for MERGE_RR.lock before giving up Thomas Bachem via GitGitGadget
2026-09-28 11:58   ` [PATCH v5 2/3] rerere: add "gc --auto" that skips a held lock Thomas Bachem via GitGitGadget
2026-09-30 15:00     ` Patrick Steinhardt
2026-10-01  8:08       ` Thomas Bachem
2026-10-01 11:19         ` Patrick Steinhardt
2026-09-28 11:58   ` [PATCH v5 3/3] rerere: go on at a conflict when the lock stays busy Thomas Bachem via GitGitGadget
2026-10-02 11:11 ` [PATCH v6 0/3] rerere: wait for MERGE_RR.lock, and go on at a conflict Thomas Bachem via GitGitGadget
2026-10-02 11:11   ` [PATCH v6 1/3] rerere: wait for MERGE_RR.lock before giving up Thomas Bachem via GitGitGadget
2026-10-02 11:11   ` [PATCH v6 2/3] rerere: add "gc --skip-locked" for auto maintenance Thomas Bachem via GitGitGadget
2026-10-09  9:06     ` Patrick Steinhardt
2026-10-10  9:09       ` Thomas Bachem
2026-10-02 11:11   ` [PATCH v6 3/3] rerere: go on at a conflict when the lock stays busy Thomas Bachem via GitGitGadget
2026-10-09  9:06     ` Patrick Steinhardt
2026-10-10  9:09       ` Thomas Bachem
2026-10-10 10:13 ` [PATCH v7 0/2] rerere: wait for MERGE_RR.lock, but not in auto maintenance Thomas Bachem via GitGitGadget
2026-10-10 10:13   ` [PATCH v7 1/2] rerere: wait for MERGE_RR.lock before giving up Thomas Bachem via GitGitGadget
2026-10-11  0:39     ` Junio C Hamano
2026-10-11 14:18       ` Thomas Bachem
2026-10-12  0:32         ` Junio C Hamano
2026-10-10 10:13   ` [PATCH v7 2/2] rerere: add "gc --skip-locked" for auto maintenance Thomas Bachem via GitGitGadget
2026-10-13  7:31     ` Patrick Steinhardt
2026-10-13 12:07 ` [PATCH v8 0/2] rerere: wait for MERGE_RR.lock, but not in " Thomas Bachem via GitGitGadget
2026-10-13 12:07   ` [PATCH v8 1/2] rerere: wait for MERGE_RR.lock before giving up Thomas Bachem via GitGitGadget
2026-10-13 12:07   ` [PATCH v8 2/2] rerere: add "gc --skip-locked" for auto maintenance Thomas Bachem via GitGitGadget
2026-10-13 12:22   ` [PATCH v8 0/2] rerere: wait for MERGE_RR.lock, but not in " Patrick Steinhardt
2026-10-13 16:20     ` Junio C Hamano

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=aroixgCkqbmKErng@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=gitster@pobox.com \
    --cc=mail@thomasbachem.com \
    --cc=phillip.wood123@gmail.com \
    --cc=phillip.wood@dunelm.org.uk \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.