How do I copy a version of a single file from one Git branch to another?
I’ve got two branches that are fully merged together. However, after the merge is done, I realize that one file has been messed up by the merge (someone else did an auto-format), and it would be easier to change to the new version in the other branch, then reinsert my one line change after bringing it over into my branch.
What’s the easiest way in Git to copy a specific file from one branch to another?
To copy a single file from one Git branch to another, the most modern and recommended approach is using git restore --source source-branch path/to/file, while the traditional method involves git checkout source-branch -- path/to/file. Both commands will copy the file from the specified branch to your current branch, preserving the exact content from the source branch.
Contents
- Using Git Restore (Modern Approach)
- Using Git Checkout (Traditional Approach)
- Alternative Methods
- Step-by-Step Workflow for Your Scenario
- Comparing the Approaches
- Best Practices and Tips
Using Git Restore (Modern Approach)
The git restore command was introduced in Git 2.23 as a more focused alternative to git checkout for file restoration operations.
Basic Syntax
git restore --source source-branch path/to/file
Advanced Options
- Shorter syntax:
git restore -s source-branch path/to/file - Restore to both staging area and working directory:
git restore --staged --worktree --source source-branch path/to/file - Shorter for staged and worktree:
git restore -s source-branch -SW path/to/file
Example
# Copy config.json from develop branch to current branch
git restore --source develop config.json
# Copy multiple files from feature branch
git restore --source feature-branch src/app.js src/styles.css
The git restore command is specifically designed for restoring files from the index or from a commit, making it more semantically clear than the overloaded git checkout command source.
Using Git Checkout (Traditional Approach)
The git checkout command has been used for this purpose for many years and remains widely supported across all Git versions.
Basic Syntax
git checkout source-branch -- path/to/file
Key Points
- The
--separator is important to prevent Git from interpreting the path as a branch name - Works with branch names, commit hashes, or tag references
- Can copy multiple files by listing them after the
--
Example
# Copy README.md from main branch to current branch
git checkout main -- README.md
# Copy entire src directory from feature branch
git checkout feature-branch -- src/
# Copy multiple specific files
git checkout release-branch -- package.json tsconfig.json
This method is well-documented and works consistently across different Git versions, though it can be confusing because git checkout serves multiple purposes source.
Alternative Methods
Using Git Show
You can also use git show to output file content and redirect it to your current file:
git show source-branch:path/to/file > path/to/file
Using Git Cherry-pick for Specific Changes
If you need to apply specific commits rather than entire file versions:
# Find the commit that modified the file
git log --follow --oneline source-branch -- path/to/file
# Cherry-pick that specific commit
git cherry-pick <commit-hash>
Using Git Switch with Restore
For a more modern workflow, you can combine git switch and git restore:
git switch source-branch git restore path/to/file git switch back-to-your-branch git restore path/to/file
Step-by-Step Workflow for Your Scenario
Based on your specific situation where you have two merged branches and need to restore a clean file version:
Step 1: Identify the Clean Version
First, verify which branch has the clean version of your file:
# Compare the file between branches without switching
git diff source-branch..target-branch path/to/file
# Or check the specific version in each branch
git show source-branch:path/to/file
git show target-branch:path/to/file
Step 2: Copy the Clean File to Your Current Branch
Use either git restore or git checkout:
# Using modern approach
git restore --source clean-branch path/to/file
# Or traditional approach
git checkout clean-branch -- path/to/file
Step 3: Apply Your Specific Change
Now make your single line change to the restored file:
# Edit the file with your preferred editor
vim path/to/file
# Or make the change programmatically
sed -i 's/old-text/new-text/' path/to/file
Step 4: Commit the Changes
Finally, commit your restored file with your change:
git add path/to/file
git commit -m "Restore clean version and apply custom fix"
git push origin your-branch
Comparing the Approaches
| Feature | git restore |
git checkout |
|---|---|---|
| Availability | Git 2.23+ | All versions |
| Semantic clarity | Excellent (restores files) | Poor (overloaded command) |
| Syntax | git restore --source branch file |
git checkout branch -- file |
| Safety | More focused, less error-prone | Can accidentally switch branches |
| Multiple files | Supported | Supported |
| Staging area | Can control with --staged |
Limited control |
According to the Git community,
git restorewas introduced specifically to address the confusion caused bygit checkoutserving too many purposes. As one developer put it: “checkout was very hard to understand for me, much harder than rebase and merge… as soon as i heard about switch and restore it made more sense” source.
Best Practices and Tips
When to Use Each Method
- Use
git restoreif you’re using Git 2.23+ and want the most semantically clear command - Use
git checkoutif you need compatibility with older Git versions or if you’re working in a team that hasn’t adopted the modern syntax
Safety Considerations
- Always check what you’re about to restore first with
git diff - Consider stashing your current changes before restoring if you’re unsure:bash
git stash git restore --source source-branch path/to/file git stash pop - Use
--dry-runequivalent by checking the file first
Performance Tips
- For large repositories, both methods are generally fast for single files
- If copying many files, consider using wildcards or directory paths
- The commands work the same way whether you’re copying from a local branch or remote branch
Common Pitfalls to Avoid
- Forgetting the
--separator withgit checkoutcan cause branch switching instead of file copying - Not realizing that
git restorewill overwrite your current changes without warning - Using relative paths that might not work from different directories
For your specific scenario of dealing with merge conflicts and auto-formatting issues, using git restore from the clean branch followed by your manual change is likely the most straightforward approach. This avoids the complexity of merge conflicts while giving you precise control over the final result.