In fact, both filter-branch and rebase use the same basic idea, which is that each commit is copied, by expanding the original contents, making any desired changes, and then making a new commit out of the result.