Complete Guide to Listing File Changes Between Two Commits in Git

Oct 26, 2025 · Programming · 21 views · 7.8

Keywords: Git | file changes | commit comparison | version control | command line tools

Abstract: This comprehensive technical article explores methods for accurately identifying files changed between specific commits in Git version control system. Focusing on the core git diff --name-only command with supplementary approaches using git diff-tree and git log, the guide provides detailed analysis, practical examples, and real-world application scenarios for efficient code change management in development workflows.

Core Command for Git File Change Detection

In software development, accurately identifying file changes between commits is crucial for code review, version management, and continuous integration. Git provides a robust toolkit for such requirements, with git diff --name-only standing as the most direct and efficient solution.

Detailed Command Analysis

The git diff --name-only SHA1 SHA2 command primarily generates a list of files modified between two specified commits. SHA1 and SHA2 can be complete 40-character commit hashes or any unique prefix that identifies the commits. Git's design allows using the shortest unique prefix to reference commits, providing significant convenience in practical operations.

The command output format consists of one file path per line, using relative path notation:

src/utils/helper.js
config/database.yml
tests/integration/user_test.rb

Parameter Flexibility

Git commit references offer extensive flexibility beyond hash values. Developers can utilize various reference forms:

# Using relative references
git diff --name-only HEAD~10 HEAD~5

# Using branch names
git diff --name-only main feature-branch

# Using tags
git diff --name-only v1.0 v2.0

Relative references are particularly useful for quickly examining recent change history. HEAD~10 denotes the 10th commit before the current commit, providing intuitive representation when dealing with linear history.

Output Characteristics

The elegance of the --name-only option lies in its output containing only file paths without displaying specific change content. This design ensures faster command execution and output that's easier to parse and process. When needing to pass file lists to other tools or scripts, this concise output format becomes particularly valuable.

Notably, the command outputs file paths relative to the Git repository root directory, ensuring path consistency regardless of the current working directory location within the repository.

Supplementary Command Methods

Beyond git diff --name-only, Git offers additional file change detection commands:

git diff-tree Command

git diff-tree --no-commit-id --name-only -r COMMIT_HASH specializes in analyzing file changes within a single commit. This command proves particularly useful in continuous integration environments for precisely identifying changes introduced by specific commits.

# Analyze file changes in specific commit
git diff-tree --no-commit-id --name-only -r abc123def

git log Command

When needing to view file changes alongside commit information, git log --name-only --pretty=oneline COMMIT1..COMMIT2 provides richer contextual information.

# View file change history across commit range
git log --name-only --pretty=oneline abc123..def456

Practical Application Scenarios

Accurate file change identification is essential in CI/CD pipelines. For example, in GitLab CI/CD environments, changed file lists can be obtained through:

# Compare target branch in merge request
CHANGED_FILES=$(git diff --name-only $CI_MERGE_REQUEST_TARGET_BRANCH_SHA $CI_COMMIT_SHA)

# Process each changed file
echo "$CHANGED_FILES" | while read file; do
    if [[ "$file" == *.js ]]; then
        eslint "$file"
    fi
done

Advanced Usage and Best Practices

For more complex change analysis requirements, combine with other Git options:

# Include change status (modified, added, deleted)
git diff --name-status SHA1 SHA2

# Ignore whitespace changes
git diff --name-only --ignore-all-space SHA1 SHA2

# Show only specific file types
git diff --name-only SHA1 SHA2 -- '*.java' '*.xml'

Performance Optimization Considerations

Command execution efficiency becomes important when handling large repositories. The following optimization strategies are worth considering:

First, use the most recent commit references possible to reduce the number of commits Git needs to traverse. Second, when only file lists are needed without concern for specific change content, the --name-only option significantly improves performance compared to full diff output.

Error Handling and Edge Cases

Various edge cases may be encountered in practical usage:

# Handle non-existent commit references
if git rev-parse --verify SHA1 >/dev/null 2>&1; then
    git diff --name-only SHA1 SHA2
else
    echo "Invalid commit reference"
fi

# Handle empty result cases
changed_files=$(git diff --name-only SHA1 SHA2)
if [ -z "$changed_files" ]; then
    echo "No files changed between the two commits"
fi

Integration into Development Workflow

Integrating file change detection into daily development workflows can significantly enhance efficiency. For example, checking changed files in pre-commit hooks:

#!/bin/bash
# .git/hooks/pre-commit

# Get changed files in staging area
changed_files=$(git diff --cached --name-only)

for file in $changed_files; do
    case "$file" in
        *.py)
            python -m py_compile "$file" || exit 1
            ;;
        *.js)
            npx eslint "$file" || exit 1
            ;;
    esac
done

By systematically mastering these Git file change detection techniques, developers can manage code changes more efficiently, enhance team collaboration effectiveness, and build more reliable software development processes.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.