I’m trying to work out a method to port code between two disconnected environments using Git. Code will be edited in both locations before being merged together for releases. Ideally, I’d like to export the “master” branch from one location (A) and then add it to a repository in another location (B) as a “remote-dev” branch. After that, changes in the “remote-dev” branch can be merged into the “master” branch of the second location (B) for release preparation. This transfer would be repeated periodically so the desire is to be able to overlay “remote-dev” with updated code and have the history still preserved and still allow for merges up to “master” without having to remerge code that was previously merged. Also, only the “master” branch should be brought over from environment A as there will be many other branches with active development present that should not be copied.
The goal here is for an automated, repeatable process. I’d like to be able to setup a batch file which does the export of a branch in environment A each night. Someone will copy the files over to environment B and place them in a drop-off location. Another batch file will be scheduled to run in environment B which picks up the files and merges them into the destination repository in environment B.
There are good details in both "How do you merge two Git repositories?" and "How to import existing Git repository into another?". Unfortunately, neither seems to cover the repeatability aspect that I’m looking for.
Both discussions mention “git merge” and “git subtree add” as possible solutions here for grating a branch into a different repository. However, neither covers the repeatability aspect of it. Would it be necessary to delete the destination branch before re-merging or can the imported branch be merged over the top of a previous import? Also, should any special steps be taken to export out only the “master” branch from environment A to avoid any excess data being moved between environments?
Has anyone tried something like this with success?
You describe the environments as "disconnected". I assume you mean that you cannot add one repo as a remote of the other. The solution for that is to use git bundle
.
At repo 1, you create a bundle file. You will specify that you want the bundle created from master
s history.
If you want, you can also make the bundles incremental by specifying a "starting point" for the bundle. By this I mean, you can say "if you're going to import this bundle, you must already have commit ABC, because that's the parent commit of the first commit in the bundle".
On the receiving end, you add the bundle file as though it were a remote, and then you can fetch
from it and merge the resulting refs, or pull
from it, or whatever. Just like a remote. The only thing is you don't push
to the bundle. Instead you create your own bundle to send back.
So that removes the "disconnected" aspect from the picture.
If you want to bundle up master
and then have it received as remote-dev
, you could use a refspec when you fetch from the bundle; or you could go ahead and fetch it as remote-dev/master
and then track that with a local branch called rmeote-dev
; or any number of other variations.
It's repeatable whether or not you make the bundles incremental, because fetch
always knows that it might already have some of the objects in the history it's fetching.
So now you're just syncing between two long-lived branches, much like the pattern you'd use to take periodic vendor drops or update a fork from its upstream.
As an aside, the above answer assumes you have reasons, apart from the disconnected environment, for wanting the branch workflow you described. The truth is, with bundle files you can work pretty much the same as you would with connected repositories, so if you were assuming the need for a remote-dev branch just to deal with the separation, I wouldn't bother. Distributed development is exactly what git is for.