Help
cancel
Showing results for 
Search instead for 
Did you mean: 
Ground Controller Lvl 1
Message 1 of 3

Adding a folder from one repo to another

I have been playing around to create a `subtree`.

 

     RepoFolderSrc         RepoFolderTarget       RepoAnother
        |                        |                    |
      develop                  sfcc------------------sfcc18
        |                        |         
        |                        | 
        |-someFolder1            |
        |-someFolder2----------featureBranch


I want to copy the `someFolder1` and `someFolder2` from `RepoFolderSrc` to `RepoFolderTarget`. I want to retain all the history for the folder `someFolder1` and `someFolder2` when it is copied over to the `featureBranch`.

 

A few of the solutions I have seen requires deleting the `origin` from `RepoFolderSrc`. I should not make any changes to the `RepoFolderSrc` and I should not create any additional branch or commits on the folder.

Is there a way by which I can copy over the folder by only playing around with the `RepoFoldertarget`. I do have push and pull permissions for all repositories.

2 Replies
Moderator
Message 2 of 3

Re: Adding a folder from one repo to another

If you're referring to the solution described in this blog post, as one of the ones you've seen but disliked how it worked because it made changes to the source repository, then I'm afraid to say that it is the canonical solution for getting done what you're describing. I also think you're misunderstanding when you say that the solution requires "deleting the `origin`" or "create additional branch or commits". Let me see if I can rephrase the solution more clearly.

 

The goal here is to copy from a repo named `source` to a repo named `destination` only the contents of folder `foo`, including all history that touches folder `foo`. In order to do that, because Git doesn't track folders per se but tracks commits, we'll have to filter the commit history of the `source` repo to only contain the commits that touch folder `foo`. The way we'll do that is via the `git filter-branch` command using the `--subdirectory-filter` filter. First, we'll need to create a local copy of the `source` repo separate from any local copy you already have. You can do this by doing the following:

 

mkdir backup
cd backup
git clone https://github.com/user/source.git
cd source

 

Now, we are in the directory `backup/source` which is a completely new local copy of the `source` repo separate from any local copy you already have. Additionally, we want to protect https://github.com/user/source from being accidentally changed by our process here. We do that by deleting the `origin` remote, but only in this new local copy.

 

git remote rm origin

 

Next, we want to filter the commit history of the `source` repo to only contain the commits that touch folder `foo`. We do that by issuing the `filter-branch` command:

 

git filter-branch --subdirectory-filter foo -- --all

 

But, as you'll notice in the documentation for the `git filter-branch --subdirectory-filter` command, it states:

 

The result will contain that directory (and only that) as its project root.

 

 This means that everything that was in `foo` is now in the root of the repo. So, in order to put it all back in folder `foo`, we have to add one commit to this local only temporary working repository that we're going to throw away soon:

 

mkdir foo
mv * foo
git add .
git commit

 

Now we have a local repository that contains only the files and history that we want. We're halfway there! 🎉And remember, this is just a temporary place to store some work. It is completely separated from your normal local `source` repository and from https://github.com/user/source, so any changes we make here are not permanent. It's like making a temporary backup of a file so that you can revert back to the original if you screw something up.

 

Now, in order to merge this new history that we've created into the destination repository, let's assume that the destination repository is already cloned locally in `projects/destination` from https://github.com/user/destination. So we need to:

 

cd ../../projects/destination

 

in order to move from `backup/source` to `projects/destination`. Then we issue the following commands:

 

git remote add modified-source ../../backup/source
git pull modified-source master --allow-unrelated-histories

 

This pulls all of the commit history of our temporary `source` repo into the `master` branch of our local copy of the `destination` repo. Then all that is needed is to clean things up:

 

git remote rm modified-source

 

This removes the link between our local `destination` repo and the temporary `source` repo. And when you're sure everything worked correctly, you can delete the modified local `source` repo whenever you feel like.

 

I hope that helps explain things a bit better! Let me know if you have any questions.

Ground Controller Lvl 1
Message 3 of 3

Re: Adding a folder from one repo to another

very detailed and targeted answer, this is really useful