Skip to content

Instantly share code, notes, and snippets.

@kanzure
Last active May 17, 2022 17:25
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save kanzure/5558267 to your computer and use it in GitHub Desktop.
Save kanzure/5558267 to your computer and use it in GitHub Desktop.
git-filter-branch examples and notes
"""
Creates pretty-looking commit messages for git. This was created to pretty
print the old-commit-id values for filter-branched-rewritten commits in
pyphantomjs from the phantomjs repository.
"""
import os
import sys
commit_id = os.environ["GIT_COMMIT"]
message = sys.stdin.read()
if len(message) > 0:
if message[-2] != "\n" and not "Last changes" in message:
message += "\n"
message += "original-commit-id: " + str(commit_id)
message = message.replace("Last changes", "")
if not "\n\noriginal-commit-id: " in message:
message = message.replace("\noriginal-commit", "\n\noriginal-commit")
print message
git filter-branch --index-filter "git ls-files | grep -v pilot/tag_extractor.py | xargs git rm --cached" --prune-empty
git filter-branch -f --tree-filter "if [[ -e pilot/tag_extractor.py ]]; then mv pilot/tag_extractor.py tag_extractor.py; fi;"
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_NAME" = "--Nathan McCorkle" ];
then
GIT_COMMITTER_NAME="Nathan McCorkle";
GIT_AUTHOR_NAME="Nathan McCorkle";
GIT_COMMITTER_EMAIL="nmz787@gmail.com";
GIT_AUTHOR_EMAIL="nmz787@gmail.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
git filter-branch -f --index-filter "git rm -r -f --cached --ignore-unmatch $(ls -xd trainers/ text/ stats/ gfx/ audio/ battle/)" --prune-empty -- --all
git filter-branch -f --tree-filter "git rm -rf -f --cached --ignore-unmatch README.md compare.sh constants.asm main.asm INSTALL.md Makefile main.asm pokecrystal.asm wram.asm vblank.asm bittable2.asm" --prune-empty -- --all
git filter-branch --tag-name-filter cat --prune-empty --msg-filter 'python ~/scripts/commit-cleaner.py' -- --all
git filter-branch --index-filter "git update-index --remove README.md compare.sh constants.asm main.asm INSTALL.md Makefile main.asm pokecrystal.asm wram.asm vblank.asm bittable2.asm trainers/ text/ stats/ gfx/ audio/ battle/ music/" --
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch README.md compare.sh constants.asm main.asm INSTALL.md Makefile main.asm pokecrystal.asm wram.asm vblank.asm bittable2.asm trainers/ text/ stats/ gfx/ audio/ battle/ music/ README .hgignore textpre.awk data/" HEAD
git filter-branch --prune-empty
git filter-branch -f --commit-filter "git rm -r -f --cached --ignore-unmatch README.md compare.sh constants.asm main.asm INSTALL.md Makefile main.asm pokecrystal.asm wram.asm vblank.asm bittable2.asm trainers/ text/ stats/ gfx/ audio/ battle" --prune-empty -- --all
# move files out of a subdirectory
git filter-branch --tree-filter 'test -d extras/ && mv extras/* . || echo "Nope"' HEAD
git filter-branch --tree-filter 'test -d extras/ && mv extras crystal && (test -d preprocessor.py && mv preprocessor.py crystal/ || echo "hi") || echo "Nope"' HEAD
# prune empty merges ??
# http://git.661346.n2.nabble.com/Removing-useless-merge-commit-with-quot-filter-branch-quot-td7356544.html
git filter-branch -f --prune-empty --parent-filter ~/scripts/git-rewrite-parent.rb master
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_NAME" = "padz" ];
then
GIT_COMMITTER_NAME="yenatch";
GIT_AUTHOR_NAME="yenatch";
GIT_COMMITTER_EMAIL="yenatch@gmail.com";
GIT_AUTHOR_EMAIL="yenatch@gmail.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
@kanzure
Copy link
Author

kanzure commented Aug 3, 2013

yo, use --subdirectory-filter. Also, can I have commit-cleaner.py pretty please?

@kanzure
Copy link
Author

kanzure commented Sep 9, 2013

Here's a good way to clean the repo up after filter-branch:

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d

And then:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \
-c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@" --aggressive

@whitecat
Copy link

whitecat commented Oct 4, 2016

Is there some way to use filter--branch and replace a using a pattern. For example say I want to replace all issue number with just the word task(i.e. issue-\d{1,4} -> Task)

@chmartinez
Copy link

The real MVP! Thanks man!

@TWiStErRob
Copy link

Tip: you can write a complex shell script into a file rather than between a multiline '':

git filter-branch --commit-filter 'source $(PWD)/../../.git/commit-filter-foo.sh' <first-commit-hash>^..<last-commit-hash>

Note: PWD is <repo>/.git-rewrite/t/.

commit-filter-foo.sh in .git of the <repo> contains for example if [ "$GIT_COMMITTER_NAME" = ... from above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment