Hello! I was directed to ask here; I hope I am respecting your format.
I have a repo with a subtree. I squashed every merge with the subtree
remote to keep the history manageable. Now down the road after a bunch
of merges, I need to split my repo’s master branch into two new
branches and move the subtree from `/subdir/subdir/` to `/`.
(`/subdir/subdir/user/mycode/` contains code from my repo.)
I ran `git subtree split -P=subdir/subdir/ -b newbranch` and the
outcome seems to be perfect except that each squash merge has turned
into a full merge, bringing along all history from the other repo. Why
does it do this and how can I preserve my repo history, including only
squashes from the subtree remote repo like it is today?
> I ran `git subtree split -P=subdir/subdir/ -b newbranch` and the
> outcome seems to be perfect except that each squash merge has turned
> into a full merge, bringing along all history from the other repo. Why
> does it do this and how can I preserve my repo history, including only
> squashes from the subtree remote repo like it is today?
The only thing that --squash does on an add/merge/pull is a read-tree of
the fetched commit into a new commit in the host repository which is
then merged in to the host repository's branch. It also annotates the
hash of the original commit in the git-subtree-split metadata.
As the split code processes commits it records parents to link up the
history to that in the subtree's original repository. Crucially, the
git-subtree-split metadata of the commit message git-subtree creates for
squashes lists the original commit ID of the squashd commit. That lets
git-subtree hook up split commits back to the original project history.
I believe that's why the split branch is showing the full history. It's
baked into the split algorithm.
Presumably you split the subdirectory from the same working repository
in which you added the subtree commits in the first place. Thus the
history of the original project is all there (it was fetched when the
subtree was added/merged). I have not tested this, but I wonder what
would happen if you either deleted that history from the host repository
or you cloned the host repository to a new place and tried the split
there. The original hisory wouldn't be there and git-subtree would not
have it to hook up to.
I have mentioned before that I'm working on a complete overhaul of the
split code. Since git-subtree split it typically used to send commits
back to the original subtree repository, I never imagined that someone
would *not* want to get the original history back. If the squash were
not reversed we would not be able to merge the history back in to the
original repository. If keeping squashes is truly desired I will have
to think about how to do that, likely as a non-default option to split
or even an entirely different command.
I began to wonder if indeed I was using the correct paradigm, since
the split operation would leave the subtree prefix as `/` which is an
impossible prefix when creating a subtree. Attempting to add a new
subtree with prefix `/` results in an error because the prefix
directory is not empty (it contains `.git`).
Long story short, I realized I probably had to start over without
using subtree at all and manually rebase and remerge. I discovered
that now that I'm not using subtree, I can no longer squash merge. It
works for the first merge but subsequent squashes do not remember what
the previous squash's parent commit was from the other repo. (The
subtree subsequent squash merge experience was perfect.) I decided to
be okay with that and give up the idea of squashes; I can use `git log
--author=jnm2` so that I can actually read my history, and in the
unlikely scenario that I can't access the other repo at least I'll
have full history.
The only thing I dislike is that I'm giving up the concept of that
separation between two repos in the same working tree- that some files
belong to one repo and some to the other. That's a cool paradigm.
Since my access to the other repo is read only, I suppose that doesn't
matter. I can't use subtree because the prefix would be `/`, and I
can't use submodule because my repo needs to track my changes inside
the prefix as part of my repo.
> I have not tested this, but I wonder what would happen if you either deleted that history from the host repository or you cloned the host repository to a new place and tried the split there.
I tried that in the course of my tests earlier; if I remember
correctly, I lost the squash merge history. Git log showed only the
parents from my repo. I couldn't do a new squash merge because it lost
track of the most recent squash's parent commit in the other repo.
> I never imagined that someone would *not* want to get the original history back
It's possible that what I was trying to do made no sense in the first
place. It's likely that I'm missing something since I'm new to these
concepts. I feel like I've settled for a less clean solution but I
can't put my finger on it. I'm willing to try a different