Search code examples
gitgitorious

git intermediary repository ( as a proxy to another)


Is is possible to have a git repository ( clonable and pushable) be itself a clone of another remote repo?

The scenario:

We have an installation of gitorious for our company's git hosting. We want to keep it updated but add some very private features ( mostly deploy scripts), hence the need to a pushable project. The desired workflow would be:

  • create a mygitorous as a pushable git repo
  • clone gitorious-official into mygitorious (not as submodule, as ref)
  • users now can clone and push mygitorious
  • I can then merge mygitorious with gitorious-official to update from upstream
  • I can update my deployed clone
  • users can update their clones with merged version

PS. Since these deploy scripts are very sensitive, I cannot simply make a public clone in gitorious and use it.


Solution

  • Sure. The whole idea behind a distributed version control system like git is that no repository is "special". Any repository can be a clone of or destination of zero, one, or more other repositories.

    For example, assuming I have a repository repo1.git, I can do this:

    $ git clone --bare repo1.git repo2.git
    $ git clone repo2.git repo3
    $ cd repo3
    $ ...make some changes and commit...
    $ git push
    $ cd ../repo2.git
    $ git push
    

    If you follow that along, you can see I pushed repo3 --> repo2, and then repo2 --> repo1.

    Responding to your comment:

    You can't run git checkout in a bare repository. That's what fatal: This operation must be run in a work tree means. When you git clone a repository, you get two things:

    • A copy of the repository, contained in a .git directory, and
    • A "working copy", or "work tree", which is a directory containing the checked-out copies of files in the repository. A number of commands (checkout, pull) only make sense when you're interacting with the working copy.

    Note, however, that it is tricky to push into a non-bare repository (that is, a repository with an associated working tree); git will throw an error without explicit configuration. You would see something along the lines of:

    To /home/lars/tmp/so/repo
     ! [remote rejected] foo -> foo (branch is currently checked out)
    error: failed to push some refs to '/home/lars/tmp/so/repo'
    

    This is because it would be surprising to have changes happening inside the repository underneath your working tree if other people were pushing into it. You can read more in this answer.