F=partialcopy maintaining a partial copy of a repo

The regular documentation on basic access control mentions [here][rpr_] that it is easy to maintain two repositories if you need a (set of) branch(es) to be "secret", with one repo that has everything, and another that has everything but the secret branches.

Here's how gitolite can help do that sanely, with minimal hassles for all concerned. This will ensure the right branches propagate correctly when people pull/push -- you don't have to do anything manually after setting it up unless the rules change.

To start with, here's a NON-WORKING config that merely describes what we're trying to achieve:

                # THIS WILL NOT WORK!
repo foo
        -   secret-1$       =   wally
        RW+ dev/USER/       =   wally
        RW+                 =   dilbert alice ashok wally

We want Wally the slacker to not be able to see the "secret-1" branch.

The only way to do this is to have two repos -- one with and the other without the secret branch.

These two repos cannot share git objects (to save disk space) using hardlinks etc. Doing so would cause a data leak if Wally decides to stop slacking and start hacking. See my conversation with Shawn here for more on this, but it basically involves Wally finding out the SHA of one of the secret branches, pushing a branch that he claims to have built on that SHA, then fetching that branch again.

It requires a serious understanding of the git transport protocol, how objects are sent/received, how thin packs are created, etc., to implement it. Or to convince yourself that someone's implementation is correct.

Meanwhile, the method described here, once you accept the disk space cost, is quite understandable to mere mortals like me :-)

In the above example you had 2 sets of read access -- (1) all branches (2) all branches except secret-1. If you end up with one more set (say, "all branches except secret-2") then you need one more repo to handle it. If you can afford the storage, the following recipe can certainly make it manageable.

first, as usual, the caveats!

the basic idea

The basic idea is very simple.

The main repo is always the canonical/current one. The others may or may not be uptodate.

the config file

Here's what we actually need to put in the config file. Note that the reponames can be whatever you want of course.

repo foo
        RW+                 =   dilbert alice ashok

repo foo-partialcopy-1
        -   secret-1$       =   wally
        R                   =   wally
        RW+ dev/USER/       =   wally

        config gitolite.partialCopyOf = foo

Important notes:

the hooks

The code for both hooks is included in the source directory contrib/partial-copy. Note that this is all done without touching gitolite core at all -- we only use two hooks; both described in the [hooks][] section. A pictorial representation of all the stuff gitolite runs is [here][flow]; it may help you understand the role that these two hooks are playing in this scenario.