In order to bring into main
all the relevant changes that happened in external
two things will need to happen:
- Isolate the original
main
- Bring into
main
it all commits that happened in external
For the first, Isolate the original main
:
Seems like you probably have main
in its own repository.
If not it could be retrieved from the external
repository as long as the original main
commits where set as a parent of the commit that created the external/main
subdirectory. An example of such is the process outlined in Git Book Subtree Merging page
Commits where subtree where introduced can be found as described in this answer.
And then it is just a matter of grabbing the whole set of commits that are the base of main
and make a repository out of it.
For the second, Bring into main
it all commits that happened in external
:
You already have isolated the commits that contain changes in the exteral/main
subfolder, but as you state it does not include the original main
commits.
git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all
This is because filter-branch
will only check for the files in the specific subdirectory location, without knowing how to handle more complex operations like the read-tree
that created the subdirectory.
After the filter-branch
operation, you will be left with a set of commits that contain all changes that happened in main/external
. Lets assume that this set of commits can be reached in the filteredMain
branch.
Since the contents were moved from the subdirectory to the root the location of the files is now the same again as in the contents in the main
repository. This will allow for both trees to be joined. Since this two trees, main
's master branch and filterBranch
have no history in common they can be joined by a rebase
replaying the changes of the commits.
# in the main repository
# bring the external repository and get the branch
git remote add external /path/to/external
git fetch external filteredMain
git checkout filteredMain
# We need the first commit of this tree for the rebase command
firstCommit=$(git rev-list --max-parents=0 HEAD)
# run the rebase
git rebase --onto master $firstCommit filteredMain
After this the filteredMain
branch should contain all the changes that happened in external/main
replayed on top of the original master
branch in the main
repository.