Complete guide for converting filter-branch commands to git-filter-repo
This guide is for users familiar with git filter-branch who want to migrate to git-filter-repo. We’ll show you how to convert your existing commands and take advantage of filter-repo’s improved performance and safety.
filter-branch and filter-repo have different approaches:
filter-branch: Checks out each commit and runs shell commands on the working copy
filter-repo: Operates on the fast-export stream with predefined filters and Python callbacks
filter-repo defaults to rewriting all branches while filter-branch requires -- --all to do so. Use --refs <rev-list-args> to limit the scope in filter-repo.
This is a BAD example for both tools! It doesn’t remove the author’s changes, just their commits. The changes get attributed to subsequent authors. Use git rebase instead for most use cases. Learn more about the differences.
filter-branch
filter-repo
git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then skip_commit "$@"; else git commit-tree "$@"; fi' HEAD
git filter-branch --env-filter ' if test "$GIT_AUTHOR_EMAIL" = "root@localhost" then[email protected] fi if test "$GIT_COMMITTER_EMAIL" = "root@localhost" then[email protected] fi ' -- --all
# Add to .mailmap:# <[email protected]> <root@localhost>git filter-repo --use-mailmap
Apply a code formatter to all matching files in history:
filter-branch
filter-repo (callback)
filter-repo (lint-history)
# Runs on every commit, even those without C filesgit filter-branch --tree-filter ' git ls-files -z "*.c" \ | xargs -0 -n 1 clang-format -style=file -i '
git filter-repo --file-info-callback ' if not filename.endswith(b".c"): return (filename, mode, blob_id) contents = value.get_contents_by_identifier(blob_id) tmpfile = os.path.basename(filename) with open(tmpfile, "wb") as f: f.write(contents) subprocess.check_call(["clang-format", "-style=file", "-i", filename]) with open(filename, "rb") as f: contents = f.read() new_blob_id = value.insert_file_with_contents(contents) return (filename, mode, new_blob_id) '
# Using the lint-history contrib scriptlint-history --relevant 'return filename.endswith(b".c")' \ clang-format -style=file -i
The lint-history script simplifies code formatting operations while maintaining filter-repo’s automatic handling of commit message rewrites and empty commit pruning.