Search code examples
gitgit-subtree

Git subtree push seems to push commits that don't apply to the subtree?


I have a subfolder of a repo that I'm trying to split into a subtree. To start, I followed this procedure (https://stackoverflow.com/a/43985326/136785) to create a branch containing just the commits related to the subfolder (including renames). I confirmed that the branch's commit log looks as expected.

Next, I create a new repo for that sub-project:

git init --bare \\nas\git\FPF.git
git push ssh://myserver.com/~/FPF.git branch-fpf:master 

Then I remove the subfolder from the parent repo & re-add it as a subtree:

git rm -r htdocs/wp-content/plugins/fpf
git add -A
git commit -am "Removing folder to re-add as subtree"
git remote add fpf ssh://myserver.com/~/FPF.git
git subtree add --prefix=htdocs/wp-content/plugins/fpf fpf master --squash

Now as a quick sanity check, I'll grab a copy of the remote subtree repo (in another folder, of course):

git clone ssh://myserver.com/~/FPF.git

And:

git subtree push --prefix=htdocs/wp-content/plugins/fpf fpf master

Because I've not committed any changes between adding the subtree & pushing, I expect there to be nothing new to push. But as it turns out, if I clone FPF.git once more, I find that it now has a TON of extra commits - FPF has grown many times larger, with a commit log that now reflects many commits that only apply to files outside of the subtree.

Why would git subtree push be pushing commits that don't apply to the subtree?

Edit 1: The extra commits are all the commits from the main (parent) repo starting before the first FPF commit & going back to the beginning of time. In other words: if I compare the logs of the FPF subtree repo before & after doing the git subtree push, they are identical, until I get to the bottom of the "pre-push" clone's log. From there, the "post-push" clone's log continues all the way back through the first commit of the parent project. Git subtree push effectively appended the parent's full prior history.

Edit 2: I've decided to give up on git-subtree. I discovered https://github.com/ingydotnet/git-subrepo, which not only works properly, but solves a number of subtree's shortcomings (most notably the VERY slow pushes). Leaving this question here in case anyone else comes up with an answer or is struggling with the same, but to simplify a bit, here's a full start-to-finish set of commands that exhibits the problem. Difference from above: this doesn't start with a branch made by grafting together multiple filter-branches; it just does the simplest case of a single subtree split:

cd MainProjectRepo
git subtree split --prefix=htdocs/wp-content/plugins/fpf --branch=branch-new
git init --bare \\nas\git\FPF.git
git remote add fpf ssh://myserver.com/~/FPF.git
git push fpf branch-new:master
git rm -r htdocs/wp-content/plugins/fpf
git add -A
git commit -am "Removing folder to re-add as subtree"
git subtree add --prefix=htdocs/wp-content/plugins/fpf fpf master --squash

git clone ssh://myserver.com/~/FPF.git /tmp/fpf1
git subtree push --prefix=htdocs/wp-content/plugins/fpf fpf master
git clone ssh://myserver.com/~/FPF.git /tmp/fpf2

As described above, fpf2 ends up with the entire history of commits from the source repo.


Solution

  • For others who may come across this:

    My conclusion, after many many hours of struggling (reading, discussing, retrying in different ways, etc) was that git-subtree just doesn't work properly. Instead, I discovered a much better alternative: git-subrepo. Not only does it work properly, but solves a number of subtree's other shortcomings - most notably the VERY slow pushes.

    Thus my "answer" to how to solve this: abandon git-subtree & use git-subrepo instead :)