Basis


Flags

--commit-filter
 Specify a custom filter that processes each commit individually.

--env-filter
Specify a custom filter that to modify environment variables for each commit (e.g. GIT_AUTHOR_NAME or GIT_AUTHOR_EMAIL.).

--tag-name-filter cat
Preserve existing tag name.

-- --all
Apply the filter to all branches and tags in the repository.

--force
Require when the repo has already been pushed to a remote server.


Apply Filter on all Branches

# Checkout all branches locally
git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

# Apply filter
git filter-branch ...

# Push all branches to origin
git push --all origin --force

Snippets


Sets Committer info to Author info

This is useful because Committer and Author info can be different when modifying history (e.g. Committer date).

git filter-branch --force --tag-name-filter cat --commit-filter '
	GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME;
	GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
	GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE;
	git commit-tree "$@";' -- --all

Change Commits Author

git filter-branch --force --tag-name-filter cat --commit-filter '
	if [ "$GIT_AUTHOR_NAME" = "myOldName" ];
	then
		GIT_AUTHOR_NAME="myNewName";
		GIT_AUTHOR_EMAIL="myEmail@email.com";
		GIT_COMMITTER_NAME="myNewName";
		GIT_COMMITTER_EMAIL="myEmail@email.com";
		GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE;
		git commit-tree "$@";
	else
		git commit-tree "$@";
	fi' -- --all

Sign old Commits of a specific Author

git filter-branch --force --tag-name-filter cat --commit-filter '
	if [ "$GIT_AUTHOR_NAME" = "myName" ];
	then
		git commit-tree -S "$@";
	else
		git commit-tree "$@";
	fi' -- --all

Remove Commits older than 90 days

git filter-branch --force --commit-filter '
	if [ "$(date -d "$(git show -s --format=%ci $GIT_COMMIT)" +%s)" -gt "$(date -d"90 days ago" +%s)" ];
	then
	  git commit-tree "$@";
	else
	  skip_commit "$@";
	fi' -- --all