Skip to content

merge-one-file Git Command Guide

The git merge-one-file command is the standard helper program used with git merge-index to resolve merges after the trivial merge done with git read-tree -m. It handles the three-way merge of individual files during Git merge operations.

Terminal window
git merge-one-file <filename>
ParameterDescription
<filename>File to perform three-way merge on
Input: Base file (common ancestor)
Our file (current branch version)
Their file (incoming branch version)
Output: Merged file with conflict markers if needed
Exit code: 0=success, 1=conflict
Terminal window
# merge-index calls merge-one-file for each conflicted file
git merge-index git-merge-one-file -a
# merge-one-file receives arguments from merge-index:
# $1=base-sha, $2=our-sha, $3=their-sha, $4=filename
Terminal window
# Merge single file (called by merge-index)
git merge-one-file conflicted-file.txt
# Check exit code for conflict detection
if git merge-one-file file.txt; then
echo "File merged successfully"
else
echo "File has conflicts - manual resolution needed"
fi
Terminal window
# Manually perform three-way merge
# Create base, ours, theirs versions
git show :1:file.txt > base.txt
git show :2:file.txt > ours.txt
git show :3:file.txt > theirs.txt
# Perform merge
git merge-one-file file.txt
# Check result
cat file.txt
Terminal window
# Process multiple conflicted files
git ls-files -u | awk '{print $4}' | sort | uniq | \
while read file; do
echo "Merging $file"
if git merge-one-file "$file"; then
echo "$file merged successfully"
git add "$file"
else
echo "$file needs manual resolution"
fi
done
#!/bin/bash
# Enhanced merge-one-file with custom logic
enhanced_merge_one_file() {
local filename="$1"
echo "Processing merge for $filename"
# Get file information
local base_sha="$1"
local our_sha="$2"
local their_sha="$3"
local file="$4"
# Custom merge logic based on file type
case "${filename##*.}" in
json|yml|yaml)
# Use jq for JSON/YAML merging
if command -v jq >/dev/null; then
git cat-file -p "$our_sha" > .ours.tmp
git cat-file -p "$their_sha" > .theirs.tmp
jq -s '.[0] * .[1]' .ours.tmp .theirs.tmp > "$filename" 2>/dev/null
if [ $? -eq 0 ]; then
echo "✓ JSON/YAML merge successful"
rm .ours.tmp .theirs.tmp
return 0
fi
fi
;;
md|txt)
# Use union strategy for documentation
git merge-file --union "$filename" \
<(git cat-file -p "$base_sha" 2>/dev/null || echo "") \
<(git cat-file -p "$our_sha") \
<(git cat-file -p "$their_sha")
return $?
;;
esac
# Fall back to standard merge
git merge-one-file "$filename"
}
# Use with merge-index
git merge-index enhanced_merge_one_file -a
Terminal window
# Analyze merge results
analyze_merge_results() {
local merge_log=$(mktemp)
# Create wrapper that logs results
cat > "$merge_log" << 'EOF'
#!/bin/bash
filename=$4
echo "$(date): Processing $filename" >> merge-analysis.log
if git merge-one-file "$filename" 2>/dev/null; then
echo "SUCCESS: $filename" >> merge-analysis.log
echo "✓ $filename"
else
echo "CONFLICT: $filename" >> merge-analysis.log
echo "✗ $filename"
exit 1
fi
EOF
chmod +x "$merge_log"
# Run merge with logging
if git merge-index "$merge_log" -a; then
echo "All files merged successfully"
echo "See merge-analysis.log for details"
else
echo "Some files need manual resolution"
echo "Failed files logged in merge-analysis.log"
fi
rm "$merge_log"
}
analyze_merge_results
Terminal window
# Optimize merge operations for large repositories
optimize_merge_performance() {
# Disable auto-GC during merge
git config gc.auto 0
# Set merge limits
git config merge.renameLimit 999999
git config diff.renameLimit 999999
# Use parallel processing where possible
# Note: merge-one-file is typically called per-file by merge-index
}
# Batch processing for efficiency
process_merge_batch() {
local batch_size="${1:-10}"
# Get list of conflicted files
conflicted_files=$(git ls-files -u | awk '{print $4}' | sort | uniq)
echo "$conflicted_files" | \
xargs -n "$batch_size" | \
while read batch; do
echo "Processing batch: $batch"
for file in $batch; do
git merge-one-file "$file" &
done
wait # Wait for batch to complete
done
}
optimize_merge_performance
process_merge_batch 5
#!/bin/bash
# Automated merge resolution with fallback
auto_resolve_merge() {
local strategy="${1:-standard}"
case "$strategy" in
"ours")
# Always take our version
git ls-files -u | awk '{print $4}' | sort | uniq | \
while read file; do
git checkout --ours "$file"
git add "$file"
done
;;
"theirs")
# Always take their version
git ls-files -u | awk '{print $4}' | sort | uniq | \
while read file; do
git checkout --theirs "$file"
git add "$file"
done
;;
"standard")
# Use merge-one-file with custom logic
git merge-index git-merge-one-file -a
;;
"intelligent")
# Use intelligent resolution based on file type
git merge-index intelligent-merge-resolver -a
;;
esac
# Check if any conflicts remain
if git ls-files -u | grep -q .; then
echo "Conflicts remain - manual resolution needed"
return 1
else
echo "All conflicts resolved"
return 0
fi
}
# Usage
auto_resolve_merge "standard"
Terminal window
# Merge conflict handling in CI
handle_ci_merge_conflicts() {
# Check if merge conflicts exist
if git ls-files -u | grep -q .; then
echo "Merge conflicts detected in CI"
# Attempt automatic resolution
if auto_resolve_merge "intelligent"; then
echo "Conflicts resolved automatically"
git commit -m "Auto-resolve merge conflicts"
else
echo "Manual conflict resolution required"
# Report conflicts for manual intervention
echo "Conflicted files:"
git ls-files -u | awk '{print $4}' | sort | uniq
# Fail the build
exit 1
fi
else
echo "No merge conflicts detected"
fi
}
# Use in CI pipeline
handle_ci_merge_conflicts
Terminal window
# Configure merge-one-file for development
setup_merge_environment() {
# Configure merge tool for interactive resolution
git config merge.tool vscode
git config mergetool.vscode.cmd "code --wait \$MERGED"
# Set up automatic merge for certain file types
echo "*.json merge=json-merge" >> .gitattributes
git config merge.json-merge.driver "jq -s '.[0] * .[1]' %O > %A"
# Configure rerere for learning from resolutions
git config rerere.enabled true
git config rerere.autoupdate true
echo "Merge environment configured"
echo "Use 'git mergetool' for interactive conflict resolution"
echo "Use 'git rerere status' to see learned resolutions"
}
setup_merge_environment
Terminal window
# Debug merge-one-file operation
GIT_TRACE=1 git merge-one-file conflicted-file.txt
# Check file permissions
ls -la conflicted-file.txt
# Verify file content
git show :1:conflicted-file.txt > base.txt
git show :2:conflicted-file.txt > ours.txt
git show :3:conflicted-file.txt > theirs.txt
# Manual merge test
git merge-file ours.txt base.txt theirs.txt
Terminal window
# Check index state
git status
git ls-files --stage conflicted-file.txt
# Reset problematic index entries
git checkout --theirs conflicted-file.txt
git checkout --ours conflicted-file.txt
# Verify repository integrity
git fsck --unreachable | head -10
Terminal window
# Fix file permissions
chmod 644 conflicted-file.txt
# Handle read-only files
chmod u+w conflicted-file.txt
# Check filesystem issues
df -h .
ls -la .git/
Terminal window
# Check file sizes
du -h conflicted-file.txt
# Handle memory limits
ulimit -v $((1024*1024*1024)) # 1GB limit
# Split large files if needed
split -l 10000 large-file.txt part-
git merge-one-file part-aa # Process first part
cat part-a* > merged-large-file.txt
#!/bin/bash
# Enterprise-grade merge conflict resolution
enterprise_merge_resolution() {
local ticket_id="$1"
local merge_strategy="${2:-standard}"
echo "=== Enterprise Merge Resolution ==="
echo "Ticket: $ticket_id"
echo "Strategy: $merge_strategy"
echo "Timestamp: $(date)"
# Pre-merge validation
conflicted_count=$(git ls-files -u | wc -l)
if [ "$conflicted_count" -eq 0 ]; then
echo "No conflicts detected"
return 0
fi
echo "Found $conflicted_count conflicted entries"
# Create backup
backup_branch="backup-before-merge-$(date +%Y%m%d-%H%M%S)"
git branch "$backup_branch"
# Resolution strategy selection
case "$merge_strategy" in
"ours")
echo "Using 'ours' strategy"
git ls-files -u | awk '{print $4}' | sort | uniq | \
while read file; do
git checkout --ours "$file"
git add "$file"
done
;;
"theirs")
echo "Using 'theirs' strategy"
git ls-files -u | awk '{print $4}' | sort | uniq | \
while read file; do
git checkout --theirs "$file"
git add "$file"
done
;;
"intelligent")
echo "Using intelligent resolution"
git merge-index intelligent-resolver -a
;;
"standard")
echo "Using standard merge-one-file"
git merge-index git-merge-one-file -a
;;
esac
# Verify resolution
remaining_conflicts=$(git ls-files -u | wc -l)
if [ "$remaining_conflicts" -eq 0 ]; then
echo "✓ All conflicts resolved"
# Create merge record
git notes add -m "Merge resolution: $ticket_id" HEAD
git notes append -m "Strategy: $merge_strategy" HEAD
git notes append -m "Resolved by: $(git config user.name)" HEAD
git notes append -m "Backup branch: $backup_branch" HEAD
return 0
else
echo "$remaining_conflicts conflicts remain"
echo "Manual resolution needed"
echo "Backup available at: $backup_branch"
return 1
fi
}
# Usage
enterprise_merge_resolution "PROJ-1234" "intelligent"
Terminal window
# Team merge conflict handling
team_merge_workflow() {
local feature_branch="$1"
local target_branch="${2:-main}"
echo "=== Team Merge Workflow ==="
echo "Feature: $feature_branch"
echo "Target: $target_branch"
# Pre-merge analysis
git checkout "$target_branch"
git pull origin "$target_branch"
# Check for conflicts
if git merge-tree "$target_branch" "$feature_branch" >/dev/null 2>&1; then
echo "✓ Clean merge possible"
git merge --no-ff "$feature_branch"
else
echo "⚠ Conflicts detected - using merge-one-file"
# Start merge
git merge "$feature_branch"
# Resolve conflicts with merge-one-file
if git merge-index git-merge-one-file -a; then
echo "✓ All conflicts resolved automatically"
git commit -m "Merge $feature_branch with auto-resolution"
else
echo "✗ Manual conflict resolution needed"
echo "Use 'git mergetool' for interactive resolution"
return 1
fi
fi
# Push merged changes
git push origin "$target_branch"
}
# Usage
team_merge_workflow "feature/user-authentication" "develop"
Terminal window
# QA merge validation
qa_merge_validation() {
local merge_commit="$1"
echo "=== QA Merge Validation ==="
# Check if merge has conflicts
if git ls-files -u | grep -q .; then
echo "✗ Merge has unresolved conflicts"
return 1
fi
# Validate merge quality
echo "Validating merge quality..."
# Check for merge-one-file usage patterns
git show "$merge_commit" --stat | grep -q "merge-one-file" && \
echo "✓ Used proper merge resolution tools"
# Check for conflict markers
if git show "$merge_commit" | grep -q "^<<<<<<<\|^=======\|^>>>>>>>"; then
echo "✗ Found conflict markers in merge"
return 1
fi
# Validate file integrity
git show "$merge_commit" --name-only | \
while read file; do
if [ -f "$file" ]; then
# Basic file validation
file "$file" | grep -q "text" && echo "$file is valid text"
fi
done
echo "✓ Merge validation passed"
return 0
}
# Use in QA process
qa_merge_validation "HEAD"

