I've been using the git-subtree extension (https://github.com/apenwarr/git-subtree) to manage sub-projects within our main project. It's doing exactly what I want other than the fact that it fails when I try to split out changes made to a sub-project from our main project.
e.g. earlier on I had done
git subtree add -P Some/Sub/Dir --squash git@gitserver:lib.git master
to bring in the library code to Some/Sub/Dir in our main project. Everything here went great so I then pushed my changes to our central main project bare git repo. I then decide to make a change to my local version of the lib in Some/Sub/Dir, commit it, then split it out to push it back to the lib.git repo
git subtree split -P Some/Sub/Dir -b some_branch
everything works as expected. No longer needing the local copy of the repo I deleted it.
After cloning a new copy of the repo from our central repo I made some changes to the lib in Some/Sub/Dir and decided I wanted to split those changes out and push them back to the lib.git repository. I attempt to use the same subtree split command as before, however this time I end up with the following output:
1/ 3 (0)
2/ 3 (1)
3/ 3 (1)
fatal: bad object d76a03f0ec7e20724bcfa253e6a03683211a7bb1
d76a03f0ec7e20724bcfa253e6a03683211a7bb1 comes from when I added the subtree:
commit 43b3eb7d69d5eb64241eddb12e5bd74fd0215083
Author: Ian Bond <ibond@onezero.com>
Date: Fri Apr 22 15:06:50 2011 -0400
Squashed 'Subtree/librepoLib/' content from commit d76a03f
git-subtree-dir: Subtree/librepoLib
git-subtree-split: d76a03f0ec7e20724bcfa253e6a03683211a7bb1
which actually refers to a commit in the lib.git repo.
What I've been able to piece together (and I'm a git noob so I may be wrong, overlooking something, or using incorrect terminology here), is that 'git subtree add --squash' will bring in the entire history from the remote lib.git repo into the current repo, squash it down into a separate commit, then add that commit into the working branch. The lib.git commit history remains in the current repo, however they're dangling commits since they're not actually referenced other than through the text of the squash commit. As long as those dangling commits remain, git-subtree can use them to perform splits, however since a push or pull doesn't contain dangling objects (or if I run a gc and fully prune dangling objects), those dangling commits are lost and git-subtree no longer has the necessary information to perform the split.
I've added a script that will fully reproduce the issues I've been having.
My questions are:
1) What can I do to handle the existing situation where I now have subtrees that I want to merge back to their origin repo, but no longer have any sort of history that links them together. My current thought is to do something like:
git subtree split -P Some/Sub/Dir 43b3eb7^.. --ignore-joins -b splitBranch
to split out all of the history since the 'git subtree add' and merge it back into the origin repo (which thankfully has not had any changes since the add). Is this the best way to go? Any recommendations for how I should perform the merge?
2) Is there anything I can do to make git-subtree work as expected? I believe if I omit the --squash parameter on 'git subtree add' then everything will work, however that causes a bunch of unrelated history to be injected into my repo. Is there some way to keep the needed commits around (preferably without keeping the entire history of the library around)?