Skip to content

Moving a RYS repository while keeping git history

In this article you will learn how to move an existing RYS repository into another git repository without losing commit history.


When to use this approach

Use this process when a RYS or gem lives in its own repository and you want to move it into another repository, for example into gems/ryspec, while preserving its full git history.

The key idea is:

  1. rewrite the source repository so its files live under the target subdirectory,
  2. fetch that rewritten history into the destination repository,
  3. merge the histories together.

Prerequisites

Make sure git-filter-repo is installed:

brew install git-filter-repo

You will need:

  • the source repository URL,
  • a clean temporary directory for the rewritten clone,
  • a target path in the destination repository, for example gems/ryspec.

Migration procedure

1. Clone the source repository into a temporary directory

git clone <ryspec_repo> ryspec_tmp
cd ryspec_tmp

2. Rewrite the repository into the target subdirectory

git filter-repo --to-subdirectory-filter gems/ryspec

After this step, every commit from the source repository is preserved, but its files are now stored under gems/ryspec.

3. Switch to the destination repository and create a working branch

cd ../your_app
git checkout -b fix/ryspec-history

4. Add the rewritten repository as a temporary remote

git remote add ryspec_clean ../ryspec_tmp
git fetch ryspec_clean

5. Remove the existing subtree if it is already present

If the target directory already exists and contains the old broken subtree, remove it first:

git rm -r gems/ryspec
git commit -m "Remove broken subtree"

Skip this step if gems/ryspec is not present yet.

6. Merge the rewritten history into the destination repository

git merge ryspec_clean/master --allow-unrelated-histories

This creates a merge commit connecting both repositories while keeping the full original history of the moved RYS.

If git reports conflicts, resolve them as usual, then finish the merge.


Full example

# ensure git-filter-repo is installed on your machine
brew install git-filter-repo

git clone <ryspec_repo> ryspec_tmp
cd ryspec_tmp
git filter-repo --to-subdirectory-filter gems/ryspec

cd ../your_app
git checkout -b fix/ryspec-history
git remote add ryspec_clean ../ryspec_tmp
git fetch ryspec_clean
git rm -r gems/ryspec   # if subtree already added
git commit -m "Remove broken subtree"
git merge ryspec_clean/master --allow-unrelated-histories

Verification

After the merge, verify that history was preserved:

git log -- gems/ryspec

You should see commits originating from the old repository.

It is also a good idea to inspect the resulting tree:

ls gems/ryspec

Cleanup

Once the merge is done, you can remove the temporary remote:

git remote remove ryspec_clean

If you no longer need the temporary clone, you can delete ryspec_tmp as well.


Notes

  • git filter-repo rewrites commit hashes in the temporary clone. That is expected.
  • Always run git filter-repo on a disposable clone, not on your original working repository.
  • If the default branch of the source repository is not master, merge the correct branch instead.
  • This approach is useful when replacing a broken subtree import with a clean history-preserving merge.