Git Basics: Trace One File Back Through a Rename
A file may have a longer history than its current name suggests. Create a configuration file, rename it without changing its contents, and then edit it to compare two history queries.
Prepare a scratch directory
Tested on Linux with Git 2.52.0 and GNU Bash 5.2.37. You need Bash, Git, a text editor, and standard mktemp, rm, rmdir, cat, head, wc, and sed utilities. Run from an ordinary shell without repository-selection variables such as GIT_DIR, GIT_WORK_TREE, or GIT_INDEX_FILE set. The script isolates global and system Git configuration and uses fictional identities only in its temporary repository.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-log-follow.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
export GIT_CONFIG_NOSYSTEM=1
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_AUTHOR_NAME='Example Author'
export GIT_AUTHOR_EMAIL='author@example.invalid'
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
export GIT_AUTHOR_DATE='2026-10-29T00:00:00+00:00'
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
git init -q --object-format=sha1 -b main "$fixture_dir/repo"
cd -- "$fixture_dir/repo"
git config commit.gpgsign false
git config core.hooksPath /dev/null
printf 'timeout=10\nmode=basic\n' > old.conf
git add old.conf
git commit -qm 'Create original configuration'
git mv old.conf service.conf
git commit -qm 'Rename configuration'
printf 'timeout=20\nmode=basic\n' > service.conf
git commit -qam 'Raise timeout'
printf 'Current path only:\n'
git log --format=%s -- service.conf
printf 'Following the rename:\n'
git log --follow --format=%s -- service.conf
test "$(git log --follow --format=%s -- service.conf | wc -l)" -eq 3Run it:
bash demonstrate-log-follow.shObserved output:
Current path only:
Raise timeout
Rename configuration
Following the rename:
Raise timeout
Rename configuration
Create original configurationRead the result
The current-path query shows the timeout edit and the rename that introduced service.conf. Adding --follow also reaches the commit that originally created old.conf. This fixture makes the rename unambiguous by preserving the entire file in the rename commit.
Apply it carefully
Git detects renames from content similarity rather than storing a permanent file identity. --follow accepts a single file and can behave poorly on nonlinear history. A heavily edited rename may not be recognized; inspect neighboring commits and earlier paths if the result looks incomplete. This example follows reachable history from the current branch, not every remote branch.
The official Git reference documents these options. The script creates and removes only its own temporary fixture; it does not contact a remote or change your existing repository.
Clean up
Remove the saved script, return to the starting directory, and remove the empty practice directory:
rm -- demonstrate-log-follow.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect its remaining files rather than deleting unknown content.
Acknowledgements
This post was created with assistance from AI.