Reputation: 3021
I have found a couple of examples [here's one] of how to move a folder from one git repo to another. However, it seems to be destructive to the original repo (if I'm reading it correctly). What I need is to just copy a folder from one repo to another, with history, to another. something like the following:
Repo A:
/myApp/
/deploy/...
/src/...
/test/...
/bin/...
Repo B:
/myDeploymentCode/
/projects/
/myWebService/...
/myWebsite/...
After the copy I would like it to look like this:
Repo A:
/myApp/
/deploy/...
/src/...
/test/...
/bin/...
Repo B:
/myDeploymentCode/
/projects/
/myWebService/...
/myWebsite/...
/myApp/... << full copy of the deploy folder from myApp
I will likely get rid of the original deploy folder but want to keep it around until I know we are in the clear.
I'm guessing this is possible and I'm just blind. If it isn't, I could just manually move the files over. Losing all of the history but capturing the current state. But that is less than ideal.
Upvotes: 2
Views: 98
Reputation: 55563
You can do that via the git subtree
command (built-in since some time; available in contrib
earlier):
git subtree split -P myApp/deploy
in repo "A" to create a synthetic history containing only the contents of that "myApp/deploy" folder.git subtree add -P myDeploymentCode/projects/myApp ...
to "plant" that history using a merge commit.The only problem with the result is that all the commits in that extracted history line—except the one which merged it with the new code base—will not record the fact the files in them are under the "myDeploymentCode/projects/myApp" prefix so commands which trace the history of a pathname or pathname prefix, like
git log -- myDeploymentCode/projects/myApp/foo.txt
might fail to advance back past that merge commit which "planted" the extracted history into the new code base (in this example, the file "foo.txt" will be there in those commits but located at the top level rather than under that prefix).
If you're OK with this then just do it. Otherrwise you might need to first run a git filter-branch
encantation on the extracted history to rewrite all commits forming it to have their files under that new prospective prefix the history will be planted at.
One way to do that is
git filter-branch -f --tree-filter \
'test -e myDeploymentCode/projects/myApp || mkdir -p myDeploymentCode/projects/myApp
find . -mindepth 1 -maxdepth 1 \
-type d -path ./myDeploymentCode -prune -o -print \
| xargs -n 30 mv -t ./myDeploymentCode/projects/myApp' temp
(Assuming you've created a branch named "temp" out of the SHA-1 name of the commit git subtree split
told you at step (1).)
Please see this for the same example accompanied by an in-depth explanation of how it works.
It might worth noting that the history git subtree split
produces is synthetic, that is, the SHA-1 names of the commits comprising it do not exist in the source repository. That's obvious to those familiar with the Git internals—while blobs are reused by the extracted history, tree and commit objects are not—but be warned just in case.
Upvotes: 1