Search code examples
ruby-on-railsgitmergegit-history

Merge 2 Rails App subdirectories keeping git history


I want to merge 2 Rails application "we can call source" into another Rails application "we can call target" distributed into subfolders without losing git history.

I want to merge only the main folders of rails.

e.g.

merge source/subfolder >> target/subfolder/source

merge source/subfolder/file.rb >> target/subfolder/source/file.rb

source
├── app
│   ├── controllers
│   │   └── ...
│   ├── helpers
│   │   └── ...
│   ├── jobs
│   │   └── ...
│   ├── mailers
│   │   └── ...
│   ├── models
│   │   └── ...
│   └── views
│       └── ...
├── config
│   └── ...
└── test
    └── ...    

target app should look like:

target
├── app
│   ├── controllers
│   │   ├── source
│   │   │   └── ...
│   │   └── ...
│   ├── helpers
│   │   ├── source
│   │   │   └── ...
│   │   └── ...
│   ├── jobs
│   │   ├── source
│   │   │   └── ...
│   │   └── ...
│   ├── mailers
│   │   ├── source
│   │   │   └── ...
│   │   └── ...
│   ├── models
│   │   ├── source
│   │   │   └── ...
│   │   └── ...
│   └── views
│       ├── source
│       │   └── ...
│       └── ...
├── config
│   └── ...
└── test
    ├── source
    │   └── ...
    └── ...

I just want to keep the git history of the main subfolder, I will merge the rest of the files manually.

Following this post here, I have tried the git tool git subtree and it only works to merge an application "source" into a folder of the target like libraries or plugins, but I want to distribute subdirectories of the source app (controllers, models, helpers, views, specs, ...) into target app subdirectories.

The main objective of this is to can see in Github all the history of the files imported from source app into target app.


Solution

  • ✅ [SOLUTION]

    Finally I found a solution very similar as @matthewd propose, Thanks @matthewd.

    What I did is prepare my source app to merge it directly to target app.

    For each subfolder I wanted to merge, in source dir. I did :

    in source/ $
    

    1) Remove remote just to prevent remote changes.

    $ git remote rm origin
    

    2) Filter repo with the directory I want to merge (e.g. directory: app/controllers)

    $ git filter-branch --subdirectory-filter <directory> -- --all
    

    3) Prepare subfolder

    $ mkdir target
    $ mv * target
    

    e.g. app/controllers/target

    4) Add and commit the changes

    $ git add --all
    $ git commit -a -m "Controllers added"
    

    Then:

    in target/ $
    

    1) I added the remote referenced to my local dir with the previous changes.

    $ git remote add source <../target-dir>
    

    1.1) Create a branch to work with.

    $ git checkout -b new-branch
    

    2) And pull the changes using --allow-unrelated-histories to my repo which if we created a correct subfolder should not have conflicts.

    $ git pull source master --allow-unrelated-histories
    

    And thats all, just push the changes to your current branch