How to Get a List of New, Modified, or Deleted Files/Directories in Git: Comparing Local and Remote Repositories

Git is the cornerstone of modern version control, enabling collaboration and tracking changes across distributed teams. A common challenge developers face is understanding how their local repository differs from the remote (e.g., GitHub, GitLab, or Bitbucket). Whether you’re preparing to push changes, reviewing updates from teammates, or troubleshooting discrepancies, knowing how to identify new, modified, or deleted files/directories between local and remote repositories is critical.

This guide will walk you through step-by-step methods to compare your local repository with the remote, using Git commands to list changes clearly. We’ll cover basic comparisons, interpreting status codes, advanced filtering, and troubleshooting common issues. By the end, you’ll confidently identify file-level differences and streamline your workflow.

Table of Contents#

  1. Prerequisites
  2. Understanding Local vs. Remote Repositories
  3. Step 1: Fetch the Latest Remote Changes
  4. Step 2: Compare Local and Remote Branches
  5. Step 3: Interpreting Git Status Codes
  6. Step 4: Advanced Comparisons (Specific Files, Commit Ranges)
  7. Step 5: Handling Detached HEAD or Stashed Changes
  8. Troubleshooting Common Issues
  9. Conclusion
  10. References

Prerequisites#

Before proceeding, ensure you have:

  • Git installed: Verify with git --version (install from git-scm.com if missing).
  • A local Git repository: Clone an existing repo with git clone <remote-url> or initialize one with git init.
  • Access to the remote repository: You must have network access to fetch/push (e.g., GitHub, GitLab credentials).
  • Basic Git knowledge: Familiarity with git add, git commit, git branch, and git remote commands.

Understanding Local vs. Remote Repositories#

  • Local Repository: Resides on your machine, containing your working directory (files you edit), staging area (files marked for commit), and local branches (committed history).
  • Remote Repository: A centralized repo hosted elsewhere (e.g., GitHub). It acts as a shared hub for team collaboration.
  • Remote-Tracking Branches: Local references (e.g., origin/main) that mirror the state of remote branches. These are updated when you run git fetch or git pull.

To compare local and remote, you first need to update your remote-tracking branches (via git fetch) to reflect the latest changes on the remote.

Step 1: Fetch the Latest Remote Changes#

Before comparing, always fetch remote updates to ensure your local remote-tracking branches (e.g., origin/main) are up-to-date. This avoids comparing against stale data.

Commands:#

  1. Check your remotes: Confirm the remote name (usually origin by default):

    git remote -v  

    Output example:

    origin  https://github.com/your-username/your-repo.git (fetch)  
    origin  https://github.com/your-username/your-repo.git (push)  
    
  2. Fetch remote changes: Update remote-tracking branches without merging them into your local branch:

    git fetch origin  
    • origin: The name of your remote (replace with your remote name if different).
    • This command downloads new commits, branches, or tags from the remote but leaves your local working directory unchanged.

Step 2: Compare Local and Remote Branches#

Once you’ve fetched remote changes, use git diff to compare your local branch with its remote counterpart. The goal is to list files/directories that differ, not just view content changes.

Key Command: git diff --name-status <local-branch> <remote-branch>#

  • --name-status: Shows filenames and their status (added, modified, deleted) instead of full content diffs.
  • <local-branch>: Your local branch (e.g., main, feature/login).
  • <remote-branch>: The remote-tracking branch (e.g., origin/main).

Example Workflow:#

Suppose you’re on the main branch and want to compare it with origin/main (the remote main branch):

  1. Ensure you’re on the local branch:

    git checkout main  # Switch to main if not already on it  
  2. Compare with the remote branch:

    git diff --name-status main origin/main  

Sample Output:#

A       src/new-file.txt  
M       docs/user-guide.md  
D       tests/old-test.js  

This output lists:

  • A: src/new-file.txt was added locally but not on the remote.
  • M: docs/user-guide.md was modified locally.
  • D: tests/old-test.js was deleted locally.

Alternative: Compare Current Branch Automatically#

