GIT-FILTER-BRANCH(1) Git Manual GIT-FILTER-BRANCH(1) (NAME) git-filter-branch - (SYNOPSIS) git filter-branch [--setup ] [--subdirectory-filter ] [--env-filter ] [--tree-filter ] [--index-filter ] [--parent-filter ] [--msg-filter ] [--commit-filter ] [--tag-name-filter ] [--prune-empty] [--original ] [-d ] [-f | --force] [--state-branch ] [--] [...] (WARNING) git filter-branch ( ). . git filter-repo[1] . git filter-branch << (SAFETY)>> ( << (PERFORMANCE)>>) filter-branch . (DESCRIPTION) . ( perl ) . ( ) . ( a..b b ). . . : .git/info/grafts refs/replace/ . (grafts) . ! . (push) . . ( "RECOVERING FROM UPSTREAM REBASE" git-rebase(1) .) : refs/original/ . / (I/O) -d ( tmpfs) . . (Filters) . eval ( commit ). $GIT_COMMIT . GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_COMMITTER_DATE git-commit- tree(1) . . map " sha1 " " sha1 " " sha1 " commit map . (OPTIONS) --setup . . ( commit). --subdirectory-filter . ( ) . << >> . --env-filter . // / ( git-commit-tree(1) ). --tree-filter . . ( - .gitignore !). --index-filter (index) . tree (checkout) . git rm --cached --ignore-unmatch ... . git-update-index(1) . --parent-filter . . git-commit-tree(1) : "-p parent" "-p parent1 -p parent2 -p parent3 ..." . --msg-filter . . --commit-filter . git commit-tree " [(-p )...]" . . commit . map . skip_commit "$@" ( ! git rebase ). git_commit_non_empty_tree "$@" git commit-tree "$@" . --tag-name-filter . ( ) . . "--tag-name-filter cat" . . . . . "" ( ...) . . ( ) . . --prune-empty . git-filter-branch . --commit-filter git_commit_non_empty_tree commit . --original . refs/original . -d . tree . .git-rewrite/ . -f, --force git filter-branch refs/original/ . --state-branch . . ... git rev-list. . --all -- git filter-branch . << >> . git-rev-list(1) . : . . (EXIT STATUS) 0 . 2 . . (EXAMPLES) ( ) : git filter-branch --tree-filter 'rm filename' HEAD rm filename . rm -f filename . --index-filter git rm . rm filename git rm --cached filename . << >> --ignore-unmatch : git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD HEAD . foodir/ : git filter-branch --subdirectory-filter foodir -- --all . -- filter-branch revision --all . ( ) : git filter-branch --parent-filter 'sed "s/^\$/-p /"' HEAD ( - - graftcommit ). ( ). : git filter-branch --parent-filter \ 'test $GIT_COMMIT = && echo "-p " || cat' HEAD : git replace --graft $commit-id $graft-id git filter-branch $graft-id..HEAD <> : git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then skip_commit "$@"; else git commit-tree "$@"; fi' HEAD skip_commit : skip_commit() { shift; while [ -n "$1" ]; do shift; map "$1"; shift; done; } shift tree -p . ! Darl P1 P2 P1,P2 . (revert) . (interactive) git rebase . --msg-filter . git svn-id git svn : git filter-branch --msg-filter ' sed -e "/^git-svn-id:/d" ' Acked-by ( ) : git filter-branch --msg-filter ' cat && echo "Acked-by: Bugs Bunny " ' HEAD~10..HEAD --env-filter / . user.email : git filter-branch --env-filter ' if test "$GIT_AUTHOR_EMAIL" = "root@localhost" then GIT_AUTHOR_EMAIL=john@example.com fi if test "$GIT_COMMITTER_EMAIL" = "root@localhost" then GIT_COMMITTER_EMAIL=john@example.com fi ' -- --all (revision range) . git rev-list . : D--E--F--G--H / / A--B-----C D E F G H A B C : git filter-branch ... C..H E F G H : git filter-branch ... C..H --not D git filter-branch ... D..H --not C : git filter-branch --index-filter \ 'git ls-files -s | sed "s-\t\"*-&newsubdir/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD (CHECKLIST FOR SHRINKING A REPOSITORY) git-filter-branch --index-filter --subdirectory-filter. . : o (blob) . git log --name-only --follow --all -- filename . o : git-filter-branch --tag-name-filter cat -- --all . . (clone) . o git clone file:///path/to/repo . . git- clone(1) . ( !). ( ). . . o git-filter-branch : git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d. o reflog git reflog expire --expire=now --all . o (garbage collect) git gc --prune=now ( git-gc --prune git repack -ad; git prune ). (PERFORMANCE) git-filter-branch : o git-filter-branch (checkout) . 10^5 10^5 git-filter-branch 10^10 ( ) 5*10^5 (blob) . o git-filter-branch : o ( ) o ( ). o ( --index-filter ) . . . o git-filter-branch . git-filter-branch ( ()map) ( git-filter-branch ). (IPC) git-filter-branch . IPC . o (pipeline) . . o git-filter-branch . git-filter-branch . o : git-filter-branch . : git-filter-branch (()map ()skip_commit ) --setup ( ). git filter-repo[1] git-filter-branch ( ) . git-filter-branch git filter-repo filter-lamely[2] git-filter-branch ( ). filter-lamely git-filter-branch . (SAFETY) git-filter-branch : o << >> ( git-filter-branch ). BSD GNU . . . . ( .) o . find -print0 xargs -0 git-ls-files -z . . . o (non-ascii) . git ls-files | grep -v ^WANTED_DIR/ | xargs git rm . ls-files ( ). core.quotePath ( \t \n " ) ls-files -z grep . o (double quote) . ( .) o . git-filter-branch ! . <<>> . : o (--all ) o o --tag-name-filter ( ) o . (rebase) ( ) . "DISCUSSION" git filter-repo . o (annotated tags) (lightweight tags) : o refs/original/ git-filter-branch . ( refs/original/ .) o git-filter-branch --tags --all . --tag-name-filter ( refs/original/ ). o (encoding) git-filter-branch commit-tree . ( --msg-filter .) o ( UTF-8 ) -- . o . ( (node_modules ) .) o --prune-empty o --prune-empty . o --prune-empty ( ...) o --env-filter (taggers) . o --tag-name-filter git-filter-branch . ( git-filter-branch .) git-filter-branch : o . ( ...) . git-filter-branch ( ). / . . o . . . . GIT git(1) (NOTES) 1. git filter-repo https://github.com/newren/git-filter-repo 2. filter-lamely https://github.com/newren/git-filter- repo/blob/master/contrib/filter-repo-demos/filter-lamely Git 2.55.0 2026-06-29 GIT-FILTER-BRANCH(1)