The build system I work with usually requires that the project data is committed to the local repository before a full build can be performed. This -- along with my usual habit of committing frequently and rebasing before pushing to the public repo -- means I usually have a stack of commits on top of the remote head. Most of them have commit messages like "s" because I know they will be squashed.
The situation I have here is automating one of the steps of rebasing the list of commits. I know that all the changes I make to a certain file should not be pushed to the public repo, and I was looking for a way to edit each commit to split off the changes to that file into separate commits which I will squash in a later rebase.
For example, here's the commits I have on top if the origin's HEAD:
* 6f42745 (HEAD, master-dave) s
* b33bc68 s
* 0b787e8 s
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
I want to iterate through all commits from master..master-dave, extract changes to ./file.txt, giving me:
* 6f42745 (HEAD, master-dave) s
* ------- DD (changes to file.txt)
* b33bc68 s
* ------- DD (changes to file.txt)
* 0b787e8 s
* ------- DD (changes to file.txt)
* 3d47e9e s
* ae45dec brought pkg up-to-date with master branch
* dd87ec1 s
* 96fd4ef DD: dave dev
* 422cf73 (origin/master, master) Add missing build scripts.
And finally, I would run git rebase -i origin/master, squash all the "DD" commits together, all the "s" commits into "brought pkg up-to-date with master branch", re-order them, update master, and push to origin, finally ending up with:
* ------- (HEAD, master-dave) DD: dave dev
* ------- (origin/master, master) brought pkg up-to-date with master branch
* 422cf73 Add missing build scripts.
I'm pretty sure the answer lies with git filter-branch, but I can't figure out how.
EDIT:
- --autosquash fixes the annoyance of the "s" commits, but that's not the main question. I still don't know how to split out the changes to a specific file, which must happen before I squash them.
- smudge/clean filters are nifty, but I'm not doing keyword replacement, and I don't think the changes I want to maintain on my personal branch are going to be predictable enough to script. I think I'm always going to have to be at least one commit ahead of the public master.