From 6d5f2476d4ff089e7e722806f671aac5cbdfff95 Mon Sep 17 00:00:00 2001 From: Ammar Date: Fri, 5 Dec 2025 09:41:07 -0600 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20fix:=20minimize=20git=20lock=20c?= =?UTF-8?q?onflicts=20with=20smart=20fetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The background git fetch polling was creating locks that conflicted with terminal commands and agent git operations. Now uses a smarter approach: 1. git ls-remote to get remote SHA (no lock, network only) 2. git cat-file -e to check if SHA exists locally (no lock) 3. If local: skip fetch entirely (no lock needed) 4. If not local: fetch to get new commits (lock, but rare) This eliminates locks in the common case where the remote SHA is already local (e.g., IDE or user already fetched). Locks only occur when there are genuinely new remote commits that haven't been fetched by anyone. _Generated with `mux`_ --- src/common/utils/git/gitStatus.ts | 37 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/common/utils/git/gitStatus.ts b/src/common/utils/git/gitStatus.ts index e6650c71f6..6f9a58e0a5 100644 --- a/src/common/utils/git/gitStatus.ts +++ b/src/common/utils/git/gitStatus.ts @@ -82,10 +82,17 @@ export function parseGitStatusScriptOutput(output: string): ParsedGitStatusOutpu } /** - * Optimized git fetch script with no prompts. + * Smart git fetch script that minimizes lock contention. * - * Environment variables disable all interactive prompts (keychain, SSH, credentials). - * Git flags optimize for speed - only fetch refs, not objects. + * Uses ls-remote to check if remote has new commits before fetching. + * This avoids locks in the common case where remote SHA is already local + * (e.g., IDE or user already fetched). + * + * Flow: + * 1. ls-remote to get remote SHA (no lock, network only) + * 2. cat-file to check if SHA exists locally (no lock) + * 3. If local: skip fetch (no lock needed) + * 4. If not local: fetch to get new commits (lock, but rare) */ export const GIT_FETCH_SCRIPT = ` # Disable ALL prompts @@ -94,7 +101,29 @@ export GIT_ASKPASS=echo export SSH_ASKPASS=echo export GIT_SSH_COMMAND="\${GIT_SSH_COMMAND:-ssh} -o BatchMode=yes -o StrictHostKeyChecking=accept-new" -# Fast fetch with optimization flags +# Get primary branch name +PRIMARY_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') +if [ -z "$PRIMARY_BRANCH" ]; then + PRIMARY_BRANCH=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | cut -d' ' -f5) +fi +if [ -z "$PRIMARY_BRANCH" ]; then + PRIMARY_BRANCH="main" +fi + +# Check remote SHA via ls-remote (no lock, network only) +REMOTE_SHA=$(git ls-remote origin "refs/heads/$PRIMARY_BRANCH" 2>/dev/null | cut -f1) +if [ -z "$REMOTE_SHA" ]; then + echo "SKIP: Could not get remote SHA" + exit 0 +fi + +# Check if SHA exists locally (no lock) +if git cat-file -e "$REMOTE_SHA" 2>/dev/null; then + echo "SKIP: Remote SHA already local" + exit 0 +fi + +# Remote has new commits we don't have - fetch them git -c protocol.version=2 \\ -c fetch.negotiationAlgorithm=skipping \\ fetch origin \\