Git's diff and apply commands are essential tools for code review, patching, and migrating changes between branches or repositories. While git diff generates a patch file showing differences between commits or working trees, git apply applies that patch to another codebase. This guide walks through practical usage, from basic file-level diffs to handling complex scenarios, with a focus on real-world developer workflows.

Understanding git diff and Patch Files
git diff produces a unified diff format that describes changes line by line. A patch file (.patch or .diff) is the output of git diff and can be applied elsewhere. Unlike git format-patch, which generates one file per commit with full commit metadata, git diff creates a single patch without commit history, making it ideal for ad-hoc changes.
Basic Usage
Generate a patch for a specific file:
git diff Test.java > test.patch
Generate a patch for all modified files:
git diff > all-changes.patch
Generate a patch between two commits:
git diff <old-commit> <new-commit> > changes.patch
Applying Patches with git apply
Once you have a patch file, apply it to the target repository:
git apply test.patch
git apply modifies the working tree but does not create a commit. It's safe to use on a clean working directory; if the patch fails, it leaves the tree unchanged.
Options
--check: Test if the patch applies cleanly without actually applying.--reject: Apply what can be applied, leaving rejected hunks in.rejfiles.--whitespace=fix: Fix whitespace errors automatically.
Worked Example: Code Review and Patching
Consider a scenario where a developer, Alice, makes changes to a feature branch and wants Bob to review and apply them.
- Alice modifies two files:
src/app.jsandsrc/utils.js. - She generates a patch:
git diff > feature.patch - Bob receives
feature.patchand reviews it. He can inspect the diff without applying:git apply --check feature.patch - If clean, Bob applies:
git apply feature.patch
Handling Conflicts
If the patch fails, Bob can use --reject to apply non-conflicting parts:
git apply --reject feature.patch
This creates .rej files for rejected hunks, which Bob can manually resolve.
Comparison: git diff vs git format-patch
| Feature | git diff |
git format-patch |
|---|---|---|
| Contains commit metadata | No | Yes (author, date, message) |
| File granularity | Single file or all changes | One file per commit |
| Use case | Ad-hoc patches, code review | Email-based workflows, preserving history |
| Apply command | git apply |
git am |
Common Pitfalls
- Applying patches on dirty working tree: Always apply patches on a clean state to avoid confusion.
- Binary files:
git diffworks for text files; binary files require--binaryflag. - Whitespace issues: Patches may fail due to trailing whitespace or indentation differences. Use
--whitespace=fix. - Cross-repository patches: Paths must match; otherwise, use
-p<n>to strip leading directory components. - Large patches: For big changes, consider splitting into smaller logical patches.
Performance Considerations
git diff and git apply are efficient for most use cases. However, for very large repositories or deep history, consider:
- Limiting diff scope with path arguments.
- Using
git diff --cachedto compare staging area vs last commit. - For massive patches, use
git format-patchandgit amwhich handle binary files and encoding better.
FAQ
What is the difference between .patch and .diff files?
Technically, they are the same format. .patch is conventionally used for output from git format-patch, while .diff is used for git diff. Both are plain text unified diffs.
Can I apply a patch from another repository?
Yes, as long as the file paths match. If not, use git apply -p1 (strip one directory level) or adjust with -p<n>.
How do I revert an applied patch?
Use git apply -R <patch-file> to reverse the patch. Alternatively, git checkout the affected files.
Does git apply create a commit?
No, it only modifies the working tree. To commit, run git commit afterward.
What if the patch fails partially?
Use --reject to apply non-conflicting parts. Manually resolve rejected hunks in .rej files.
Try it in our text diff tool to visually compare changes before applying patches.