Move git module with history
A while back in my daily job as an Android developer I received a task to move a git module from it’s origin to another git module while keeping it’s history.
As a developer I’ve always prefered to use tool with UI for git related stuff but this time decided to go real hardcore by using only Terminal (in MAC OS).
Before explaining how I achieve to complete the task let’s explain a little but how our project was structured.
In our Android project there was a main app module which holds all code related to the application itself. Since the project itself had lots of modules and submodules we decide to reorganize a little bit for better development process and improve projects structure.This is how the structure was before:
- app-module (git module 1)
- main-library-module (git module 2)
- many-submodules
- // Lots of them
- arch-module (git module 3)
- // Many other modules
And that’s how the project should look like after:
- app-module (git module 1)
- main-library-module (git module 2)
- new-name-arch-module (with history) (part of git module 2)
- many-submodules
- // Lots of them
- // Many other modules
As it seems almost every module is a separate git module with it’s own history and I should move one git module to another while keeping the history (sorry for repeating myself again.).
So which is the easiest way to achieve this?
Not sure if that’s the easiest way, buy I completed the task using git remote.
I hope everyone reading this knows what is git remote and used it at least once. If not you can learn more about it using the link: Git Remote Documentation
So now we can begin with my step by step explanation
1.Add arch-module as a remote to main-library-module via:
git remote add arch-module [url of the remote: git@github.com/hardartcore/some-repo]
2 Check for remote’s status
git remote -v
3 Fetch remote and checkout master branch
git fetch arch-module
git checkout arch-module/master
4 Check status to be sure everything is ok for now
git status
5 Clean the repo
git clean -d -fx
By using this command git cleans the current repo and leaves only files from arch-module/master branch. The reason behind this is very simple. Lets assume that lots of works are working on that same project and while you are moving stuff around a coworker of yours made some changes in main-library-module which creates conflicts with your version of the repo. When the time comes to merge your changes to the master/main branch youl will have to resolve those conflicts. By using clean this won’t happen because you are introducing only new files.
6 Checkout a new branch
git checkout -b new-arch-migration
7 Apply some changes if needed and commit changes
git rm filename.txt // just for example
git commit -m 'Remove: filename.txt from repo'
8 That’s when we apply other operations. In this example moving the files to a new directory
git mv arch-module new-arch-module
9 This is the point where we checkout the main branch of the task
git checkout new_arch_framework_integration
10 And the most important command
git merge new-arch-migration --allow-unrelated-histories
11 Commit changes
git commit -m 'Update: Merge new-arch-module to main-library-module'
And since we are done with the task we can remove the remote we added at the beggining of the task:
git remote remove arch-module
And that’s all.
Hope this will be useful for somebody else too.