If your local branch is tracking a remote branch (the default for cloned repos), simplify the command to:

git diff --name-status @{u}  
  • @{u} (short for @{upstream}) refers to the remote branch your local branch is tracking (e.g., origin/main for main).

Step 3: Interpreting Git Status Codes#

The --name-status flag uses single-letter codes to describe file changes. Here’s what each code means:

CodeDescription
AAdded: File exists in local but not in remote (new file).
CCopied: File was copied from another file (requires --find-copies-harder).
DDeleted: File exists in remote but not in local (deleted locally).
MModified: File content differs between local and remote.
RRenamed: File was renamed (requires --find-renames or -M flag).
TType Changed: File type changed (e.g., symlink to regular file).
UUnmerged: File has merge conflicts (needs resolution).
XUnknown: Git cannot determine the change type.

Example: Detecting Renames#

By default, git diff may not detect renames. Use -M (or --find-renames) to identify renamed files:

git diff --name-status -M main origin/main  

Output example:

R100    src/old-name.js      src/new-name.js  # R100 = 100% rename similarity  

Step 4: Advanced Comparisons#

Compare Specific Files/Directories#

To narrow results to a specific file or directory, append the path to the git diff command:

  • Specific file:

    git diff --name-status main origin/main src/app.js  
  • Specific directory:

    git diff --name-status main origin/main tests/  

Compare Commit Ranges#

To list changes between two specific commits (instead of entire branches), use commit hashes:

git diff --name-status <commit-hash-1> <commit-hash-2>  

Example: Compare the last 3 local commits with the remote:

git diff --name-status HEAD~3 origin/main  

List Changes with Commit Details#

To see which commits introduced changes, use git log with --name-status:

git log --name-status origin/main..main  
  • origin/main..main: Shows commits in main that are not in origin/main (local changes not pushed).

Output example:

commit a1b2c3d4 (HEAD -> main)  
Author: Your Name <[email protected]>  
Date:   Wed Oct 11 12:00:00 2023  

    Update user guide  

M       docs/user-guide.md  

commit e5f6g7h8  
Author: Your Name <[email protected]>  
Date:   Tue Oct 10 10:30:00 2023  

    Add new feature  

A       src/new-file.txt  
D       tests/old-test.js  

Step 5: Handling Detached HEAD or Stashed Changes#

Detached HEAD State#

If you’re in a detached HEAD state (not on a branch), compare your current commit directly with the remote:

git diff --name-status <current-commit-hash> origin/main  

Stashed Changes#

To compare stashed changes with the remote:

git diff --name-status stash@{0} origin/main  
  • stash@{0}: The most recent stash (use git stash list to view all stashes).

Troubleshooting Common Issues#

"No Differences Found" When Changes Exist#

  • Cause: You forgot to git fetch the remote, so origin/main is outdated.
  • Fix: Run git fetch origin and retry the comparison.

"fatal: ambiguous argument 'origin/main': unknown revision or path"#

  • Cause: The remote branch name may differ (e.g., origin/master instead of origin/main).
  • Fix: Check remote branches with git branch -r, then use the correct name:
    git branch -r  # Lists remote-tracking branches (e.g., origin/main, origin/feature-x)  
    git diff --name-status main origin/master  # If remote uses "master"  

"Permission Denied" When Fetching#

  • Cause: Invalid credentials or network issues.
  • Fix: Verify remote URL with git remote -v, check credentials (e.g., SSH keys, PATs), or ensure VPN/proxy settings allow access.

Conclusion#

Comparing local and remote Git repositories is a foundational skill for tracking changes and collaborating effectively. By following these steps:

  1. Fetch remote updates with git fetch origin.
  2. Use git diff --name-status <local-branch> origin/<remote-branch> to list changed files.
  3. Interpret status codes (A, M, D, etc.) to identify new, modified, or deleted files.
  4. Use advanced flags (e.g., -M, --find-renames) or path filters for granular control.

You’ll gain clarity on how your local work differs from the remote, reducing merge conflicts and ensuring smooth collaboration.

References#