Skip to content

Git for Windows 2.53.0.windows.1 slow log performance #6120

@dustybluebird

Description

@dustybluebird

Existing issues matching what you're seeing

  • I was not able to find an open or closed issue matching what I'm seeing

Git for Windows version

git version 2.53.0.windows.1
cpu: x86_64
built from commit: a5512bdee37ed7142c233d21e2d347ffc4860ff3
sizeof-long: 4
sizeof-size_t: 8
shell-path: D:/git-sdk-64-build-installers/usr/bin/sh
rust: disabled
feature: fsmonitor--daemon
gettext: enabled
libcurl: 8.18.0
OpenSSL: OpenSSL 3.5.5 27 Jan 2026
zlib: 1.3.1
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1

Windows version

Windows 10

Windows CPU architecture

x86_64 (64-bit)

Additional Windows version information

Microsoft Windows [Version 10.0.19045.6456]

Options set during installation

Editor Option: Notepad
Custom Editor Path:
Default Branch Option:
Path Option: Cmd
SSH Option: OpenSSH
Tortoise Option: false
CURL Option: OpenSSL
CRLF Option: CRLFAlways
Bash Terminal Option: MinTTY
Git Pull Behavior Option: Merge
Use Credential Manager: Enabled
Performance Tweaks FSCache: Enabled
Enable Symlinks: Disabled
Enable FSMonitor: Disabled

Other interesting things

No response

Terminal/shell

CMD

Commands that trigger the issue

#!/bin/bash

# Benchmark Git Operations for IntelliJ VCS performance diagnosis
# This script measures execution time of common Git operations used by the IDE.
# It takes multiple samples and averages them for more reliable results.

REPO_PATH="."
SAMPLES=5

if [ ! -z "$1" ] && [[ "$1" =~ ^[0-9]+$ ]]; then
  SAMPLES=$1
  shift
fi

if [ ! -z "$1" ]; then
  REPO_PATH="$1"
fi

cd "$REPO_PATH" || exit 1
echo "Benchmarking Git in: $(pwd)"
echo "Samples per operation: $SAMPLES"
git --version

# Define operations to benchmark
OPS=("Full_VCS_Log" "File_History" "Metadata" "Revision_Status")

get_cmd() {
  case $1 in
    "Full_VCS_Log") echo "log --date-order --pretty=format:%H --all -n 10000" ;;
    "File_History") echo "log --full-history --simplify-merges --name-status --pretty=format:%H --encoding=UTF-8 -M --follow community/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java" ;;
    "Metadata") echo "log --no-walk --stdin --pretty=format:%H%x01%ct%x01%an%x01%at%x01%ae%x01%cn%x01%ce%x01%P%x01%s%x01%b%x02" ;;
    "Revision_Status") echo "log -n1 --pretty=format:%H --all -- community/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java" ;;
  esac
}

# Function to run benchmark with multiple samples
run_benchmark() {
  local label="$1"
  local cmd="$2"
  local env_vars="$3"
  local durations=()

  echo "Running: $label"
  
  local hashes=""
  if [[ "$label" == "Metadata" ]]; then
    hashes=$(git rev-list HEAD -n 100)
  fi

  for ((i=1; i<=SAMPLES; i++)); do
    local start_time end_time duration
    
    if [[ "$label" == "Metadata" ]]; then
      start_time=$(python -c 'import time; print(time.time())')
      echo "$hashes" | env $env_vars git $cmd > /dev/null 2>&1
      end_time=$(python -c 'import time; print(time.time())')
    else
      start_time=$(python -c 'import time; print(time.time())')
      env $env_vars git $cmd > /dev/null 2>&1
      end_time=$(python -c 'import time; print(time.time())')
    fi
    
    duration=$(python -c "print($end_time - $start_time)")
    durations+=("$duration")
    printf "  Sample %d: %.3f s\n" "$i" "$duration"
  done

  # Calculate statistics using python
  python -c "
import sys
durations = [float(x) for x in sys.argv[1:]]
if not durations:
    print('  No samples recorded.')
    sys.exit(0)
avg = sum(durations) / len(durations)
min_val = min(durations)
max_val = max(durations)
print(f'  Results: Avg: {avg:.3f} s | Min: {min_val:.3f} s | Max: {max_val:.3f} s')
" "${durations[@]}"

  return 0
}

echo "--------------------------------------------------------"
echo "Scenario 1: Default Settings"
for op in "${OPS[@]}"; do
  run_benchmark "$op" "$(get_cmd $op)" ""
done

echo "--------------------------------------------------------"
echo "Scenario 2: GIT_OPTIONAL_LOCKS=0"
for op in "${OPS[@]}"; do
  run_benchmark "$op" "$(get_cmd $op)" "GIT_OPTIONAL_LOCKS=0"
done

echo "--------------------------------------------------------"
echo "Scenario 3: core.symlinks=false"
ORIG_SYMLINKS=$(git config core.symlinks)
git config core.symlinks false
for op in "${OPS[@]}"; do
  run_benchmark "$op" "$(get_cmd $op)" ""
done
git config core.symlinks "$ORIG_SYMLINKS"

echo "--------------------------------------------------------"
echo "Maintenance & Index Status:"
git maintenance status 2>/dev/null || echo "Git maintenance not supported or configured."
git commit-graph verify 2>/dev/null || echo "Commit-graph not found or invalid."

echo "--------------------------------------------------------"
echo "Done."

Expected behaviour

I would expect similar performance across git versions

Actual behaviour

Git 2.53.0.windows.1 is around twice as slow as other versions for
log -n1 --pretty=format:%H --all -- community/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java

Issue seems to be fixed in 2.53.0.windows.2 and doesn't occur in older versions (e.g 2.50)

Version Scenario Avg Min Max
2.50.0.windows.1 Default 5.58 s 5.55 s 5.67 s
2.50.0.windows.1 GIT_OPTIONAL_LOCKS=0 5.62 s 5.55 s 5.95 s
2.50.0.windows.1 core.symlinks=false 5.95 s 5.58 s 6.95 s
2.53.0.windows.1 Default 13.27 s 9.67 s 20.88 s
2.53.0.windows.1 GIT_OPTIONAL_LOCKS=0
2.53.0.windows.2 Default 6.87 s 6.15 s 55.02 s*
2.53.0.windows.2 GIT_OPTIONAL_LOCKS=0 6.40 s 6.17 s 6.79 s
2.53.0.windows.2 core.symlinks=false 6.59 s 6.16 s 9.16 s
  • The 55 s outlier in 2.53.0.windows.2 default is the cold-start sample 1 — the steady-state is ~6.25 s.
    Note: the 2.53.0.windows.1 run was stopped early since it was clear it's slower, so GIT_OPTIONAL_LOCKS=0 data isn't available for it.

Full benchmarks attached.
2.50_extended.txt
2.53.2.txt
2.53.txt

Repository

Repo used for benchmark: https://github.com/JetBrains/intellij-community

But I expect similar results on any sufficiently large repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions