I have attached a testcase shell script. I want to downgrade a sub-project, but can't figure out how. Here's the story:
I created two repos, "subproject" and "superproject". I committed several versions of some files into subproject, giving them tags "v0", "v1", "v2"... etc. In superproject, I added subproject as a repo and merged it as a subtree:
git remote add subproject ../subproject
git fetch --tags subproject
git merge -s ours --no-commit v1
git read-tree --prefix=subproject/ -u v1
git commit -m "added subproject at v1"
Next I update the subproject to v3, and that goes well:
git merge -s subtree -X subtree=subproject v3
But then I realize I really want v2. I think what I need here is a rebase, but I'm not sure. Here's what I tried:
git checkout -b downgrade-subproject-to-v2
git rebase -s subtree -X subtree=subproject --onto v2 downgrade-subproject-to-v2
But I see the contents of the subproject get spoojed out all over my superproject's main directory!
So I did some reading and found some other ideas. This one did not work:
git revert --no-edit v3
It also spoojed files in my superproject, and complained about conflicts. This also did not work:
git merge -s subtree -X subtree=subproject v2
Obviously, v3 has already been merged, so merging v2 (an ancestor of v3) will have no effect.
The only thing I've found that results in a downgrade is this:
git diff v3 v2 --src-prefix=subproject/ --dst-prefix=subproject/ | patch -p0
But I don't like it, because it doesn't actually show proper ancestry in the commit DAG. It is just a brute-force rewriting of the tree. Also, it relies on the patch program to do "merging", which is not nearly as smart as git merging can do. If superproject made any changes to subproject before the downgrade, patch will not be as likely to resolve merge errors as git merge would be.