1. Fixing Case-Sensitivity Issues with git mv --force
Sometimes developers rename a file, changing only its case (e.g., readme.md
to README.md
) forget and commit, even push. On case-insensitive file systems like Windows or macOS, Git may ignore the change, leading to inconsistencies. For assets deployed to be served from webservers, this can also be an issue.
On case-insensitive file systems like Windows or macOS renaming the file, adding and committing is not working. Many use rename to a temp name, add and commit and them rename to the correct name, add and commit. This solves the issue, but it is cumbersome and pollutes the git history.
Another alternative is to delete and recreate the file, but this even more cumbersome, loses history and is error-prone compared to the mv --force
command.
The correct solution is to avoid the file system change altogether and use the git mv --force
command to explicitly tell Git to recognize the rename:
# Move the file in git and commit
> git mv --force readme.md README.md
renamed 'readme.md' -> 'README.md'
> git commit -m "Rename file to fix case sensitivity issue"
[main abc1234] Rename file to fix case sensitivity issue
This is short, affects both git and filesystem and prevents conflicts when pushing or merging changes across case-sensitive and case-insensitive systems.
2. Using git rm --cached
to Delete Files Accidentally Missing from .gitignore
Sometimes files that should have been ignored (e.g., logs, environment files) are accidentally committed and pushed to the repository. This often happens when .gitignore
is updated after these files have already been tracked. To fix this, we need to remove the files from the repository while keeping them locally and prevent them from being committed again by adding an appropriate pattern to .gitignore
.
# Remove the file from tracking but keep it locally
> git rm --cached filename
rm 'filename'
# Add the file to .gitignore to prevent future commits
> echo 'filename' >> .gitignore
# Stage and commit the changes
> git add .gitignore
> git commit -m "Remove file and add to gitignore"
[main abc1234] Remove file and add to gitignore
1 file changed, 1 insertion(+)
This keeps the file locally while removing it from Git history and prevents future commits of the file by adding it to .gitignore.
Another alternative is to delete the file entirely, but this approach is risky if you need the file locally.
3. Tracking File Changes Across Renames with git log --follow
Sometimes files are renamed, and their commit history appears lost, making it difficult to track changes over time. This is problematic when debugging issues or auditing past modifications.
# Track history even across renames
> git log --follow -- filename
commit abc1234
Author: User <user@example.com>
Date: Mon Jan 1 12:00:00 2024
Initial commit
commit def5678
Author: User <user@example.com>
Date: Tue Jan 2 12:00:00 2024
Updated filename
This provides a complete history of changes, including before and after renaming.
Its also useful for debugging and auditing changes.
4. Cleaning Up Merged Branches
Old branches often clutter repositories after merging, making it hard to manage active branches.
# List and delete merged branches
> git branch --merged | grep -v '\*' | xargs -n 1 git branch -d
Deleted branch feature/login (was abc1234).
Deleted branch bugfix/logout (was def5678).
5. Working on Multiple Worktrees with git worktree add
When working on multiple branches simultaneously, switching branches or stashing changes can be disruptive.
# Create a new worktree for a branch
> git worktree add ../temp-branch new-branch
Preparing worktree (checkout new-branch)
HEAD is now at abc1234 Initial commit
6. Amending Commits Without Changing Timestamps
You may need to fix a typo or add a file to the last commit without changing its timestamp.
# Amend the last commit without changing the timestamp
> git commit --amend --no-edit --date="$(git show --format=%ci HEAD | head -1)"
[main abc1234] Commit amended without changing timestamp
Another variation would allow you to see information on each change:
> git log --follow --pretty=format:"%h - %an, %ar : %s" -- src/app.ts
a1b2c3d - Jane Doe, 2 weeks ago : Fixed bug in user authentication
d4e5f6g - John Smith, 1 month ago : Refactored application structure
...