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
README
in 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
-
Fetch the
master
branch 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
subproject
that contains themaster
branch of thesecondary-repo
. -
(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
subproject
branch into themaster
branch: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 subproject
.
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 – primary
and 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:
Tags: git