Skip to content

Procedure to move code from one repo to another with history

colinb[APMG] edited this page Jan 7, 2025 · 2 revisions

This page will serve as a guide as how to move an o3de object with history from a subdir of one repo to another repo.

This is the procedure we will use to move gems (and other objects) out of the o3de/o3de to o3de/o3de-etras.

This method was tested on the aws-lumberyard/gallifrey repo which hosts the xr gems and project.

For this example the structure of the gallifrey repo is:
root
\
   XR                   (a gem)
   OpenXRVk      (another gem)
   OpenXRTest    (a project)

What we want to do is isolate the subdirs by using git repo filtering.
The idea here is we take the entire repo and filter out everything we do not need for this object.
And we want to filter in a way that the object will be in the correct subdir relative to the root as we want to see it in the final repo. Then we add this filtered repo as a remote to the destination repo. We do a remote update and then merge using the --allowunrealted-histories.

Always use a FRESH CLONE!!!

git clone https://github.com/aws-lumberyard/gallifrey.git

Since there are 3 different objects in this one repo, I will just copy it 3 times after the clone into their own sibling folders to make things easier, and I'll leave the gallifrey unaltered in case I make a mistake and then I dont have to re clone it again...

cp -R .\gallifrey .\gallifrey-XR

cp -R .\gallifrey .\gallifrey-OpenXRTest

cp -R .\gallifrey .\gallifrey-OpenXRVk

Since we want the XR gem to land in the destination repo's Gems/ folder we want to tell the filter to move it to a subdir called Gems/

cd gallifrey-XR

git filter-repo --path XR --to-subdirectory-filter Gems/

Since we want the OpenXRTest project to land in the destination repo's Projects/ folder we want to tell the filter to move it to a subdir called Projects/
cd ../gallifrey-OpenXRTest

git filter-repo --path OpenXRTest --to-subdirectory-filter Projects/

Since we want the OpenXRVk gem to land in the destination repo's Gems/ we want to tell the filter to move it to a subdir called Gems/

cd../gallifrey-OpenXRVk

git filter-repo --path OpenXRVk --to-subdirectory-filter Gems/

After these commands:
gallifrey-XR should look like:
root
\
   Gems
   \
     XR

gallifrey-OpenXRVk should look like:
root
\
   Gems
   \
     OpenXRVk

gallifrey-OpenXRTest should look like:
root
\
   Projects
   \
     OpenXRTest

Now we want to merge these 3 repos into o3de-extra, so we do a FRESH CLONE of o3de-extras, set these new repos as remotes, create a new branch to merge into it allowing unrelated histories.
git clone https://github.com/aws-lumberyard/o3de-extras.git
cd o3de-extras 
git remote add XR ../gallifrey-XR 
git remote add OpenXRTest ../gallifrey-OpenXRTest 
git remote add OpenXRVk ../gallifrey-OpenXRVk 
git remote update git switch -C <your merge branch> 
git merge --allow-unrelated-histories XR/main 
git merge --allow-unrelated-histories OpenXRTest/main 
git merge --allow-unrelated-histories OpenXRVk/main

Then push

git push origin

Warning: If your source repos have LFS files, you then have to take care of the LFS objects by uploading them.

Remove the remotes:

git remote  remove gallifrey-XR
git remote  remove gallifrey-OpenXRTest
git remote  remove gallifrey-OpenXRVk

Then create your PR and done.

Example moving a gem from the engine to the o3de-extra

For moving a gem from the engine to extras we will do the same thing but for just one object. Lets do an example Gems\Achievements:

We need a FRESH CLONE of o3de/o3de and for this example we will rename the repo on clone to what we are going to filter down to. So I'll call it o3de-gem-achievements as this is the repo we will filter down to the achievements gem

git clone https://github.com/o3de/o3de.git o3de-gem-achievements

We don't need to move Gems\Achievements into a different subdir as it is already in the Gems\Achievements, which is the relative path where we want it to land in the extras repo, but if it wasn't we would have added --to-subdirectory-filter Gems/

git filter-repo --path Gems\Achievements

So now we have a repo, o3de-gem-achievements, filtered down to only have the single gem in it, and it looks like:

root
\
  Gems
  \
    Achievements

Now we need a FRESH CLONE o3de-extras repo

git clone https://github.com/aws-lumberyard/o3de-extras.git

cd o3de-extras

We add the filtered down gem repo we just made,o3de-gem-achievements, as a remote

git remote add o3de-gem-achievements ../o3de-gem-achievements

git remote update

We create a new branch for these changes

git switch -C inital-o3de-gem-achievements

Merge these changes allowing unrelated histories

git merge --allow-unrelated-histories o3de-gem-achievements/main

Push to origin

git push origin o3de-gem-achievements

Warning: If your source repos have LFS files, you then have to take care of the LFS objects by uploading them.

Remove the remote:

git remote remove o3de-gem-achievements

Your PR for adding the gem to the extras is now ready, however you still have the old gem in o3de/o3de that has the same name as the gem you are putting into the extras. Its not likely but could fail AR... So you create a new PR to remove it from o3de/o3de, in this case the o3de/o3de Gems\Achievements. Since you may technically be able to get away with having two objects with the same name at the same time, it will most likely pass AR as the first one it finds will be used.

Once your PR for removing the old gem passes and is removed, your PR for the addition to extras can be accepted.

Don't forget to remove the gem from the engine.json in o3de and dont forget to add the gem in the extras .automatedtesting.json