What’s the relationship between merge-one-file and git merge?

Section titled “What’s the relationship between merge-one-file and git merge?”

git merge uses merge-index internally, which calls merge-one-file for individual file merges. merge-one-file is the low-level file merge utility.

How do I create custom merge logic for merge-one-file?

Section titled “How do I create custom merge logic for merge-one-file?”

Write scripts that handle the three-way merge arguments passed by merge-index. Return 0 for success, non-zero for conflicts requiring manual resolution.

Yes, but merge logic must handle binary content appropriately. Standard merge-one-file is text-oriented and may not work well with binary files.

What’s the difference between merge-one-file and git merge-file?

Section titled “What’s the difference between merge-one-file and git merge-file?”

merge-one-file is called by merge-index for individual files during Git merges; git merge-file is a standalone three-way merge utility for manual file merging.

Use GIT_TRACE=1 for detailed execution tracing. Test merge operations manually before using in merge-index workflows.

Can merge-one-file work with custom merge drivers?

Section titled “Can merge-one-file work with custom merge drivers?”

Yes, merge-one-file can be replaced with custom merge programs in merge-index calls. Configure custom merge drivers in .gitattributes.

What’s the performance impact of merge-one-file?

Section titled “What’s the performance impact of merge-one-file?”

Very fast for individual files. Performance scales with number of conflicted files and file sizes. Memory usage depends on file content.

Use timeout command: timeout 300 git merge-index git-merge-one-file -a. Individual file merges may need per-file timeout handling.

Can merge-one-file work in bare repositories?

Section titled “Can merge-one-file work in bare repositories?”

Yes, operates on Git objects regardless of working directory. Useful for server-side merge operations and CI/CD pipelines.

What’s the exit code behavior of merge-one-file?

Section titled “What’s the exit code behavior of merge-one-file?”

Returns 0 for successful merge, non-zero when conflicts require manual resolution. merge-index uses this to determine merge success.

How do I integrate merge-one-file with external tools?

Section titled “How do I integrate merge-one-file with external tools?”

Write wrapper scripts that call external merge tools and return appropriate exit codes. Use in merge-index for custom merge workflows.

Can merge-one-file handle Unicode and international characters?

Section titled “Can merge-one-file handle Unicode and international characters?”

Yes, supports UTF-8 and other encodings. Ensure consistent encoding between all three file versions being merged.

What’s the relationship between merge-one-file and git rerere?

Section titled “What’s the relationship between merge-one-file and git rerere?”

git rerere records and reuses conflict resolutions. merge-one-file can benefit from rerere when the same conflicts occur repeatedly.

How do I handle merge-one-file in automated environments?

Section titled “How do I handle merge-one-file in automated environments?”

Test merge operations thoroughly, use appropriate exit code handling, implement fallback strategies for failed merges.

Can merge-one-file work with Git LFS files?

Section titled “Can merge-one-file work with Git LFS files?”

Yes, works normally with LFS pointer files. LFS handles the large file content separately from the Git merge process.

Applications of the git merge-one-file command

Section titled “Applications of the git merge-one-file command”
  1. Standard Merge Resolution: Serve as the default helper program for git merge-index during Git merge operations
  2. Custom Merge Logic: Enable specialized merge strategies for different file types and content
  3. Automated Conflict Resolution: Implement intelligent conflict resolution in CI/CD pipelines
  4. Enterprise Merge Workflows: Support complex merge requirements in corporate development environments
  5. Merge Quality Assurance: Validate merge operations and ensure consistent merge behavior
  6. Collaborative Development: Facilitate team merge processes with standardized conflict resolution