How to Merge a Git Repository without Losing it’s History (without using submodules)

Eva Gabriela Zamudio
3 min readJun 21, 2018

--

achievement-image from Pexels.com

In the past few months I have been working helping Girl Develop It to build a workflow and to create an efficient and sustainable system of contribution for their master curriculum. One of my steps was to connect two repositories together (the new master curriculum repository with the individual project repositories already existing) and have them look as they had always being in one repository, and I didn’t want to lose the individual project history in the process and neither in this case trying to make changes or ship things back to the individual old repository and instead from now on to maintain all the code in the master curriculum while keeping the fill log of the old repository which is useful so we can understand why things were done that way they are.

Most of the resources I found online, suggest using submodules which goal is to bring in source code from external libraries or projects and where you want to suggest or ship changes to bring back to them and the whole process is kind of complex.

The good news is that Git provides an easier alternative to accomplish this task and here are the steps I have followed and I hope it can help you:

Step 1: Clone projects


git clone git@github.com:main/master-curriculum-repository.git
git clone git@github.com:old-individual-project/old-individual-project.git

Step 2: Moving old repo to master curriculum:


cd old-individual-project
mkdir old-individual-project
git mv !(old-individual-project) old-individual-project
git add .
git commit -m “Moving old project into its own subdirectory to prepare for merge to GDI master curriculum”
git push

!(old-individual-project) is a shell command that says “everything but old-project”. If your project is called html-css, then you move “everything but the html-css.

Troubleshooting: When you are moving the files, if you encounter the following error like this one:


-bash: !: event not found

Run the following command:

$ shopt -s extglob; set +H

The !(old-individual-project) shell command is an extended glob and extglob is turned off so by running the command above, it should fix the event not found error. More info

Step 3: Merging

# Go to the Master Curriculum repository folder
cd ../master-curriculum-repository
# Add a remote for and fetch the old repo
git remote add -f old-individual-project <old-individual-project repo URL>
# Merge the files from old_a/master into new/master
git merge -S --allow-unrelated-histories old-individual-project/master
# Push changes upstream
git push

What we’re doing is add a remote to the old project, and merge everything into the Master Curriculum repository. Since git doesn’t allow merges without a common history, we’ll have to force it using the allow-unrelated-histories option.

Troubleshooting: If you are not familiar with VIM and when you commit your changes, you see a terminal window that opens with a vim window and with a message already pre-populated, then in order to save that message and exit from vim, just follow these steps:
1. Press Esc key
2. Press : (colon). The cursor should reappear at the lower left corner of the screen beside a colon prompt.
3. Enter the following command:
* type :wq!
* press Enter key):
4. This will quit the editor, and all changes you have made to the document will be saved to the file.

Optional: Because there is a good practice to have a well maintained repo, you could also do everything in a branch which we will merge after a code review is done.

Conclusion: By doing few normal merges, I was able to merge two repositories together into the master curriculum repo and make it look like it was that way all along while avoiding headaches using submodules or subtree merges.

--

--

Eva Gabriela Zamudio

Creator, New Mama, Software Engineer 👩‍💻, entrepreneur, community builder & advocate for women’s empowerment 💪🏽 🙋‍♀️