Können Sie mit einem Befehl auf alle Git-Fernbedienungen zugreifen?

194

Anstatt zu tun:

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

Gibt es eine Möglichkeit, dies mit nur einem Befehl zu tun?

Vielen Dank :)

Balupton
quelle
1
Siehe auch: stackoverflow.com/q/5620525/223092
Mark Longair
Informationen zum Erstellen einer allFernbedienung zum Drücken
Édouard Lopez

Antworten:

252

So schieben Sie alle Zweige zu allen Fernbedienungen:

git remote | xargs -L1 git push --all

Oder wenn Sie einen bestimmten Zweig auf alle Fernbedienungen übertragen möchten:

Ersetzen Sie ihn masterdurch den Zweig, den Sie verschieben möchten.

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

(Bonus) So erstellen Sie einen Git-Alias ​​für den Befehl:

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

Durch das Ausführen git pushallwerden nun alle Zweige zu allen Fernbedienungen verschoben.

schwach
quelle
1
Sehr gute und einfache Lösung. Übrigens können Sie xargs -l anstelle von -L 1 verwenden. Die Option -l ist dieselbe wie -L 1. Außerdem füge ich manchmal --all zum Git-Push hinzu. git remote | xargs -l git push --all
Tony
2
Ich steige xargs: illegal option -- lauf OSX. Ich habe es herausgefunden, du brauchstgit remote | xargs -L1 git push
Balupton
4
Mit Git können Sie diesen Aufruf in einen benutzerdefinierten Befehl umwandeln. Fügen Sie es einfach in eine Datei ein, die 1) auf Ihrem Pfad ist, 2) für die Sie Ausführungsberechtigungen haben und 3) "git- [benutzerdefinierter Name]" (z. B. git-foo, git-push-all) heißt, und Sie werden Sie können einfach "git [benutzerdefinierter Name]" eingeben (z. B. git foo, git push-all).
Andrew Martin
2
@Tony Unter Ubuntu man xargsheißt es , dass die Option -lveraltet ist, da sie nicht in der POISX-Spezifikation enthalten ist.
Wjandrea
2
@kyb In der Git-Alias-Syntax !bedeutet Folgendes, dass es sich nicht um einen internen Git-Befehl handelt, sondern um einen externen Shell-Befehl.
schwächer
285

Erstellen Sie eine allFernbedienung mit mehreren Repo-URLs zu ihrem Namen:

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

Dann einfach git push all --all.


So sieht es aus .git/config:

  [remote "all"]
  url = origin-host:path/proj.git
  url = nodester-host:path/proj.git
  url = duostack-host:path/proj.git
Aristoteles Pagaltzis
quelle
5
Super cooler Trick! Der einzige Nachteil ist, dass es keine entfernten Köpfe bewegt. Sie müssen git fetch --alldirekt nach einem solchen Push laufen .
Madhead
8
Herr Torvalds (Schöpfer von Git) erwähnt, dass er diese Methode verwendet, gibt jedoch an, dass sie lediglich der Bequemlichkeit dient und keinen technischen Vorteil bietet. Marc.info/?l=git&m=116231242118202&w=2 "Und am Ende sogar eine" git push all "Wenn Pushs an mehrere Repositorys gesendet werden, wird die Verbindung für jedes Repository tatsächlich einmal hergestellt. Es ist also nur eine Abkürzung für mehrere" Git Pushs ". Es gibt keinen wirklichen technischen Vorteil, nur eine Annehmlichkeit."
Matt
14
Ein Problem bei diesem Ansatz besteht darin, dass Sie der allFernbedienung neue URLs hinzufügen müssen, sobald diese verfügbar sind, während git remote | xargs -L1 git push --allneue Fernbedienungen automatisch abgerufen werden.
Raffi Khatchadourian
2
Tipp: allWenn Sie beim Senden eines Commits keine Eingabe benötigen, verwenden Sie einfach "origin" anstelle von "all":git remote set-url --add origin nodester-host:path/proj.git
Macabeus
Ich habe vergessen, die Push-URLs festzulegen, da sonst git pushnicht alle URLs aktualisiert werden. Antwort entsprechend aktualisiert
user3338098
88

Wenn Sie immer auf repo1, repo2 und repo3 pushen möchten, aber immer nur auf repo1 ziehen möchten, richten Sie den Remote-Ursprung als ein

[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/*

In der Befehlszeile konfigurieren:

$ 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

Wenn Sie nur von einem bestimmten Zweig ziehen, repo1aber zu repo1und repo2 für einen bestimmten ZweigspecialBranch drücken möchten :

[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
    ...

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

Meng Lu
quelle
4
Ich bin mir nicht sicher, warum dies nicht mehr Stimmen hat. Dies ist eigentlich sehr praktisch, da Sie damit einfach git pushohne Argumente arbeiten können.
Husky
1
Stimmen Sie bitte für mich ab!
Meng Lu
1
Dies scheint mir angemessener zu sein. Hätte die höchsten Stimmen haben sollen.
Ahmad
Es ist sehr nützlich. Ist es möglich, Pushurl nur auf den Hauptzweig zu beschränken?
fbucek
17

Als CLI-Alternative zum Bearbeiten der .git / config-Datei können Sie die folgenden Befehle verwenden:

# 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

Das gleiche git push all --allfunktioniert auch hier.

Sie haben das Gleiche wie Antwort 1 erreicht. Sie haben es gerade mit der Befehlszeile gemacht, anstatt die Konfigurationsdatei roh zu bearbeiten.

Kurt Vanderwater
quelle
2

Ich habe eine kurze Bash-Funktion geschrieben, um in einem Aufruf auf viele Fernbedienungen zuzugreifen. Sie können eine einzelne Fernbedienung als Parameter angeben, mehrere Fernbedienungen durch Leerzeichen getrennt oder keine angeben, damit sie auf alle Fernbedienungen übertragen wird.

Dies kann zu Ihrem .bashrc- oder .bash_profile hinzugefügt werden.

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
}

Beispiel: Angenommen, Ihr Repo verfügt über 3 Fernbedienungen: rem1, rem2 und rem3.

# Pushes to rem1
GitPush rem1

# Pushes to rem1 and rem2
GitPush rem1 rem2

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

Sie können Git-Hooks verwenden - insbesondere pre-push: Fügen Sie Pushs hinzu, die keinen Ursprung haben .git/hooks/pre-push.

Vitaly Zdanevich
quelle