Git tricks
Reset all commit times to the original commit date
The command originally published, git filter-repo
, will still work but is no
longer recommended. Git recommends using the git-filter-repo
tool, which can achieve the same
results with the following command:
$ git filter-repo --commit-callback 'commit.committer_date = commit.author_date' --force
Credit goes to Simon Willison for this solution.
$ git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'
When rebasing commits, the date information is updated to the current date and time. There are two times stored in a commit however; commit date and author date.
The author date is the original date of the commit, so running a filter-branch
across the repository will reset the date of every commit to the original author
commit.
Reset all commit author information for a specific name/email
$ git filter-branch --env-filter '
OLD_EMAIL="old@email.com"
NEW_NAME="New Name"
NEW_EMAIL="new@email.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$NEW_NAME"
export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$NEW_NAME"
export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
If searching by name instead of email, swap $GIT_COMMITTER_EMAIL
and
$GIT_AUTHOR_EMAIL
with $GIT_COMMITTER_NAME
and $GIT_AUTHOR_NAME
name
respectively.
Format the output of logs
Aliases for Git can be set up to display customised outputs from git log
,
typically using the --pretty=format:'...'
flag.
See my own Git configuration file for examples of log formatting.
The Pro Git book lists:
- the formats available for
git log
and the--pretty
flag; and - the available colours for use with
git log
formatting
Split one existing commit into many commits
Run an interactive rebase at the specific commit:
$ git rebase -i <id>^
Mark the commit to split as edit
in the interactive rebase's todo
:
edit <id>
Once editing the commit, reset the HEAD to unstage all files from the commit being edited:
$ git reset HEAD~
With all files unstaged, select the files to commit with git add
, commit them
and repeat this process until the commit is split as desired. Then let the
rebase continue:
$ git rebase --continue
Export a stash to a file
$ git stash show -p > stash.patch
To apply the patch:
$ git apply stash.patch
Remove untracked files in Git
First, double check which untracked files Git will remove using -n
, the dry
run flag:
$ git clean -n -d
Once happy with the output of the dry run, delete the untracked files via:
$ git clean -d -f
The -d
flag tells Git to recursively delete files in directories. -f
is
required to force the removal of files if the Git configuration variable
clean.requireForce
is set to true
.
You can use the -i
flag to interactively delete files and directories. This is
useful if only certain untracked files should be removed.
Find and replace text in commit messages
$ git-filter-repo --replace-message <expressions_file> --refs <refs+>
An example of an expression that will change all instances of find
to
replace
is:
find===>replace