Capaz de passar para todos os controles remotos git com o único comando?

194

Em vez de fazer:

git push origin --all && git push nodester --all && git push duostack --all

Existe uma maneira de fazer isso com apenas um comando?

Obrigado :)

Balupton
fonte
1
Veja também: stackoverflow.com/q/5620525/223092
Mark Longair
Para criar um allcontrole remoto para empurrar em todos os seus controles remotos ver: stackoverflow.com/a/18637593/802365
Édouard Lopez

Respostas:

252

Para enviar todas as ramificações para todos os controles remotos:

git remote | xargs -L1 git push --all

Ou se você deseja enviar uma ramificação específica para todos os controles remotos:

Substitua masterpelo ramo que deseja empurrar.

git remote | xargs -L1 -I R git push R master

(Bônus) Para criar um alias para o comando git:

git config --global alias.pushall '!git remote | xargs -L1 git push --all'

A execução git pushallagora enviará todos os ramos para todos os controles remotos.

fraco
fonte
1
Solução muito boa e simples. BTW, você pode usar xargs -l em vez de -L 1, a opção -l é a mesma que -L 1. Além disso, às vezes eu adiciono --all ao push do git. remoto git | xargs -l git empurrar --all
Tony
2
Eu entro xargs: illegal option -- lno OSX. Descobri-lo, você precisagit remote | xargs -L1 git push
balupton
4
O Git permite que você faça essa chamada em um comando personalizado. Basta colocá-lo em um arquivo que 1) está no seu caminho, 2) você tem permissões para executar e 3) chamado "git- [nome personalizado]" (por exemplo, git-foo, git-push-all) e você simplesmente digite "git [nome personalizado]" (por exemplo, git foo, git push-all).
Andrew Martin
2
@ Tony No Ubuntu, man xargsdiz que a opção -lestá obsoleta, pois não está na especificação POISX.
precisa saber é o seguinte
2
@kyb Na sintaxe do git alias, !significa que o seguinte não é um comando interno do git, mas um comando externo do shell.
weakish
285

Crie um allcontrole remoto com vários URLs de repo para o seu nome:

git remote add all origin-host:path/proj.git
git remote set-url --add all nodester-host:path/proj.git
git remote set-url --add all duostack-host:path/proj.git

Então apenas git push all --all.


É assim que fica .git/config:

  [remote "all"]
  url = origin-host:path/proj.git
  url = nodester-host:path/proj.git
  url = duostack-host:path/proj.git
Aristóteles Pagaltzis
fonte
5
Truque super legal! A única desvantagem é que ele não move cabeças remotas. Você precisa correr git fetch --alllogo após fazer esse empurrão.
madhead
8
Torvalds (criador do Git) menciona que ele usa esse método, mas afirma que é apenas por conveniência e não oferece nenhuma vantagem técnica marc.info/?l=git&m=116231242118202&w=2 "E no final, até mesmo um" O git push all "que envia para vários repositórios acabará realmente se conectando uma vez para cada repositório; portanto, é apenas uma abreviação para executar vários" git push "es. Não há nenhuma vantagem técnica real, apenas uma conveniência."
Matt
14
Um problema com essa abordagem é que você precisa adicionar novos URLs ao allcontrole remoto à medida que estiverem disponíveis, ao passo git remote | xargs -L1 git push --allque selecionará automaticamente novos controles remotos.
Raffi Khatchadourian 05/05
2
Dica: Para não precisar digitar allsempre que você enviar um commit, basta usar "origin" em vez de "all":git remote set-url --add origin nodester-host:path/proj.git
Macabeus
esqueceu de definir os URLs de envio, caso contrário git pushnão atualizará todos os URLs. resposta atualizada em conformidade
user3338098
88

Se você deseja sempre pressionar repo1, repo2 e repo3, mas sempre puxar apenas do repo1, configure a 'origem' remota como

[remote "origin"]
    url = https://[email protected]/path/to/repo1
    pushurl = https://[email protected]/path/to/repo1
    pushurl = https://[email protected]/path/to/repo2
    pushurl = https://[email protected]/path/to/repo3
    fetch = +refs/heads/*:refs/remotes/origin/*

Configure na linha de comando:

$ git remote add origin https://[email protected]/path/to/repo1
$ git remote set-url --push --add origin https://[email protected]/path/to/repo1
$ git remote set-url --push --add origin https://[email protected]/path/to/repo2
$ git remote set-url --push --add origin https://[email protected]/path/to/repo3

Se você deseja apenas retirar, repo1mas pressione para repo1e repo2 para um ramo específicospecialBranch :

[remote "origin"]
    url = ssh://[email protected]:7999/yyy/repo1.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...
[remote "specialRemote"]
    url = ssh://[email protected]:7999/yyy/repo1.git
    pushurl = ssh://[email protected]:7999/yyy/repo1.git
    pushurl = ssh://[email protected]:7999/yyy/repo2.git
    fetch = +refs/heads/*:refs/remotes/origin/*
    ...
[branch "specialBranch"]
    remote = origin
    pushRemote = specialRemote
    ...

Consulte https://git-scm.com/docs/git-config#git-config-branchltnamegtremote .

Meng Lu
fonte
4
Não sei por que isso não tem mais votos. Na verdade, isso é realmente conveniente porque permite que você faça um git pushsem argumentos.
Husky
1
Vote em mim, por favor!
Meng Lu
1
Isso me parece uma maneira mais apropriada de fazer isso. Deveria ter tido os votos mais altos.
Ahmad
É muito útil. É possível limitar o pushurl apenas à ramificação principal?
Fbucek
17

Como uma alternativa da CLI para editar o arquivo .git / config, você pode usar os seguintes comandos:

# git remote add all origin-host:path/proj.git
# git remote set-url --add all nodester-host:path/proj.git
# git remote set-url --add all duostack-host:path/proj.git

O mesmo git push all --allfunciona aqui também.

Você realizou o mesmo que a resposta nº 1. Você acabou de fazer isso com a Linha de Comando, em vez da edição bruta do arquivo de configuração.

Kurt Vanderwater
fonte
2

Eu escrevi uma função bash curta para enviar vários controles remotos em uma chamada. Você pode especificar um único controle remoto como parâmetro, vários controles remotos separados por espaços ou não especificar nenhum para que ele seja enviado a todos os controles remotos.

Isso pode ser adicionado ao seu .bashrc ou .bash_profile.

function GitPush {
  REMOTES=$@

  # If no remotes were passed in, push to all remotes.
  if [[ -z "$REMOTES" ]]; then
    REM=`git remote`

    # Break the remotes into an array
    REMOTES=$(echo $REM | tr " " "\n")
  fi

  # Iterate through the array, pushing to each remote
  for R in $REMOTES; do
    echo "Pushing to $R..."
    git push $R
  done
}

Exemplo: digamos que seu repo tenha 3 controles remotos: rem1, rem2 e rem3.

# Pushes to rem1
GitPush rem1

# Pushes to rem1 and rem2
GitPush rem1 rem2

# Pushes to rem1, rem2 and rem3
GitPush
KeyboardCowboy
fonte
0

Você pode utilizar ganchos do git - especialmente pre-push: adicione toques de não origem ao .git/hooks/pre-push.

Vitaly Zdanevich
fonte