6

I have a big private repository which is maintained on a local network. I'd like to automatically push a subtree of that repository outside of that network. I need it to be simple:

*Task* someone pushes to local remote repository --> a subtree is automatically pushed to some other repository

I am not sure if this could be achieved with a server side hook because AFAIK there is no such thing as pushing subtrees from bare remotes. I came up with two ideas:

  • I could clone the remote on the server and automatically split the subtree in the cloned remote. This doesn't really help because I don't know how to auto-pull the subtree (others also have this problem).
  • Another idea is to write a custom client-side post-commit-hook and make every user install it, but this is terrible, isn't it? Git book specifically states that policies should be enforced on server side.

Is there a simple way of achieving something like this? Or is this impossible and it's just git abuse?

jjj
  • 1,067
  • 1
  • 15
  • 30
  • You can push from a post-receive hook on a bare remote repository to another remote repo, so what's the problem? – wrzasa Oct 13 '17 at 09:09
  • @wrzasa hey, thanks for asking. Maybe I didn't make this part clear enough: can you push *subtrees* from bare remotes? I thought, since there is no such thing as a working tree on a bare remote, you can't really specify a subtree. E: I edited the question to make it clear – jjj Oct 13 '17 at 09:17
  • 1
    Didn't use subtrees, but you can always in your hook checkout your repo to a temp dir and then do whatever you need. – wrzasa Oct 13 '17 at 09:34
  • @wrzasa Thanks, I didn't know that. I'll give it a try. – jjj Oct 13 '17 at 09:49
  • Good luck! Here you have some hook examples: https://www.digitalocean.com/community/tutorials/how-to-set-up-automatic-deployment-with-git-with-a-vps – wrzasa Oct 13 '17 at 10:16

1 Answers1

3

Umm, I'm a bit embarrassed. Apparently this was much easier than I thought. Here is a hasty solution which builds on @wrzasa suggestion:

  1. Clone your repository on the server to which you are pushing, like this (dir.git is a bare repo):

    .
    |- dir.git
    |- dir
    
  2. In dir do: git remote add <remote-name> <remote-address>

  3. In dir.git/hooks/post-receive put:

    #! /bin/bash
    unset GIT_DIR
    cd ../dir
    git pull ../dir.git
    git subtree split --prefix=<subdir-in-dir> --branch=<branch-name>
    git push <remote-name> <branch-name>
    

    Remember to make post-receive executable. See this answer if you wanna know why unset GIT_DIR is needed.

That's pretty much it. Now whenever someone pushes to dir remote (i.e. dir.git) subtree under <subdir-in-dir> will be pushed to <remote-name>.

jjj
  • 1,067
  • 1
  • 15
  • 30
  • from `git subtree --help`: _--branch= [...] must not already exist_ So I suppose You have to delete at the end of the hook procedure; am I right? – ardabro Jul 13 '18 at 20:23
  • @ardabro I don't see the line you are referring to in the documentation. Which version of git are you using? Also tbh I ended up with a different version of the hook in which it basically pulls from the bare repo and then does `git subtree push --prefix= `. – jjj Jul 16 '18 at 12:02