update-index Git Command Guide
The git update-index command registers file contents in the index (staging area) and manages Git’s internal state. It’s a low-level command that provides direct control over the index, allowing you to add, remove, and modify index entries with precise control over Git’s staging operations.
git update-index Syntax:
Section titled “git update-index Syntax:”git update-index [--add] [--remove] [--refresh] [-q] [--ignore-submodules] [--ignore-missing] [--unmerged] [--really-refresh] [--again] [--unresolve] [--info-only] [--index-info] [--chmod=(+|-)x] [--assume-unchanged] [--no-assume-unchanged] [--skip-worktree] [--no-skip-worktree] [--ignore-skip-worktree-entries] [--really-refresh] [--unresolve] [--again] [--info-only] [--index-info] [--chmod=(+|-)x] [--[no-]fsmonitor-valid] [--[no-]skip-worktree] [--[no-]assume-unchanged] [--[no-]ignore-skip-worktree-entries] [--renormalize] [--mode=<permissions>] [--cacheinfo <mode>,<object>,<path>] [--index-version <n>] [--null] [--file-truncate] [--untracked-cache] [--test-untracked-cache] [--force-untracked-cache] [--untracked-cache-no-op] [--force-remove] [--replace] [--stdin] [--verbose] [--clear-resolve-undo] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<pathspec>...]File Registration Options:
Section titled “File Registration Options:”| Option | Description |
|---|---|
--add | Add files not already in index |
--remove | Remove files from index and working tree |
--force-remove | Remove files even if modified |
--replace | Replace files in index |
Index State Options:
Section titled “Index State Options:”| Option | Description |
|---|---|
--refresh | Refresh stat information in index |
--really-refresh | Refresh even if up-to-date |
--again | Run refresh on previously failed entries |
--unresolve | Mark files as unresolved (merge conflicts) |
--clear-resolve-undo | Clear resolve-undo information |
File Permission Options:
Section titled “File Permission Options:”| Option | Description |
|---|---|
| `—chmod=(+ | -)x` |
--mode=<permissions> | Set file permissions |
--cacheinfo <mode>,<object>,<path> | Add arbitrary entry to index |
Skip Worktree Options:
Section titled “Skip Worktree Options:”| Option | Description |
|---|---|
--assume-unchanged | Mark files as unchanged |
--no-assume-unchanged | Unmark files as unchanged |
--skip-worktree | Mark files to skip worktree updates |
--no-skip-worktree | Unmark files for worktree updates |
--ignore-skip-worktree-entries | Ignore skip-worktree entries |
Advanced Options:
Section titled “Advanced Options:”| Option | Description |
|---|---|
--renormalize | Force re-normalization of files |
--info-only | Only show files that need updating |
--index-info | Read index info from stdin |
--stdin | Read file names from stdin |
--verbose | Verbose output |
-q, --quiet | Suppress output |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<pathspec> | Files/directories to operate on |
<mode> | File permissions (octal) |
<object> | SHA-1 of object to add |
Understanding Index Operations:
Section titled “Understanding Index Operations:”Git Index Structure:
Section titled “Git Index Structure:”Git Index (.git/index):├── File Entries: Path, SHA-1, permissions, timestamps├── Stage Information: Normal, ancestor, ours, theirs├── Skip Worktree: Files ignored by worktree updates├── Assume Unchanged: Files assumed unchanged└── Resolve Undo: Conflict resolution informationIndex Entry Components:
Section titled “Index Entry Components:”Index Entry Format:├── ctime: Change time (last metadata change)├── mtime: Modify time (last content change)├── dev/ino: Device/inode numbers├── mode: File permissions├── uid/gid: User/group IDs├── size: File size├── sha1: Object SHA-1 hash└── path: File pathStaging Area States:
Section titled “Staging Area States:”File States in Index:├── Untracked: Not in index or repository├── Unstaged: Modified but not in index├── Staged: In index, ready for commit├── Committed: In current commit└── Ignored: Excluded by .gitignoreBasic Update-Index Operations:
Section titled “Basic Update-Index Operations:”Adding Files to Index:
Section titled “Adding Files to Index:”# Add new files to indexgit update-index --add new-file.txt
# Add all files in directorygit update-index --add *.txt
# Add files with specific permissionsgit update-index --add --chmod=+x script.sh
# Add files from stdinecho "file1.txt" | git update-index --add --stdinRemoving Files from Index:
Section titled “Removing Files from Index:”# Remove file from indexgit update-index --remove old-file.txt
# Force remove modified filegit update-index --force-remove modified-file.txt
# Remove files matching patterngit update-index --remove *.tmpRefreshing Index Information:
Section titled “Refreshing Index Information:”# Refresh stat informationgit update-index --refresh
# Refresh all files including up-to-date onesgit update-index --really-refresh
# Refresh previously failed entriesgit update-index --againManaging File Permissions:
Section titled “Managing File Permissions:”# Add executable permissiongit update-index --chmod=+x script.sh
# Remove executable permissiongit update-index --chmod=-x script.sh
# Set specific permissionsgit update-index --mode=0644 file.txt
# Set executable permissionsgit update-index --mode=0755 script.shAdvanced Update-Index Scenarios:
Section titled “Advanced Update-Index Scenarios:”Skip Worktree Management:
Section titled “Skip Worktree Management:”# Mark files to skip worktree updatesgit update-index --skip-worktree large-file.dat
# Unmark files for worktree updatesgit update-index --no-skip-worktree large-file.dat
# List skip-worktree filesgit ls-files -v | grep "^S"
# Check skip-worktree statusgit ls-files --stage large-file.datAssume Unchanged Management:
Section titled “Assume Unchanged Management:”# Mark files as unchanged (performance optimization)git update-index --assume-unchanged config.local.php
# Unmark files as unchangedgit update-index --no-assume-unchanged config.local.php
# List assume-unchanged filesgit ls-files -v | grep "^h"
# Check assume-unchanged statusgit ls-files --stage config.local.phpManual Index Entry Management:
Section titled “Manual Index Entry Management:”# Add arbitrary entry to indexgit update-index --cacheinfo 100644,abc123def,file.txt
# Add blob object to indexblob_sha=$(echo "content" | git hash-object -w --stdin)git update-index --cacheinfo 100644,$blob_sha,new-file.txt
# Replace existing index entrygit update-index --cacheinfo 100644,newsha123,existing-file.txtIndex Information Management:
Section titled “Index Information Management:”# Read index info from stdingit update-index --index-info << EOF100644 abc123... 0 file1.txt100644 def456... 0 file2.txtEOF
# Show files needing updategit update-index --info-only
# Verbose index operationsgit update-index --verbose --add *.txtMerge Conflict Resolution:
Section titled “Merge Conflict Resolution:”# Mark files as unresolved (during merge)git update-index --unresolve conflicted-file.txt
# Clear resolve-undo informationgit update-index --clear-resolve-undo
# Check merge statusgit ls-files --stage conflicted-file.txtConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Update-Index:
Section titled “Git Configuration for Update-Index:”# Configure index behaviorgit config core.filemode true # Track file permissionsgit config core.ignorecase false # Case-sensitive file namesgit config core.trustctime false # Don't trust ctime for changes
# Configure performance optionsgit config core.untrackedcache true # Cache untracked filesgit config core.fsmonitor true # File system monitorgit config core.ignorestat true # Ignore stat changesSafe Update-Index Operations:
Section titled “Safe Update-Index Operations:”# Backup index before operationscp .git/index .git/index.backup
# Validate operationsgit update-index --dry-run --add new-files/
# Check index integritygit fsck --full --strict
# Restore index if neededcp .git/index.backup .git/indexPerformance Optimization:
Section titled “Performance Optimization:”# Enable untracked cachegit update-index --untracked-cache
# Test untracked cachegit update-index --test-untracked-cache
# Force untracked cache rebuildgit update-index --force-untracked-cache
# Disable untracked cache operationsgit update-index --untracked-cache-no-opFile System Monitor Integration:
Section titled “File System Monitor Integration:”# Mark files as fsmonitor validgit update-index --fsmonitor-valid *.txt
# Unmark files as fsmonitor validgit update-index --no-fsmonitor-valid *.txt
# Check fsmonitor statusgit ls-files --stage | grep fsmonitorIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”Build System Integration:
Section titled “Build System Integration:”#!/bin/bash# Update-index in build workflows
prepare_build_artifacts() { echo "Preparing build artifacts for index..."
# Add generated files to index find build/ -name "*.min.js" -exec git update-index --add {} \;
# Set proper permissions git update-index --chmod=+x build/scripts/*.sh
# Mark build artifacts as assume-unchanged git update-index --assume-unchanged build/artifacts/*
echo "Build artifacts prepared"}
# Clean build artifactsclean_build_artifacts() { echo "Cleaning build artifacts..."
# Remove build files from index git update-index --force-remove build/artifacts/*
# Reset permissions find build/ -name "*.sh" -exec git update-index --chmod=-x {} \;
echo "Build artifacts cleaned"}
# Usageprepare_build_artifacts# ... build process ...clean_build_artifactsLarge Repository Management:
Section titled “Large Repository Management:”# Manage large files in indexoptimize_large_repo() { echo "Optimizing large repository index..."
# Find large files git ls-files --stage | while read -r mode sha stage path; do size=$(git cat-file -s "$sha" 2>/dev/null || echo "0") if [ "$size" -gt 104857600 ]; then # > 100MB echo "Marking large file as skip-worktree: $path" git update-index --skip-worktree "$path" fi done
# Mark build artifacts as assume-unchanged find . -name "*.jar" -o -name "*.war" | while read -r file; do git update-index --assume-unchanged "$file" 2>/dev/null done
echo "Large repository optimized"}
# Restore full worktreerestore_worktree() { echo "Restoring full worktree..."
# Unmark skip-worktree files git ls-files -v | grep "^S" | cut -c3- | while read -r file; do git update-index --no-skip-worktree "$file" done
# Unmark assume-unchanged files git ls-files -v | grep "^h" | cut -c3- | while read -r file; do git update-index --no-assume-unchanged "$file" done
echo "Worktree restored"}Selective Staging Workflows:
Section titled “Selective Staging Workflows:”# Advanced selective stagingselective_staging() { local pattern="$1"
echo "Performing selective staging for pattern: $pattern"
# Find files matching pattern git ls-files --others --exclude-standard | grep "$pattern" | while read -r file; do echo "Adding untracked file: $file" git update-index --add "$file" done
# Refresh modified files matching pattern git ls-files | grep "$pattern" | while read -r file; do if [ -n "$(git diff "$file")" ]; then echo "Refreshing modified file: $file" git update-index "$file" fi done
echo "Selective staging complete"}
# Usageselective_staging "\.java$"Troubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Index Corruption Issues:
Section titled “Index Corruption Issues:”# Check index integritygit fsck --full --strict
# Rebuild index from HEADrm .git/indexgit read-tree HEAD
# Recover from backupcp .git/index.backup .git/index
# Reset index to HEADgit reset --hard HEADFile Permission Issues:
Section titled “File Permission Issues:”# Fix permission inconsistenciesgit ls-files --stage | while read -r mode sha stage path; do if [ -f "$path" ]; then actual_mode=$(stat -c%a "$path" 2>/dev/null || stat -f%p "$path" | cut -c4-6) index_mode=$(printf "%o" $((mode & 0777))) if [ "$actual_mode" != "$index_mode" ]; then echo "Fixing permissions for: $path" chmod "$index_mode" "$path" fi fidone
# Refresh permissions in indexgit update-index --refreshSkip Worktree Conflicts:
Section titled “Skip Worktree Conflicts:”# Resolve skip-worktree conflictsgit ls-files -v | grep "^S" | while read -r line; do file=$(echo "$line" | cut -c3-) if [ -n "$(git diff HEAD "$file")" ]; then echo "Conflict detected for skip-worktree file: $file" # Choose: keep worktree version or index version git update-index "$file" # Update index to match worktree # or: git checkout HEAD "$file" # Update worktree to match index fidone
# Clear all skip-worktree marksgit ls-files -v | grep "^S" | cut -c3- | xargs git update-index --no-skip-worktreeAssume Unchanged Issues:
Section titled “Assume Unchanged Issues:”# Check for assume-unchanged conflictsgit ls-files -v | grep "^h" | while read -r line; do file=$(echo "$line" | cut -c3-) if [ -n "$(git diff "$file")" ]; then echo "Assume-unchanged file has changes: $file" git update-index --no-assume-unchanged "$file" fidone
# Reset assume-unchanged statusgit ls-files -v | grep "^h" | cut -c3- | xargs git update-index --no-assume-unchangedIndex Refresh Issues:
Section titled “Index Refresh Issues:”# Force index refreshgit update-index --really-refresh
# Clear stat cacherm .git/indexgit read-tree HEAD
# Handle filesystem timestamp issuesgit config core.ignorestat truegit update-index --refreshgit config core.ignorestat falseMemory and Performance Issues:
Section titled “Memory and Performance Issues:”# Handle large index filesgit config core.untrackedcache false # Disable for large reposgit update-index --untracked-cache-no-op
# Optimize index operationsgit config core.deltaBaseCacheLimit 2ggit config pack.threads 1
# Split large index operationsfind . -name "*.txt" | head -100 | xargs git update-index --addfind . -name "*.txt" | tail -n +101 | xargs git update-index --addReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Custom Staging Workflows:
Section titled “Custom Staging Workflows:”#!/bin/bash# Advanced staging workflows with update-index
intelligent_staging() { echo "=== Intelligent Staging Workflow ==="
# Stage only modified configuration files git ls-files | grep "config.*\.yml$" | while read -r file; do if git diff --quiet "$file"; then echo "No changes in: $file" else echo "Staging changes in: $file" git update-index "$file" fi done
# Stage new documentation files git ls-files --others --exclude-standard | grep "\.md$" | while read -r file; do echo "Adding new documentation: $file" git update-index --add "$file" done
# Skip staging large binary files git ls-files --others | while read -r file; do if [ -f "$file" ]; then size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file") if [ "$size" -gt 10485760 ]; then # > 10MB echo "Skipping large file: $file" continue fi fi git update-index --add "$file" done
echo "Intelligent staging complete"}
# Selective unstagingselective_unstaging() { echo "=== Selective Unstaging ==="
# Unstage files larger than threshold git diff --cached --name-only | while read -r file; do size=$(git cat-file -s :"$file" 2>/dev/null || echo "0") if [ "$size" -gt 5242880 ]; then # > 5MB echo "Unstaging large file: $file" git update-index --force-remove "$file" fi done
# Unstage generated files git diff --cached --name-only | grep -E "\.(min\.js|min\.css)$" | while read -r file; do echo "Unstaging generated file: $file" git update-index --force-remove "$file" done
echo "Selective unstaging complete"}
# Usageintelligent_stagingselective_unstagingRepository Integrity Management:
Section titled “Repository Integrity Management:”# Index integrity and consistency checksindex_integrity_check() { echo "=== Index Integrity Check ==="
# Verify index matches working directory git update-index --refresh --info-only | while read -r file; do echo "File needs refresh: $file" done
# Check for inconsistent file modes git ls-files --stage | while read -r mode sha stage path; do if [ -f "$path" ]; then actual_mode=$(stat -c%a "$path" 2>/dev/null || echo "unknown") index_mode=$(printf "%o" $((mode & 0777))) if [ "$actual_mode" != "$index_mode" ] && [ "$actual_mode" != "unknown" ]; then echo "Permission mismatch: $path (index: $index_mode, actual: $actual_mode)" git update-index --mode="$actual_mode" "$path" fi fi done
# Verify object existence git ls-files --stage | while read -r mode sha stage path; do if ! git cat-file -e "$sha" 2>/dev/null; then echo "Missing object for: $path ($sha)" git update-index --force-remove "$path" fi done
echo "Index integrity check complete"}
# Index optimizationoptimize_index() { echo "=== Index Optimization ==="
# Enable performance features git update-index --untracked-cache git update-index --fsmonitor-valid
# Refresh and compact index git update-index --really-refresh
# Remove unnecessary entries git ls-files --others --exclude-standard | head -100 | xargs git update-index --add 2>/dev/null || true
echo "Index optimization complete"}
# Usageindex_integrity_checkoptimize_indexBuild System Integration:
Section titled “Build System Integration:”# Update-index in build pipelinesbuild_pipeline_integration() { echo "=== Build Pipeline Integration ==="
# Prepare build environment setup_build_index() { echo "Setting up build index..."
# Mark source files as assume-unchanged during build find src/ -name "*.ts" -o -name "*.js" | xargs git update-index --assume-unchanged 2>/dev/null || true
# Add build outputs mkdir -p dist/ echo "Build output placeholder" > dist/.gitkeep git update-index --add dist/.gitkeep
echo "Build index setup complete" }
# Update index after build update_build_index() { echo "Updating index after build..."
# Unmark source files find src/ -name "*.ts" -o -name "*.js" | xargs git update-index --no-assume-unchanged 2>/dev/null || true
# Add build artifacts find dist/ -type f -not -name ".gitkeep" | while read -r file; do git update-index --add "$file" 2>/dev/null || true done
# Set proper permissions on executables find dist/ -name "*.sh" -o -name "*.exe" | xargs git update-index --chmod=+x 2>/dev/null || true
echo "Build index updated" }
# Clean build artifacts from index clean_build_index() { echo "Cleaning build artifacts from index..."
# Remove build files git ls-files dist/ | xargs git update-index --force-remove 2>/dev/null || true
# Keep placeholder git update-index --add dist/.gitkeep 2>/dev/null || true
echo "Build index cleaned" }
# Run pipeline steps setup_build_index echo "Building application..." # ... actual build commands ... update_build_index echo "Build pipeline complete"}
# Usagebuild_pipeline_integrationMonorepo Management:
Section titled “Monorepo Management:”# Update-index for monorepo workflowsmonorepo_index_management() { echo "=== Monorepo Index Management ==="
# Manage team-specific index states team_index_workflow() { local team="$1"
echo "Managing index for team: $team"
# Create team-specific index snapshot git ls-files --stage > "team-$team-index.txt"
# Mark team files as assume-unchanged for other teams find "teams/$team/" -type f | while read -r file; do if git ls-files --error-unmatch "$file" >/dev/null 2>&1; then git update-index --assume-unchanged "$file" fi done
echo "Team index configured" }
# Selective operations by directory selective_directory_ops() { local operation="$1" local directory="$2"
echo "Performing $operation on directory: $directory"
case "$operation" in "add") find "$directory" -type f | while read -r file; do git update-index --add "$file" 2>/dev/null || true done ;; "remove") git ls-files "$directory" | xargs git update-index --force-remove 2>/dev/null || true ;; "refresh") git ls-files "$directory" | xargs git update-index --refresh 2>/dev/null || true ;; esac
echo "Directory operation complete" }
# Index performance monitoring monitor_index_performance() { echo "=== Index Performance Monitoring ==="
# Measure index operations start_time=$(date +%s.%3N) git update-index --refresh >/dev/null 2>&1 end_time=$(date +%s.%3N)
refresh_time=$(echo "$end_time - $start_time" | bc) echo "Index refresh time: ${refresh_time}s"
# Check index size index_size=$(stat -f%z .git/index 2>/dev/null || stat -c%s .git/index) echo "Index file size: $index_size bytes"
# Count index entries entry_count=$(git ls-files | wc -l) echo "Index entries: $entry_count"
# Performance recommendations if [ "$entry_count" -gt 100000 ]; then echo "Consider enabling untracked cache: git update-index --untracked-cache" fi
if (( $(echo "$refresh_time > 10" | bc -l) )); then echo "Consider enabling fsmonitor: git config core.fsmonitor true" fi }
# Interactive monorepo management echo "Monorepo Index Management Options:" echo "1. Configure team index" echo "2. Selective directory operations" echo "3. Monitor index performance"
read -p "Select option (1-3): " option
case "$option" in 1) read -p "Team name: " team team_index_workflow "$team" ;; 2) read -p "Operation (add/remove/refresh): " op read -p "Directory: " dir selective_directory_ops "$op" "$dir" ;; 3) monitor_index_performance ;; *) echo "Invalid option" ;; esac}
# Usagemonorepo_index_management