正在加载,请稍候…

Git Diff and Apply: A Practical Guide for Developers

Learn how to use git diff and apply for code review and patching with real-world scenarios. Includes worked examples, common pitfalls, and FAQ.

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.

Developer reviewing a diff on a large monitor

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 .rej files.
  • --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.

  1. Alice modifies two files: src/app.js and src/utils.js.
  2. She generates a patch:
    git diff > feature.patch
    
  3. Bob receives feature.patch and reviews it. He can inspect the diff without applying:
    git apply --check feature.patch
    
  4. 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 diff works for text files; binary files require --binary flag.
  • 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 --cached to compare staging area vs last commit.
  • For massive patches, use git format-patch and git am which 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.