From 882942ed7ba67b4cd2d0651e7e4ade81b242de0a Mon Sep 17 00:00:00 2001 From: "Ilia.Shulgin" Date: Thu, 12 Feb 2026 17:38:07 +0100 Subject: [PATCH] refactoring [git]: Align READ_OPTIONAL_LOCKING behavior with READ if write side-effect can be skipped GitOrigin-RevId: 2f4fac1c307f199c9c83c94c78c04c67c6381e48 --- .../git4idea/src/git4idea/commands/GitCommand.java | 6 ++++++ .../src/git4idea/commands/GitImplBase.java | 14 +++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/git4idea/src/git4idea/commands/GitCommand.java b/plugins/git4idea/src/git4idea/commands/GitCommand.java index b93d7dcd28cb..3f84cbb77e98 100644 --- a/plugins/git4idea/src/git4idea/commands/GitCommand.java +++ b/plugins/git4idea/src/git4idea/commands/GitCommand.java @@ -97,6 +97,12 @@ public final class GitCommand { @ApiStatus.Internal public enum LockingPolicy { READ, + /** + * Commands with non-mandatory write side effects (e.g. git status) can be executed without locking the index + * by setting env variable "GIT_OPTIONAL_LOCKS=0" or passing "--no-optional-locks". + *
+ * See the registry key "git.use.no.optional.locks" + */ READ_OPTIONAL_LOCKING, WRITE } diff --git a/plugins/git4idea/src/git4idea/commands/GitImplBase.java b/plugins/git4idea/src/git4idea/commands/GitImplBase.java index cbfa7feec20c..6709aa462b8f 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImplBase.java +++ b/plugins/git4idea/src/git4idea/commands/GitImplBase.java @@ -416,16 +416,13 @@ public abstract class GitImplBase implements Git { private static @NotNull AccessToken lock(@NotNull GitLineHandler handler, boolean canSuppressOptionalLocks) { Project project = handler.project(); - LockingPolicy lockingPolicy = handler.getCommand().lockingPolicy(); - if (project == null || project.isDefault() || lockingPolicy == READ) { + if (project == null || project.isDefault() || !shouldTakeWriteLock(handler, canSuppressOptionalLocks)) { return AccessToken.EMPTY_ACCESS_TOKEN; } ReadWriteLock executionLock = GitVcs.getInstance(project).getCommandLock(); - Lock lock = lockingPolicy == READ_OPTIONAL_LOCKING && canSuppressOptionalLocks - ? executionLock.readLock() - : executionLock.writeLock(); + Lock lock = executionLock.writeLock(); ProgressIndicatorUtils.awaitWithCheckCanceled(lock); return new AccessToken() { @@ -436,6 +433,13 @@ public abstract class GitImplBase implements Git { }; } + private static boolean shouldTakeWriteLock(@NotNull GitLineHandler handler, boolean canSuppressOptionalLocks) { + LockingPolicy lockingPolicy = handler.getCommand().lockingPolicy(); + return lockingPolicy != READ && + // If lock can't be suppressed, then command can be executed with writing side effects + (lockingPolicy != READ_OPTIONAL_LOCKING || !canSuppressOptionalLocks); + } + public static boolean looksLikeProgress(@NotNull String line) { if (PROGRESS_PATTERN.matcher(line).matches()) return true; return ContainerUtil.exists(SUPPRESSED_PROGRESS_INDICATORS, prefix -> {