A solução acabou sendo baseada no # 2:
Changing git functionality on the server side, hijacking push commands (called in the git-shell?). I have found no documentation on what takes place on the server side when pushing over SSH so I've not been able to further investigate this possible solution.
Eu encontrei um artigo por "kamalmarhubi" que explicava o que o git push
estava fazendo quando configurado para usar o SSH.
A solução
Configurar - lado do servidor
Adicione um chamado git
:
sudo useradd -m git
Note que o usuário infelizmente não pode usar o git-shell, já que o shell manipula os comandos necessários internamente.
Crie o diretório .ssh
mkdir .ssh
Crie o arquivo authorized_keys
touch .ssh/authorized_keys
Adicione as chaves públicas que você usará como linha ao arquivo authorized_keys
.
Adicione o seguinte ao topo do arquivo .bashrc
do usuário:
function git-receive-pack() {
if [ ! -d $1 ]; then
mkdir -p $1 && cd $1 && git init --quiet --bare && command git-receive-pack $@
fi
}
Configuração - lado do cliente
Execute o seguinte dentro de qualquer repositório git:
git add remote origin git@server:directory
Em que server
é o ip ou o nome do servidor e directory
o caminho para armazenar o repositório em (relativo ao diretório inicial do usuário do git, geralmente /home/git/
).
Uso
Empurrando o código do cliente
Pressione normalmente, o serviço cuidou de inicializar o repositório para você!
Como funciona
Sempre que o Git envia por SSH, ele chama ssh git@server git-receive-pack directory
, ou seja, executa git-receive-pack directory
no controle remoto. Ao usar o git-shell, o comando é tratado internamente. Ao usar um shell regular (bash), o comando é tratado como qualquer outro comando bash. Isso significa que podemos ignorar como o comando funciona, o que fazemos definindo nosso próprio git-receive-pack
in .bashrc
. A definição precisa estar na parte superior do arquivo, pois .bashrc
geralmente aborta a execução se ela for executada em um shell não interativo (como o Git é). O comando que nós definimos verifica se o repositório de destino já existe, se ele não existir, ele o inicializa como um repositório vazio (conforme o padrão Git) antes de executar o original git-receive-pack
, que cuida do envio real. / p>