Thursday, June 7, 2012

Push One Git Branch To A Different Server

I have a Github repository, for a library, with two branches on github: master and custom. I then have a third branch, which is application code (including information such as passwords) that I don't want to go on Github. I want to put that 3rd branch on another server.

Before I started my .git/config looked like:

        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
    [remote "upstream"]
        url =
        fetch = +refs/heads/*:refs/remotes/upstream/*
    [branch "master"]
        remote = upstream
        merge = refs/heads/master
    [remote "origin"]
        url =
        fetch = +refs/heads/*:refs/remotes/origin/*

git branch tells me

    * application

As in my previous article on setting up a remote git repository, I'll assume three machines are involved:
  • devel: where most development is done
  • store: the central repository server
  • www: the web server, where I want to checkout the branch

So, first is preparation. On store:
    cd /var/git/
    mkdir phirehose.git
    cd phirehose.git
    git init --bare

Next create an alias for it on devel:
    git remote add application store:/var/git/phirehose.git/
(Note: "store" is in my ssh config: it is an alias that covers server URL, username, port, etc.)

Then (still on devel machine) I need to type:
    git config push.default current

Now check that worked by typing 'git remote -v'
    origin (fetch)
    origin (push)
    application    store:/var/git/phirehose.git/ (fetch)
    application    store:/var/git/phirehose.git/ (push)

    upstream (fetch)
    upstream (push)

And in .git/config these lines will have been appended at the end:
    [remote "application"]
        url = store:/var/git/phirehose.git/
        fetch = +refs/heads/*:refs/remotes/application/*
        default = current

Now I can upload the branch with:
    git push application

Rush over to 'store' server, and you should see the files in /var/git/phirehose.git/

Now we need to do a quick fix; I'm going to go out on a limb and say this is a git bug. But, anyway, if you look inside the HEAD file you see:
    ref: refs/heads/master

But refs/heads/master does not exist! Edit HEAD so it looks like:
    ref: refs/heads/application

Now you can go to your 'www' machine and do a "git clone" command.
On your 'www' machine if you type git branch you will see just:
   * application

One last thing. Now you have 2+ remote repositories, on your 'devel' machine, I recommend you type:
    git config push.default nothing

This means that git push will no longer work: you always have to specify what you want to push. This is a safety catch to prevent you pushing application to the public GitHub. (I did, and there is no way back, so my only choice was to delete the entire GitHub repository!) So, when I'm in the application branch and I want to push to store I type:
         git push application HEAD

See this StackOverflow thread for some background (including a note that default git behaviour might change from 1.7.10+)

No comments: