Last active
November 7, 2019 23:35
-
-
Save smashwilson/015e6a3abfbf7af73d31 to your computer and use it in GitHub Desktop.
Move a subdirectory from one git repository to a subdirectory of another, without losing commit history.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Assumptions: | |
# | |
# * After the merge is complete, the directory should exist in the target repository and not exist in the source | |
# repository. In other words, this is a move, not a cross-reference: we never want to be able to push commits | |
# back to the source repository, or merge further changes from the source repository. If you want to do that | |
# instead, a subtree merge is what you're looking for. | |
# | |
# * The directory doesn't exist in the target repository yet. | |
# | |
# In this example, we're moving the "/openstack-swift/" directory from jclouds/jclouds-labs-openstack to | |
# "/apis/openstack-swift/" in jclouds/jclouds. | |
# Get a clone of the target repository. | |
git clone [email protected]:jclouds/jclouds.git | |
cd jclouds | |
# Add the source repository as a remote, and perform the initial fetch. | |
git remote add -f sourcerepo [email protected]:jclouds/jclouds-labs-openstack.git | |
# Create a branch based on the source repositories' branch that contains the state you want to copy. | |
git checkout -b staging-branch sourcerepo/master | |
# Delete everything that isn't the directory we want to move. | |
# Don't worry, we're not going to push this back ;-) | |
git rm -r openstack-glance/ openstack-heat/ openstack-marconi/ \ | |
openstack-neutron/ openstack-autoscale/ rackspace-* \ | |
*.md pom.xml | |
git commit -m "Delete everything we don't want to merge" | |
# Move the directory into its final position. | |
mkdir apis/ | |
git mv openstack-swift/ apis/ | |
git commit -m "Lock S-foils in attack position" | |
# Change back to master and merge it in. | |
# You could also do this by submitting a pull request, of course. I had one conflict, in /.mailmap. | |
git checkout master | |
git merge staging-branch | |
# I had one conflict, in /.mailmap. Fix it, stage it, and commit it to finalize the merge. | |
${EDITOR} .mailmap | |
git add .mailmap | |
git commit | |
# Voila! The directory has moved, and you still have full history: | |
# | |
# ~/samples/jclouds (master>) $ git log --follow --oneline apis/openstack-swift/pom.xml | |
# cb930d9 Move openstack-swift into apis/. | |
# 491dc97 Revert "Fix poms so that modernizer doesn't fail on snapshot." | |
# 889243a Fix poms so that modernizer doesn't fail on snapshot. | |
# d65048d Fix Maven parent.relativePath warnings | |
# f33e90e Updating project versions to 2.0.0-SNAPSHOT | |
# be8bc22 Up to 2.0.0-SNAPSHOT after the 1.8.0 release | |
# | |
# (Notice that you do need the --follow to trace through the git mv I did.) | |
# Next: be sure to promptly delete the directory from the source repository by normal means | |
# (git rm -r dir/ && git commit && git push && pull request), because you don't have an | |
# easy way to update the target repository with further changes. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
:) Agree. I also checked this without having been notified!
If I'm not wrong (haven't tried, just seen comments after googling for the best process) when using subtrees you're not able to rebase normally the branch. It presents several issues.
+1, and thanks for the feedback! :)