From: "Thomas Bachem via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>,
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: [PATCH v5 0/3] rerere: wait for MERGE_RR.lock, and go on at a conflict
Date: Mon, 28 Sep 2026 11:58:19 +0000 [thread overview]
Message-ID: <pull.2214.v5.git.1790596702.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2214.git.1788337897490.gitgitgadget@gmail.com>
This is now three patches: the wait on its own, the gc's skip as "git rerere
gc --auto", and the conflict-time callers on top, as before.
Patch 1 makes every writer wait rerere.lockTimeout for MERGE_RR.lock before
it fails as it does today. That alone keeps a rebase alive through the gc
that a commit's auto maintenance starts, since pruning a few thousand
entries takes well under the one second default.
Patch 2 is the split Patrick asked for: a "git rerere gc" run by hand waits
and then fails as it does today, like every other rerere command, and only
"git rerere gc --auto" skips a held lock, quietly, as "git gc --auto" does
with its own lock. "git maintenance run --auto" and "git gc --auto" pass the
option, as they do for "git pack-refs --auto". A manual or scheduled
maintenance run does not and fails on a held lock like the command itself. I
left scheduled runs on that side since maintenance treats them like manual
runs for pack-refs and gc too.
Patch 3 is v4's second patch: a command that stops at a conflict warns and
goes on when the lock is still held after the wait, and the warning says to
run "git rerere" before resolving.
Changes since v4:
* Based on today's master, which has ps/tune-rerere-gc, and merges cleanly
into next. In seen it only conflicts with its own v4.
* "git rerere gc" no longer skips a held lock on its own. Only "git rerere
gc --auto" does, and silently, so a background run prints nothing
(Patrick, Phillip).
* The git-rerere(1) sentence with the merge and rebase examples is gone.
The gc paragraph describes --auto instead (Patrick).
* I kept the timeout an int, like core.filesRefLockTimeout and
core.packedRefsTimeout, and dropped the long local (Patrick).
* The hint to run "git rerere" goes through advise_if_enabled() under
advice.mergeConflict (Patrick).
* Tests: the old gc test became the "gc --auto" test of patch 2, "git
rerere gc" joined the commands that fail on a held lock in patch 1, and
t7900 checks that maintenance passes --auto and that a run without it
fails on a held lock.
Thomas Bachem (3):
rerere: wait for MERGE_RR.lock before giving up
rerere: add "gc --auto" that skips a held lock
rerere: go on at a conflict when the lock stays busy
Documentation/config/rerere.adoc | 13 +++
Documentation/git-rerere.adoc | 9 +-
apply.c | 2 +-
builtin/am.c | 3 +-
builtin/gc.c | 4 +-
builtin/merge.c | 2 +-
builtin/rerere.c | 13 ++-
builtin/stash.c | 2 +-
rerere.c | 56 ++++++++--
rerere.h | 6 +-
sequencer.c | 4 +-
t/t4200-rerere.sh | 175 +++++++++++++++++++++++++++++++
t/t7900-maintenance.sh | 25 ++++-
13 files changed, 292 insertions(+), 22 deletions(-)
base-commit: 34f06850c16c7f7ac822b1adc71354f11b0f2ca3
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2214%2Fthomasbachem%2Frerere-gc-lock-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2214/thomasbachem/rerere-gc-lock-v5
Pull-Request: https://github.com/gitgitgadget/git/pull/2214
Range-diff vs v4:
1: 8a7a74d6aa ! 1: 3dc3d02f12 rerere: wait for MERGE_RR.lock, and let the gc skip it
@@ Metadata
Author: Thomas Bachem <mail@thomasbachem.com>
## Commit message ##
- rerere: wait for MERGE_RR.lock, and let the gc skip it
+ rerere: wait for MERGE_RR.lock before giving up
- setup_rerere() takes MERGE_RR.lock with LOCK_DIE_ON_ERROR. When two
- processes want the lock at the same time, the second one dies. This
- was always the case, but since 452b12c2e0 (builtin/maintenance: use
- "geometric" strategy by default, 2026-02-24) it is easy to hit: auto
- maintenance now runs "git rerere gc" after every commit whenever
- rr-cache contains at least one entry, and the gc holds the lock
- while it prunes.
+ setup_rerere() takes MERGE_RR.lock with LOCK_DIE_ON_ERROR, so of two
+ processes that want it at the same time the second one dies. That
+ used to be rare. Since 452b12c2e0 (builtin/maintenance: use
+ "geometric" strategy by default, 2026-02-24) the auto maintenance
+ after a commit runs "git rerere gc" whenever rr-cache has enough
+ stale entries, and the gc holds the lock while it prunes.
- A rebase whose next pick conflicts while the gc holds the lock dies
- inside repo_rerere(). That runs before the sequencer writes the state
- that "git rebase --continue" needs, so every later "git rebase
- --continue" fails with "you have staged changes".
+ A rebase whose next pick conflicts while that happens dies inside
+ repo_rerere(), before the sequencer has written the state that
+ "git rebase --continue" needs. Every later "git rebase --continue"
+ then fails with "you have staged changes in your working tree".
- Instead of dying right away, wait for the lock for up to
- rerere.lockTimeout milliseconds, 1000 by default, and only then fail
- as before. The gc itself does not wait: when the lock is held, it
- skips this run and leaves the pruning to the next one.
+ Wait for the lock for up to rerere.lockTimeout milliseconds, 1000 by
+ default, and only then fail as before. Pruning a few thousand entries
+ takes well under a second, so the default covers a rebase that runs
+ into the gc.
Assisted-by: Claude Fable 5.1
Signed-off-by: Thomas Bachem <mail@thomasbachem.com>
@@ Documentation/config/rerere.adoc: rerere.enabled::
+ `git rerere gc`. Value 0 means not to wait at all; -1 means
+ to wait indefinitely. Default is 1000 (i.e., wait for 1
+ second). When the time is up, the command fails as it does
-+ for any other lock it cannot take. `git rerere gc` never
-+ waits and skips its run while the lock is held.
-
- ## Documentation/git-rerere.adoc ##
-@@ Documentation/git-rerere.adoc: 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.
-
-
- DISCUSSION
++ for any other lock it cannot take.
## rerere.c ##
@@ rerere.c: static int rerere_enabled = -1;
@@ rerere.c: int setup_rerere(struct repository *r, struct string_list *merge_rr, i
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
@@ rerere.c: int setup_rerere(struct repository *r, struct string_list *merge_rr, i
- 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;
-+
+ /*
+ * Another process may hold the lock for a while, e.g.
+ * "git rerere gc" while it prunes rr-cache, so wait for
-+ * it instead of dying right away. The gc itself never
-+ * waits: skipping one of its runs costs nothing.
++ * it instead of dying right away.
+ */
-+ if (flags & RERERE_NOWAIT) {
-+ lock_flags = 0;
-+ timeout_ms = 0;
-+ }
+ fd = repo_hold_lock_file_for_update_timeout(r, &write_lock,
-+ path, lock_flags,
-+ timeout_ms);
-+ if (fd < 0) {
-+ warning_errno(_("skipping rerere, "
-+ "unable to create '%s.lock'"), path);
-+ return -1;
-+ }
++ git_path_merge_rr(r),
++ LOCK_DIE_ON_ERROR,
++ rerere_lock_timeout_ms);
+ }
read_rr(r, merge_rr);
return fd;
}
-@@ rerere.c: 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",
-
- ## rerere.h ##
-@@ rerere.h: struct repository;
- #define RERERE_AUTOUPDATE 01
- #define RERERE_NOAUTOUPDATE 02
- #define RERERE_READONLY 04
-+/* Never wait for MERGE_RR.lock, and skip the run when it is held */
-+#define RERERE_NOWAIT 010
-
- /*
- * Marks paths that have been hand-resolved and added to the
## t/t4200-rerere.sh ##
@@ t/t4200-rerere.sh: test_expect_success 'old records rest in peace' '
test_path_is_missing $rr2/preimage
'
-+test_expect_success 'gc does nothing while MERGE_RR is locked' '
-+ mkdir -p $rr2 &&
-+ echo Hello >$rr2/preimage &&
-+ test-tool chmtime =$just_over_15_days_ago $rr2/preimage &&
-+
-+ test_when_finished "rm -f .git/MERGE_RR.lock" &&
-+ >.git/MERGE_RR.lock &&
-+ git rerere gc 2>err &&
-+ test_grep "MERGE_RR.lock" err &&
-+ test_path_is_file $rr2/preimage &&
-+
-+ rm .git/MERGE_RR.lock &&
-+ git rerere gc &&
-+ test_path_is_missing $rr2/preimage
-+'
-+
+test_expect_success 'a held lock is waited out within rerere.lockTimeout' '
+ git reset --hard &&
+ rm -rf $rr &&
@@ t/t4200-rerere.sh: test_expect_success 'old records rest in peace' '
+ test_path_is_missing $rr/preimage
+'
+
-+test_expect_success 'rerere, forget and clear fail on a lock they cannot take' '
++test_expect_success 'rerere, forget, clear and gc fail on a lock they cannot take' '
+ test_when_finished "rm -f .git/MERGE_RR.lock" &&
+ >.git/MERGE_RR.lock &&
+ test_must_fail git -c rerere.lockTimeout=0 rerere 2>err &&
@@ t/t4200-rerere.sh: test_expect_success 'old records rest in peace' '
+ test_must_fail git -c rerere.lockTimeout=0 rerere forget a1 2>err &&
+ test_grep "Unable to create" err &&
+ test_must_fail git -c rerere.lockTimeout=0 rerere clear 2>err &&
++ test_grep "Unable to create" err &&
++ test_must_fail git -c rerere.lockTimeout=0 rerere gc 2>err &&
+ test_grep "Unable to create" err
+'
+
@@ t/t4200-rerere.sh: test_expect_success 'old records rest in peace' '
rerere_gc_custom_expiry_test () {
five_days="$1" right_now="$2"
test_expect_success "rerere gc with custom expiry ($five_days, $right_now)" '
-
- ## t/t7900-maintenance.sh ##
-@@ t/t7900-maintenance.sh: test_expect_success 'rerere-gc task with --auto honors maintenance.rerere-gc.aut
- test_expect_rerere_gc ! git -c maintenance.rerere-gc.auto=0 maintenance run --auto --task=rerere-gc
- '
-
-+test_expect_success 'rerere-gc task succeeds while MERGE_RR is locked' '
-+ test_when_finished "rm -rf .git/rr-cache .git/MERGE_RR.lock" &&
-+ mkdir .git/rr-cache &&
-+ : >.git/rr-cache/entry &&
-+ >.git/MERGE_RR.lock &&
-+ test_expect_rerere_gc git maintenance run --task=rerere-gc
-+'
-+
- test_expect_success '--auto and --schedule incompatible' '
- test_must_fail git maintenance run --auto --schedule=daily 2>err &&
- test_grep "cannot be used together" err
-: ---------- > 2: 27673137aa rerere: add "gc --auto" that skips a held lock
2: 1cce403113 ! 3: 3984c7666b rerere: go on at a conflict when the lock stays busy
@@ Commit message
When a merge, rebase, cherry-pick, revert, am, stash or apply stops
at a conflict, it runs rerere right before it returns to the user.
If MERGE_RR.lock is still held when rerere.lockTimeout runs out, the
- command dies there. For a rebase that is worse than a lost
- recording: the sequencer has not yet written the state that
- "git rebase --continue" needs, so the rebase cannot continue, and
- following the "git commit --amend" advice folds the conflicted pick
- into the previous commit.
+ command dies there. A rebase loses more than a recording that way.
+ The sequencer has not yet written the state that "git rebase
+ --continue" needs, so the rebase cannot go on, and the "git commit
+ --amend" it suggests instead folds the conflicted pick into the
+ previous commit.
- So print a warning and go on instead. The conflict is still in
- place, and the warning tells the user to run "git rerere" before
- resolving it. That records the preimage, or replays a known
- resolution, just as the command would have done.
+ So warn and go on. The conflict is still in place, and the warning
+ tells the user to run "git rerere" before resolving it, which records
+ the preimage or replays a known resolution as the command would have.
+ The hint is under advice.mergeConflict like the other hints printed
+ at a conflict stop.
- All other callers still fail when the timeout runs out. "git commit"
- and "git am --continue" record the resolution and then move on to
- the next commit or patch. A warning would come too late there, and
- the next rerere run would record whatever the file contains by then.
- The "rerere clear" that am and rebase run for --skip and --abort
- would leave the same stale entry behind. "git rerere", "git rerere
- forget" and "git rerere clear" fail because the user asked for that
- state explicitly.
+ Callers that run rerere after a resolution, like "git commit" and
+ "git am --continue", still fail when the wait is up. They move on
+ right away, and a leftover MERGE_RR entry would make the next rerere
+ run record whatever the file holds by then. The user's own rerere
+ commands and the "rerere clear" of --skip and --abort fail as well.
Assisted-by: Claude Fable 5.1
Signed-off-by: Thomas Bachem <mail@thomasbachem.com>
@@ Documentation/config/rerere.adoc: rerere.lockTimeout::
`git rerere gc`. Value 0 means not to wait at all; -1 means
to wait indefinitely. Default is 1000 (i.e., wait for 1
- second). When the time is up, the command fails as it does
-- for any other lock it cannot take. `git rerere gc` never
-- waits and skips its run while the lock is held.
+- for any other lock it cannot take. `git rerere gc --auto`
+- does not wait and does nothing while the lock is held.
+ second). When the time is up, a command that stops at a
+ conflict, such as `git merge` or `git rebase`, prints a
+ warning and goes on without rerere; run `git rerere` before
+ resolving the conflict to record it after all. Any other
+ command fails, as it does for any other lock it cannot take.
-+ `git rerere gc` never waits and skips its run while the lock
-+ is held.
++ `git rerere gc --auto` does not wait and does nothing while
++ the lock is held.
## apply.c ##
@@ apply.c: static int write_out_results(struct apply_state *state, struct patch *list)
@@ builtin/merge.c: static int suggest_conflicts(void)
return 1;
## builtin/stash.c ##
-@@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info *info,
+@@ builtin/stash.c: static enum stash_apply_result do_apply_stash(const char *prefix,
ret = error(_("could not write index"));
if (ret) {
@@ rerere.c: int setup_rerere(struct repository *r, struct string_list *merge_rr, i
if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
- if ((flags & RERERE_READONLY) && (flags & RERERE_NOWAIT))
-- BUG("RERERE_READONLY takes no lock, so RERERE_NOWAIT does not apply");
+- BUG("RERERE_NOWAIT does not apply with RERERE_READONLY");
+ if ((flags & RERERE_READONLY) &&
+ (flags & (RERERE_NOWAIT | RERERE_SKIP_LOCKED)))
+ BUG("RERERE_READONLY takes no lock, so no lock flag applies");
if (flags & RERERE_READONLY) {
fd = 0;
} else {
++ const char *path = git_path_merge_rr(r);
+ int lock_flags = LOCK_DIE_ON_ERROR;
+ int timeout_ms = rerere_lock_timeout_ms;
+
@@ rerere.c: int setup_rerere(struct repository *r, struct string_list *merge_rr, int flags)
- * Another process may hold the lock for a while, e.g.
* "git rerere gc" while it prunes rr-cache, so wait for
- * it instead of dying right away. The gc itself never
-- * waits: skipping one of its runs costs nothing.
-+ * waits: skipping one of its runs costs nothing. A
-+ * command that stops at a conflict must not die here
-+ * either, so it warns and goes on without rerere.
+ * it instead of dying right away. The gc of an automatic
+ * maintenance run does not wait, since skipping one of
+- * its runs costs nothing.
++ * its runs costs nothing. A command that stops at a
++ * conflict must not die here either, so it warns and
++ * goes on without rerere.
*/
if (flags & RERERE_NOWAIT) {
lock_flags = 0;
@@ rerere.c: int setup_rerere(struct repository *r, struct string_list *merge_rr, i
+ if (flags & RERERE_SKIP_LOCKED)
+ lock_flags = 0;
fd = repo_hold_lock_file_for_update_timeout(r, &write_lock,
- path, lock_flags,
- timeout_ms);
- if (fd < 0) {
- warning_errno(_("skipping rerere, "
- "unable to create '%s.lock'"), path);
-+ if (flags & RERERE_SKIP_LOCKED)
-+ advise(_("run \"git rerere\" before resolving "
-+ "the conflict to record or replay "
-+ "its resolution"));
+- git_path_merge_rr(r),
+- lock_flags, timeout_ms);
+- if (fd < 0)
++ path, lock_flags,
++ timeout_ms);
++ if (fd < 0) {
++ if (flags & RERERE_SKIP_LOCKED) {
++ warning_errno(_("skipping rerere, "
++ "unable to create '%s.lock'"),
++ path);
++ advise_if_enabled(ADVICE_MERGE_CONFLICT,
++ _("run \"git rerere\" before "
++ "resolving the conflict to "
++ "record or replay its "
++ "resolution"));
++ }
return -1;
- }
++ }
}
+ read_rr(r, merge_rr);
+ return fd;
## rerere.h ##
@@ rerere.h: struct repository;
#define RERERE_READONLY 04
- /* Never wait for MERGE_RR.lock, and skip the run when it is held */
+ /* Take MERGE_RR.lock only if it is free, and return quietly otherwise */
#define RERERE_NOWAIT 010
+/* Warn and go on without rerere if MERGE_RR.lock cannot be taken in time */
+#define RERERE_SKIP_LOCKED 020
@@ t/t4200-rerere.sh: test_expect_success 'a held lock is waited out within rerere.
+ test_grep "^=======\$" a1
+'
+
- test_expect_success 'rerere, forget and clear fail on a lock they cannot take' '
+ test_expect_success 'rerere, forget, clear and gc fail on a lock they cannot take' '
test_when_finished "rm -f .git/MERGE_RR.lock" &&
>.git/MERGE_RR.lock &&
--
gitgitgadget
next prev parent reply other threads:[~2026-09-28 11:58 UTC|newest]
Thread overview: 52+ 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
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 ` Thomas Bachem via GitGitGadget [this message]
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
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=pull.2214.v5.git.1790596702.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mail@thomasbachem.com \
--cc=phillip.wood123@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ps@pks.im \
/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.