I found this problem interesting, so I played around with it a bit and I share this partially working script. My original approach was a bit wrong, but it can be fast (er).
I tried to improve performance by searching for modified files in each commit, where the modification contains the line you want to replace with git log -Sstring . But I forgot that if I change only those, the modification will appear in the next commit, so I had to run the script several times, but it does not check all the files only the modifications, so it may be faster to run this multiple times then your version, but I donβt sure how long the filter branch takes if it does nothing.
Maybe you can use parts of it, maybe get the file names first with git log -S... And you can improve it by using xargs to sed instead of the for loop, but in development, I like this form better. I donβt know how to open my parents correctly, so I did it this way and had to handle the initial fix case separately.
In any case, I am here to study, so if you find a good way to deal with this problem, please share :)
#!/bin/bash commit=$1 pattern=$2 replace=$3 function replaceall() { for f in `git log -S$pattern --pretty="format:" --name-only $1 | egrep -v '.sql$|.class$|.tsv$'`; do echo "FILE $f" sed -i "s/$pattern/$replace/g" $f done } parents=`git log --pretty=%P -n 1 $commit` if test -z "$parents"; then echo "ROOT" replaceall $commit else for p in $parents; do echo "PARENT $p" replaceall $p..$commit done fi
Usage: git filter-branch -f --tree-filter '/path/to/script.sh $commit 01dPassw0rd\! HIDDENPASSWORD' -- --all git filter-branch -f --tree-filter '/path/to/script.sh $commit 01dPassw0rd\! HIDDENPASSWORD' -- --all
I think the script should not be in the git working directory, because the tree filter adds everything that it found when overwriting, but I'm not sure about that.
source share