Git Tip: Quickly Merging in a Side Project Repo
The code of the filter in my older post about EAC and UTF-8 entries in freedb has evolved into a small helper utility for another project. At some point I decided to merge the Git repo containing that helper into the repo of that new project. The collective wisdom of the Internet says to use submodules or subtree merges in such a situation, but I have found a less complicated solution that worked for me (Credit goes to Dave O’Neil.)
Specifically, if you only want to retain the history of the master branch of the secondary repo, simply fetch that branch under a different name into the main project repo, and then merge it as you would merge a normal branch:
- Make sure the secondary repo is in good state – no postponed merges or uncommitted changes to the master branch.
Make sure no untracked files in the working directory of the primary repo are conflicting with files in the secondary repo. Having e.g. a
READMEin the root of both repos is okay, provided you do not skip the optional step below.
Create a backup of the primary repo. You may also wish to try the below steps on a temporary clone first:
git clone main-project-url temp-clone-directory
masterbranch from the secondary repo into the main project:
cd main-project-directory git fetch secondary-repo-url master:subproject
Now in the current repository there is a branch
subprojectthat contains the
masterbranch of the
(Optional) If required, checkout that branch and move files to an appropriate location to avoid conflicts:
git checkout -f subproject mkdir subproject-directory git mv subproject-files subproject-directory git commit -a -m "Moved subproject to a separate directory before merge" git checkout -f master
Now merge the
subprojectbranch into the
git merge subproject
If you get a merge conflict message, you must have skipped the previous step. Ensure that files of the secondary project reside in a separate directory not present in the primary project.
Now the history of the
master branch of your subproject is part of history of the main project as if you had been working on it in a separate branch called
Here is a small script illustrating the process:
#!/bin/bash [ -d primary ] && rm -fr primary [ -d secondary ] && rm -fr secondary mkdir primary mkdir secondary cd primary git init echo Primary >README git add . git commit -a -m 'Initial commit to primary' cd .. cd secondary git init echo Secondary >README git add . git commit -a -m "Initial commit to secondary" cd .. cd primary git fetch ../secondary master:secondary git checkout secondary mkdir secondary git mv README secondary git commit -a -m "Moved secondary to a separate directory before merge" git checkout -f master git merge secondary git log --graph
As you may see, the script creates two subdirectories –
secondary, initializes a git repo in each of them, commits
README files to those repos, and fetches the
master branch from the secondary repo into the primary one under the name “
secondary“. A merge attempt at this point would result in a conflict because both branches contain a file
README in their roots. So the script moves the fetched file into a new subdirectory before the merge.
Here is how the log of the
primary project looks in TortoiseGit now: