Merging Git repositories

Tags:

Git is an excellent version control system, but it does get complex. On the plus side, it gives you enough power to recover from strange situations.

I had done several modifications to my AutoNav plugin on, basically, an orphan repository. Thanks to Ben Atkin, I now have a copy of the AutoNav repository and history in GitHub, transitioned from WordPress's authoritative Subversion system. However I had done some work in a newly-created repository before that happened, having simply copied the latest source code into it, and wanted to merge the changes into the global repo.

There are several possible ways to do that -- by adding remotes, by merging, by rebasing changes -- but the simplest to understand seems to be using a patch file. Cheers to the folks at Code & Coffee for help this morning with this.

Starting in my little scratchpad orphan repository, I did a git log to see what the very first base revision and the latest were. Then I use these first and last numbers as a range to format-patch, and send the result to a file:

$ <strong>git format-patch bc0ab0..3324c --stdout > 201307-autonav.patch</strong>

OK now let's go to a new directory somewhere and clone the official repo from GitHub into it:

$ <b>git clone https://github.com/lindleyw/autonav.git</b>
Cloning into 'autonav'...
remote: Counting objects: 417, done.
remote: Compressing objects: 100% (219/219), done.
remote: Total 417 (delta 222), reused 392 (delta 197)
Receiving objects: 100% (417/417), 988.36 KiB | 984.00 KiB/s, done.
Resolving deltas: 100% (222/222), done.
$

Now, let's see what will happen if we apply our patchfile (I saved this in a directory called Xgit). This doesn't actually any changes, just gives us some statistics:

$ <strong>git apply --stat ../Xgit/201307-autonav.patch </strong>
 TODO.txt               |   30 +++++
 autonav-widget.php     |  259 +++++++++++++++++++++++++++++++++++++++++++++++
 autonav-wl-options.php |  267 ++++++++++++++++++++++++------------------------
 autonav-wl.php         |   36 ++++--
 readme.txt             |   62 ++++++++++-
 wl-config-form.php     |   75 +++++++++++++
 TODO.txt               |   12 ++
 description            |    1 
 8 files changed, 590 insertions(+), 152 deletions(-)
$

OK that looks good, now let's make sure there are no errors:

$ <strong>git apply --check ../Xgit/201307-autonav.patch</strong>
$

Excellent. We are now using to use the git am command which applies patches from a mailbox, or from mailbox format. We can use the signoff switch to make a record that we approved this:

$ <strong>git am --signoff < ../Xgit/201307-autonav.patch</strong>
Applying: Preview of version 1.5.6
<em>[......]</em>
$ <strong>git status</strong>
# On branch master
# Your branch is ahead of 'origin/master' by 3 commits.
# (use "git push" to publish your local commits)
#
nothing to commit, working directory clean
$ <strong>git push</strong>

And we're done!

Further reading: Git-format-patch (kernel.org); How to create and apply a patch with Git (ariejan.net)