Git: configurar um controle remoto somente de busca?


132

Quando executo git remote -vem um dos meus repositórios Git que possui um (s) controle (s) remoto (s) configurado (s), vejo que cada controle remoto possui especificações de busca e envio:

$ git remote -v
<remote-name> ssh://host/path/to/repo (fetch)
<remote-name> ssh://host/path/to/repo (push)

Para controles remotos que apontam para desenvolvedores de mesmo nível, não há necessidade de enviar por push, e o Git se recusará a enviar para um repositório não-nua de qualquer maneira. Existe alguma maneira de configurar esses controles remotos como "somente busca" sem endereço de push ou recursos?


4
@sehe, não, você não pode. Com nenhum URL push especificado, os pushs usarão o URL de busca.
Yoyo 16/05

Respostas:


191

Não acho que você possa remover o URL de envio. Você pode substituí- lo por algo diferente do URL de recebimento. Então, acho que o mais próximo que você vai chegar é algo assim:

$ git remote set-url --push origin no-pushing
$ git push
fatal: 'no-pushing' does not appear to be a git repository
fatal: The remote end hung up unexpectedly

Você está configurando o URL push como no-pushing, que, desde que você não tenha uma pasta com o mesmo nome no seu diretório de trabalho, o git não poderá localizar. Você está essencialmente forçando o git a usar um local que não existe.


14
Sim, você pensaria que "git remote set-url --delete --push. *" Faria o truque, mas se você excluir o URL de envio, o padrão será o URL de busca.
Yoyo 16/05

6
Pessoalmente, prefiro usar algo como ' DISALLOWED ', mais visível. Mas isso é apenas uma questão de gosto.
Pierre-Olivier Vares

@ Pierre-OlivierVares Que tal 'DONTPUSH' ?! :)
Ali Shakiba

Para sua informação, depois de fazer isso, o arquivo de configuração do git deve ficar assim: (Observe a nova opção pushurl ) [remote "origin"] fetch = + refs / heads / *: refs / remotes / origin / * url = ssh: // host / path / to / repo pushurl = ssh: // host / no-push / repo #
jaywilliams

1
Assim como @ Pierre-OlivierVares, eu fui com git remote set-url --push origin -- --read-only--- observe o extra --para permitir um nome com traços à esquerda. Isso me pareceu mais legível.
Lindes

13

Além de alterar o URL de envio para algo inválido (por exemplo, git remote set-url --push origin DISABLED), também é possível usar o pre-pushgancho.

Uma maneira rápida de parar git pushé fazer o link simbólico /usr/bin/falsepara ser o gancho:

$ ln -s /usr/bin/false .git/hooks/pre-push
$ git push
error: failed to push some refs to '...'

O uso de um gancho permite um controle mais refinado dos impulsos, se desejado. Veja .git/hooks/pre-push.sampleum exemplo de como evitar o envio de confirmações de trabalho em andamento.

Para impedir o envio para um ramo específico ou limitar o envio para um único ramo, isso é um exemplo de gancho:

$ cat .git/hooks/pre-push
#!/usr/bin/sh

# An example hook script to limit pushing to a single remote.
#
# This hook is called with the following parameters:
#
# $1 -- Name of the remote to which the push is being done
# $2 -- URL to which the push is being done
#
# If this script exits with a non-zero status nothing will be pushed.

remote="$1"
url="$2"

[[ "$remote" == "origin" ]]

Um repositório de teste com vários controles remotos:

$ git remote -v
origin  ../gitorigin (fetch)
origin  ../gitorigin (push)
upstream        ../gitupstream (fetch)
upstream        ../gitupstream (push)

Pressionar para originé permitido:

$ git push origin
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 222 bytes | 222.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ../gitorigin
 * [new branch]      master -> master

Empurrar para qualquer outro controle remoto não é permitido:

$ git push upstream
error: failed to push some refs to '../gitupstream'

Observe que o pre-pushscript do gancho pode ser modificado para, entre outras coisas, imprimir uma mensagem para o stderr dizendo que o envio foi desativado.


Boa ideia! Sem um script mais elaborado, você desativaria o push para todos os controles remotos.
v01pe 11/09/19

1
@ v01pe sim. Atualizei a resposta para incluir um exemplo de script. Realmente não é preciso muito para filtrar os push para um único ramo. Um oneliner shell faria.
Rodolfo Carvalho

4

A declaração geral "O Git se recusará a enviar para um repositório não-nua" não é verdadeira. O Git se recusará a enviar por push para um repositório remoto não-nu se você estiver tentando enviar alterações que estão na mesma ramificação que o diretório de trabalho com check-out do repositório remoto.

Esta resposta fornece uma explicação simples: https://stackoverflow.com/a/2933656/1866402

(Estou adicionando isso como resposta, porque ainda não tenho reputação suficiente para adicionar comentários)


um repositório vazio não possui diretório de trabalho com check-out, por definição. Você pode empurrar para um ramo específico nele.,
Ed Randall

1

Se você já possui uma configuração remota e apenas deseja impedir que faça algo acidentalmente pressionando diretamente para masterou release/production, pode impedir esse uso git config.

# prevent pushing to branch: master
$ git config branch.master.pushRemote no_push

# prevent pushing to branch: release/production
$ git config branch.release/production.pushRemote no_push

Para o registro, no_pushnão é um nome especial. É apenas o nome de qualquer ramo inexistente. Então você poderia usar $ git config branch.master.pushRemote create_a_pr_and_do_not_push_directly_to_mastere funcionaria muito bem.

Mais informações: git-config pushRemote


0

Se você tiver controle sobre o repositório, poderá conseguir isso usando permissões. O usuário que está buscando o repositório não deve ter permissões de gravação no repositório principal.


Se você não pode modificar os arquivos, também não pode buscar novas alterações.
Apenas um aluno
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.