Archive

Posts Tagged ‘push’

Tao of Git Submodules 2

November 3rd, 2010 subogero Comments off

During my exploits to spread the Gospel of git-managed websites, once a great crisis broke out. A user threatened me he would return to MKS Source Integrity.

Now, such an event would shake the foundations of the entire Open Source Free Software movement. Richard Stallman would put sackcloth upon his loins. Linus Torvalds would rend his clothes. I would mourn for many days and my soul would refuse to be comforted.

Time to do something. Or rather, time to think.

I had actually been wondering, why Git’s submodule interface is so inconsistent. There is a –recursive clone, but there is no recursive option for any other remote operation. And then I was enlightened. Of course

There Is No Recursive Push

How could there be? The entire concept of submodules is based on universally read-accessible subprojects inserted into your superproject. You reuse one from gnu.org, another from the Moon, and some from Alpha Centauri. Write access for these is not guaranteed, it’s the privilege of a chosen few.

So what to do with your git-managed remote website? There are two options.

1. The remote repo has a detached worktree (repo in ~, website in /var/www)

Set up remotes and server-side post-receive hooks to check out for the subprojects.
You may want to add a pre-commit hook to the superproject pushing the submodules first.

2. The remote repo is in the website worktree

Add “git submodule update” to the post-update hook on the server side.
This assumes the server is able to access the submodule URLs.

Categories: Uncategorized Tags: , ,

I am a Webmaster

September 27th, 2010 subogero Comments off

It happened that I had to put together a few html pages containing important info about a certain project at the company. Originally I stored them on a Samba share on the official Windows file-server. I turned out to be terrible. For instance Firefox needs FIVE slashes after the protocol-id in the URL:

file://///server/share/page.html

IE needs two, Chrome needs four. First step in the downward spiral: I need the http protocol, in other words a webserver. So I installed Cygwin’s lighttpd on our constantly running desktop box. Then moved the html files to “/srv/www/htdocs/site/”. First step done.

Next step: it’s very cumbersome to change the navigation links, whenever a new page is added. Time to automatize. Tools: SSI (server side includes) and CGI scripts in Perl.

Then, what about setting up a few mailing lists. No archiving, just free subscribing and sending mail via “mailto:” links. One day job in Perl.

Later SSI turned out to be a bad choice as you need an absolute path to your CGI script. Difficult if you want a test-site. So I rewrote the entire site that all links actually refer to the same CGI script which loads the required page, adding dynamic navigation.

The trickiest and nicest part is managing the website with git. On the server I set up a git repo in my home folder, with a detached worktree in “/srv/www/htdocs/site”:

server ~$ mkdir site.git && cd site.git
server ~/site.git$ git --bare init
server ~/site.git$ git config core.worktree '/srv/www/htdocs/site'
server ~/site.git$ git config receive.denycurrentbranch false

Additionally, we need a hook routine which checks out anything to the website whenever you push it into this repo:

server ~/site.git$ mv hooks/post-receive.sample hooks/post-receive
server ~/site.git$ mcedit hooks/post-receive
# checkout the received branch to the website
read OLD NEW REF
git checkout -f $RE

On my own machine, I also have a git repo to manage the site. To allow easy server-updates, I did this:

mybox ~/site$ git remote add web ssh://server/~/site.git
mybox ~/site$ git push web master

Finally, one wants a test-site. Lighty endeavours to give satisfaction, so simply enable module mod_userdir in /etc/lighttpd/lighttpd.conf, and each user’s public_html folder becomes his own website. The two lines below now refer to the same folder:

/home/foo/public_html/
http://server/~foo/

Let’s create a non-bare repo here and configure it to receive and automatically check out pushed commits:

server ~/public_html$ mkdir site && cd site
server ~/public_html/site$ git init
server ~/public_html/site$ git config receive.denycurrentbranch false

I applied the same post-receive hook as with the official website’s repo. But it refused to check out the pushed commits. After a considerable amount of cursing it turns out the bloody git runs the hooks in the “.git” folder. I discovered this when I found all my html files there. So the post-receive hook should look like this in a non bare repo:

#!/bin/sh
unset GIT_DIR
unset GIT_WORK_TREE
cd ..
read OLD NEW REF
REF=`echo $REF | sed 's:refs/..*/::'` # branch instead of detached head
git checkout -f $REF

On my box I added an other remote to allow pushing to the test site:

mybox ~/site$ git remote add test ssh://server/~/public_html/site
mybox ~/site$ git push test master

I even applied a post-commit hook on the local machine which pushes master-commits to the official site and branch-commits to the test site.