merge-file Git Command Guide
The git merge-file command performs three-way file merging, combining changes from two modified versions of a file into a single result. It takes three files (current, base, other) and merges changes from base→other into current, handling conflicts with standard conflict markers.
git merge-file Syntax:
Section titled “git merge-file Syntax:”git merge-file [-L <current-name> [-L <base-name> [-L <other-name>]]] [--ours|--theirs|--union] [-p|--stdout] [-q|--quiet] [--marker-size=<n>] [--[no-]diff3] [--object-id] <current> <base> <other>Merge Strategy Options:
Section titled “Merge Strategy Options:”| Option | Description |
|---|---|
--ours | Choose our version on conflicts |
--theirs | Choose their version on conflicts |
--union | Combine both versions on conflicts |
Output Control Options:
Section titled “Output Control Options:”| Option | Description |
|---|---|
-p, --stdout | Send output to stdout instead of overwriting file |
-q, --quiet | Suppress conflict warnings |
--marker-size=<n> | Change conflict marker size |
Label Options:
Section titled “Label Options:”| Option | Description |
|---|---|
-L <label> | Use custom label for conflict markers |
Advanced Options:
Section titled “Advanced Options:”| Option | Description |
|---|---|
--diff3 | Use diff3-style conflict markers |
--no-diff3 | Use standard conflict markers |
--object-id | Add object IDs to conflict markers |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<current> | Current version of the file (will be modified) |
<base> | Common ancestor/base version |
<other> | Other version to merge in |
Basic Merge Examples:
Section titled “Basic Merge Examples:”Three-way File Merge:
Section titled “Three-way File Merge:”# Merge changes from other into current using base as referencegit merge-file current.txt base.txt other.txt
# Merge with custom output (don't modify current file)git merge-file -p current.txt base.txt other.txt > merged.txtConflict Resolution Strategies:
Section titled “Conflict Resolution Strategies:”# Always prefer current version on conflictsgit merge-file --ours current.txt base.txt other.txt
# Always prefer other version on conflictsgit merge-file --theirs current.txt base.txt other.txt
# Combine both versions on conflictsgit merge-file --union current.txt base.txt other.txtCustom Conflict Labels:
Section titled “Custom Conflict Labels:”# Use descriptive labels instead of filenamesgit merge-file -L current -L base -L other current.txt base.txt other.txt
# Name versions for easier conflict resolutiongit merge-file -L "My changes" -L "Common base" -L "Their changes" file.txt base.txt their.txtUnderstanding Three-Way Merge:
Section titled “Understanding Three-Way Merge:”Merge Concept:
Section titled “Merge Concept:”Original (base) Modified A (other) | | | | git merge-file merges changes | | A->base into current file v vCurrent (our version) <-- merges to --> ResultConflict Example:
Section titled “Conflict Example:”<<<<<<< current.txtLine from current fileChange made in our branchLine from other fileChange made in their branch>>>>>>> other.txtDiff3 Style Conflicts:
Section titled “Diff3 Style Conflicts:”<<<<<<< current.txtour line||||||| base.txtoriginal linetheir line>>>>>>> other.txtAdvanced Usage Scenarios:
Section titled “Advanced Usage Scenarios:”Version Control Conflict Resolution:
Section titled “Version Control Conflict Resolution:”#!/bin/bash# Resolve merge conflicts using merge-file
resolve_conflict() { local conflicted_file="$1" local base_commit="${2:-HEAD~1}" # Merge base local our_commit="${3:-HEAD}" local their_commit="${4:-MERGE_HEAD}"
# Create temporary versions git show "$base_commit:$conflicted_file" > .base.tmp git show "$our_commit:$conflicted_file" > .ours.tmp git show "$their_commit:$conflicted_file" > .theirs.tmp
# Perform three-way merge if git merge-file -p .ours.tmp .base.tmp .theirs.tmp > "$conflicted_file"; then echo "✓ Auto-merged $conflicted_file"
# Clean up rm .base.tmp .ours.tmp .theirs.tmp git add "$conflicted_file" else echo "Conflicts remain in $conflicted_file" echo "Edit $conflicted_file and run 'git add $conflicted_file'" # Leave temporary files for manual resolution fi}
# Usageresolve_conflict "conflicted-file.txt"Patch Application with Conflict Detection:
Section titled “Patch Application with Conflict Detection:”# Test if patch can be applied cleanlyapply_with_merge() { local patch_file="$1" local target_file="$2"
# Backup original cp "$target_file" "${target_file}.backup"
# Get base version (unpatched) # This would need to be implemented based on patch format
# Apply changes using merge-file git merge-file "$target_file" base.txt patched.txt}
# Example workflow for patch testing# (Assumes base.txt exists as unpatched version)# git merge-file --stdout current.txt base.txt patched.txt | patch --dry-runBranch Integration Testing:
Section titled “Branch Integration Testing:”# Test how branches would merge without committingtest_branch_merge() { local feature_branch="$1" local target_branch="${2:-main}"
# Get merge base base_commit=$(git merge-base "$target_branch" "$feature_branch")
# Test merge for each conflicting file git diff --name-only "$base_commit" "$target_branch" "$feature_branch" | while read file; do echo "Testing merge of $file"
# Create temporary versions git show "$base_commit:$file" > .base.tmp git show "$target_branch:$file" > .target.tmp git show "$feature_branch:$file" > .feature.tmp
# Try merge if git merge-file -q .target.tmp .base.tmp .feature.tmp; then echo "✓ $file merges cleanly" else echo "⚠ $file has conflicts" fi
rm .base.tmp .target.tmp .feature.tmp done}
# Usagetest_branch_merge "feature-x" "main"Configuration and Customization:
Section titled “Configuration and Customization:”Default Merge Behavior:
Section titled “Default Merge Behavior:”# Configure default conflict stylegit config merge.conflictStyle diff3git config merge.conflictStyle merge # Standard style
# Configure merge-file to use diff3 style# Handled via command-line --diff3 optionCustom Merge Scripts:
Section titled “Custom Merge Scripts:”#!/bin/bash# Enhanced merge with backup and logging
enhanced_merge() { local current="$1" local base="$2" local other="$3" local output="${4:-${current}}"
echo "Merging $current with $base and $other"
# Backup if output would overwrite if [ "$output" = "$current" ]; then cp "$current" "${current}.backup.$(date +%s)" fi
# Perform merge with logging if git merge-file -p "$current" "$base" "$other" > "$output" 2>merge.log; then echo "✓ Merge successful" [ -f merge.log ] && rm merge.log else echo "⚠ Merge completed with conflicts" echo "Resolve conflicts in $output" echo "See merge.log for details"
# Create markers for manual resolution echo "Merge details:" >> merge.log echo "Current: $current" >> merge.log echo "Base: $base" >> merge.log echo "Other: $other" >> merge.log fi}
# Usageenhanced_merge file.txt base.txt their.txt merged.txtIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”Automated Code Review Merging:
Section titled “Automated Code Review Merging:”# Merge review changes with automatic conflict resolutionmerge_review_changes() { local original_file="$1" local review_comments="$2"
cp "$original_file" "${original_file}.base"
# Apply review changes (this would be automated based on review system) # For demo, assume review_comments contains change instructions
# Use merge-file to combine automatic application with review changes git merge-file "$original_file" "${original_file}.base" "$review_comments"
if [ $? -eq 0 ]; then echo "Review changes applied successfully" else echo "Manual review of $original_file needed" fi
rm "${original_file}.base"}Version Control System Migration:
Section titled “Version Control System Migration:”# Migrate files between repositories with conflict resolutionmigrate_with_merge() { local old_repo_file="$1" local new_repo_file="$2"
# Find common ancestor (might be git log analysis) # This is simplified - real migration would need history analysis
git merge-file "$old_repo_file" /dev/null "$new_repo_file"
if [ $? -eq 0 ]; then echo "Files migrated successfully" git add "$old_repo_file" else echo "Manual conflict resolution needed in $old_repo_file" fi}Troubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Malformed Input Files:
Section titled “Malformed Input Files:”# Check if files exist and are readablels -la current.txt base.txt other.txt
# Ensure files are not empty[ -s current.txt ] && echo "current.txt is OK" || echo "current.txt is empty"
# Check for binary files (merge-file works on text)file current.txt base.txt other.txtEncoding Issues:
Section titled “Encoding Issues:”# Ensure consistent encodingfile current.txt base.txt other.txt
# Convert encoding if needediconv -f latin1 -t utf8 current.txt > current_utf8.txtgit merge-file current_utf8.txt base.txt other.txtmv current_utf8.txt current.txtDirectory Issues:
Section titled “Directory Issues:”# Ensure proper permissionschmod 644 current.txt base.txt other.txtls -la current.txt base.txt other.txt
# Check filesystem spacedf -h .Performance with Large Files:
Section titled “Performance with Large Files:”# For large files, check memoryulimit -vfree -h
# Split large files if neededsplit -l 10000 large-file.txt large-file.part.git merge-file large-file.part.aa base.txt other.txtcat large-file.part.a* > merged-large-file.txtReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Resolving Forked Repository Conflicts:
Section titled “Resolving Forked Repository Conflicts:”# When a fork has diverged significantlyresolve_fork_conflicts() { local upstream_repo="$1" local local_file="$2"
# Get upstream version git show "$upstream_repo/$(basename "$local_file")" > upstream.tmp
# Get common ancestor commit base_commit=$(git merge-base HEAD "$upstream_repo" 2>/dev/null || git log --oneline -1 | awk '{print $1}') git show "$base_commit:$local_file" > base.tmp
# Merge changes if git merge-file "$local_file" base.tmp upstream.tmp; then echo "✓ Successfully merged $local_file changes from upstream" git add "$local_file" else echo "Conflicts in $local_file need manual resolution" fi
rm upstream.tmp base.tmp}
# Usage for repository syncresolve_fork_conflicts "origin/main" "important-file.txt"Collaborative Feature Development:
Section titled “Collaborative Feature Development:”# Merge feature branches with conflict resolutionmerge_feature_branches() { local branch1="$1" local branch2="$2" local target_file="$3"
# Create temporary working copies git show "$branch1:$target_file" > branch1.tmp git show "$branch2:$target_file" > branch2.tmp
# Find common ancestor base_commit=$(git merge-base "$branch1" "$branch2") git show "$base_commit:$target_file" > base.tmp
# Attempt automatic merge if git merge-file --ours branch1.tmp base.tmp branch2.tmp; then mv branch1.tmp "$target_file" echo "✓ Features merged automatically" else echo "Manual merge needed for $target_file" # Leave temporary files for inspection echo "Compare: base.tmp, branch1.tmp, branch2.tmp" echo "Edit: $target_file" return 1 fi
rm base.tmp branch1.tmp branch2.tmp}
# Usagemerge_feature_branches "feature-a" "feature-b" "shared-code.py"Configuration File Versioning:
Section titled “Configuration File Versioning:”# Manage configuration files across environmentsmerge_configurations() { local dev_config="$1" local prod_config="$2" local staging_config="$3"
# Create base from initial config git show HEAD~10:"$(basename "$dev_config")" > base-config.tmp
# Merge dev changes into staging git merge-file "$staging_config" base-config.tmp "$dev_config"
if [ $? -eq 0 ]; then echo "✓ Dev changes merged into staging" git add "$staging_config" else echo "Review $staging_config for environment-specific settings" echo "Dev changes may need adaptation for staging" fi
# Also merge into production with cautions git merge-file --stdout "$prod_config" base-config.tmp "$dev_config" > prod-preview.tmp echo "Preview merged production config in prod-preview.tmp"
rm base-config.tmp prod-preview.tmp}
# Usage for config deploymentmerge_configurations "config.dev.yml" "config.prod.yml" "config.staging.yml"What’s the difference between git merge-file and regular file concatenation?
Section titled “What’s the difference between git merge-file and regular file concatenation?”git merge-file performs intelligent three-way merging, identifying conflicts and preserving separate changes, while concatenation simply appends files.
How do I handle binary files with merge-file?
Section titled “How do I handle binary files with merge-file?”merge-file is designed for text files. Use git merge for files tracked in Git, or alternative tools for binary file merge operations.
Can merge-file be used outside of Git repositories?
Section titled “Can merge-file be used outside of Git repositories?”Yes, git merge-file is a standalone utility. It doesn’t require a Git repository and can merge any three text files.
What’s the relationship between merge-file and git merge?
Section titled “What’s the relationship between merge-file and git merge?”git merge calls git merge-file (via git merge-index) on conflicted files. merge-file is the low-level utility, git merge provides high-level workflow.
How do I automate conflict resolution with merge-file?
Section titled “How do I automate conflict resolution with merge-file?”Use —ours or —theirs for automatic resolution strategies, or interpret conflict markers in scripts to apply intelligent resolution logic.
Can merge-file merge multiple files at once?
Section titled “Can merge-file merge multiple files at once?”No, processes one file at a time. Use shell loops or build scripts to merge multiple file sets.
What’s the marker-size option for?
Section titled “What’s the marker-size option for?”Controls length of conflict markers (<<<<<<< ======= >>>>>>>). Useful for files with similar content where short markers might appear naturally.
How do I handle different line endings with merge-file?
Section titled “How do I handle different line endings with merge-file?”Generally handles line ending differences automatically. Use dos2unix/unix2dos if needed before merging for complex mixed line ending scenarios.
Can merge-file work with Unicode files?
Section titled “Can merge-file work with Unicode files?”Yes, supports UTF-8 and other Unicode encodings. Ensure consistent encoding between all three input files.
What’s the —object-id option for?
Section titled “What’s the —object-id option for?”Adds Git object IDs to conflict markers for integration with Git’s conflict resolution, showing where each version came from in the repository.
How do I use merge-file in pre-commit hooks?
Section titled “How do I use merge-file in pre-commit hooks?”Test merge conflicts before committing by merging with branch bases, or validate file integrity changes.
Can merge-file detect renames or moves?
Section titled “Can merge-file detect renames or moves?”No, operates on file content only. Use git merge for complete file lifecycle including renames and permission changes.
What’s the performance impact of large file merging?
Section titled “What’s the performance impact of large file merging?”Linear with file size. Memory usage scales with file size and number of conflicts. Use system limits for very large files.
Applications of the git merge-file command
Section titled “Applications of the git merge-file command”- Merge Conflict Resolution: Manually resolve Git merge conflicts with three-way diff visualization
- Automated File Merging: Script-based merging of configuration files across environments
- Version Control Migration: Migrate files between repositories with conflict detection
- Collaborative Document Editing: Merge changes from multiple contributors working on documents
- Configuration Management: Merge configuration changes across development, staging, and production
- Patch Testing and Validation: Test patch applicability before application with conflict detection