Search code examples
gitgit-filter-branchgit-rewrite-history

How to add a file to a specific commit with git filter-branch?


We need to add some file in a specific past commit on a repo and we are ready to rewrite history so it affects to all branches diverging from that commit's children. We are trying to use git filter-branch for that, using add, since once we add the file to a commit it won't be added to the children, but we can't find the right parameters for stop it affecting to some concurrent diverging commits. See image for understanding.

We are using this command targeting the red commit, but the file is appearing on the purple commit - why? - and it's also appearing on the green commit, and we don't want it to affect that code path, just appear on the red commit and then be inherited through all the child commits and the merge.

git filter-branch --index-filter "cp C:/Users/asdf/Documents/IdeaProj ects/git-crypt-tests/.gitattributes . && git add .gitattributes" 72c7e292ddd134c04285f3530afc829fd38de4 28..HEAD

What am I understanding bad?

Thank you.

enter image description here


Solution

  • It looks like you thought that when you write a commit range as A..B that it would include the bounds. But it does not. This notation is short for B ^A, i.e., everything leading up to B, but excluding everything up to A. This removes the "lower" bound A from the range. The solution is that you write A~, which means "the ancestor of A": A~..B.

    Furthermore, since you know exactly which commits you want to add the file to and which you do not want to add them, you can restrict the revision walker to list only the wanted commits:

    git filter-branch --index-filter "cp C:/Users/asdf/Documents/IdeaProjects/git-crypt-tests/.gitattributes . && git add .gitattributes" -- HEAD --not 72c7e29~ ":/Fix Prestapp"
    

    That is, you say that you want all commits leading up to HEAD, but nothing before 72c7e29~ nor before the commit whose message begins with Fix Prestapp.