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?

mtbkrdave
fonte
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.

Daniel Brockman
fonte
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.

Rodolfo Carvalho
fonte
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)

pkeller
fonte
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

PaulMest
fonte
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.

Abhilash
fonte
Se você não pode modificar os arquivos, também não pode buscar novas alterações.
Apenas um aluno