複数のリモートロケーションからのプル/プッシュ


743

ショート: git repoをリモートリポジトリのリストにプッシュおよびプルする方法はありますか(単一の「オリジン」ではなく)?

長い間:複数のコンピューターでアプリを開発しているときに、接続が異なることがよくあります。たとえば、移動中のラップトップ、特定の場所にいるコンピューター "A"、別のコンピューター "B"などです。別の間に。また、ラップトップは「A」または「B」のいずれか、または両方の接続を備えている場合があります。

私が望んでいるのは、gitが現在接続しているすべてのコンピューターから常に「プル」および「プッシュ」することです。これにより、あるマシンから別のマシンにジャンプしてシームレスに作業を続けることが容易になります。


39
新しい訪問者のためのノート、2016年のように:これを行うには、現在、正しい方法、ファーストクラスのによって認可git機能は、中に含まれているmalvineous下の答え。受け入れられた答えは正しくありません。
ELLIOTTCABLE 2016

@Zorzella:これに関する承認済みの回答を更新できますか?それは、現在の方法と少し混乱しています。
ntninja

回答:


503

git remote次のコマンドを使用して、複数のリモートリポジトリを構成できます。

git remote add alt alt-machine:/path/to/repo

構成されたすべてのリモートからフェッチして追跡ブランチを更新するが、にはマージしないHEAD場合は、次のようにします。

git remote update

現在いずれかのリモートに接続されていない場合は、タイムアウトになるかエラーがスローされ、次のリモートに進みます。cherry-pick変更を収集する方法に応じて、フェッチしたリポジトリから手動でマージする必要があります。

altからmasterブランチをフェッチして現在のヘッドにプルするには、次のようにします。

git pull alt master

したがって、実際にgit pullはほぼ省略形ですgit pull origin HEAD(実際には、これを判別するために構成ファイルを調べますが、アイデアはわかります)。

更新をプッシュするには、それを各リポジトリに手動で行う必要があります。
プッシュは中央リポジトリのワークフローを念頭に置いて設計されたと思います。


つまり、「git remote add foo ssh://foo.bar/baz」は省略形を作成しますが、それでも「git pull」でループするか、「git」でループする必要がありますマージ」(「git remove update」の後の構文は何ですか?)この省略名は「git push」でも機能しませんか?つまり、 "git push foo"など(ループ)できないのでしょうか。ありがとう
Zorzella 2009年

8
「git pull」は基本的に「git fetch」の後に「git merge」が続きます。「git remote update」は、一連の「git fetch」呼び出しを実行するだけです。残りは「git merge」ビットを実行することです。「git merge origin / master」と言うと、マスターのoriginのバージョンが現在のHEADにマージされます。「git pull origin master」も同じことを行いますが、最初にフェッチを実行します(すでにgitリモート更新を実行している場合は、フェッチするものがないため、冗長です)。はい、「git push foo」と言うと、一致するすべてのブランチが「foo」というリモートにプッシュされます。
araqnid 2009年

IIUCあなたは作業リポジトリにプッシュできません(結局、互換性のない/期待されていない/不要な変更をプッシュする可能性があります)。ベアリポジトリにプッシュする必要があり、プルするときにのみ更新を受け取ります。したがって、ソリューションには、各マシン上で動作するリポジトリとベアリポジトリが必要ですか?
joeytwiddle 2013年

2
どうやらあなたはまた、いくつかのレポ取引のための1つのプッシュを持っている詳細については、この答えを確認することができますstackoverflow.com/questions/14290113/...
manei_cc

797

最新バージョンでは、これを手動で行う必要はありませんgit。以下のMalvineousのソリューションを参照してください。

ここで再現:

git remote set-url origin --push --add <a remote>
git remote set-url origin --push --add <another remote>

元の答え:

これは私がかなり長い間使用してきたもので、悪い影響はなく、Linus Torvaldsがgitメーリングリストで提案しました。

araqnidのソリューションは、コードリポジトリに取り込むための適切なソリューションです...しかし、私と同じように、同等の権威のあるアップストリームが複数ある場合(私はより重要なプロジェクトのいくつかをプライベートアップストリーム、GitHub、およびCodasetの両方に複製します)毎日それぞれに変更をプッシュするのは面倒です。

簡単に言えば、git remote addすべてのリモコンを個別に…そしてgit config -e、マージされたリモートを追加します。このリポジトリがあると仮定しますconfig

[remote "GitHub"]
    url = git@github.com:elliottcable/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/GitHub/*
[branch "Master"]
    remote = GitHub
    merge = refs/heads/Master
[remote "Codaset"]
    url = git@codaset.com:elliottcable/paws-o.git
    fetch = +refs/heads/*:refs/remotes/Codaset/*
[remote "Paws"]
    url = git@github.com:Paws/Paws.o.git
    fetch = +refs/heads/*:refs/remotes/Paws/*

…とのマージされたリモートを作成するため"Paws""Codaset"、これらすべての後に以下を追加できます。

[remote "Origin"]
    url = git@github.com:Paws/Paws.o.git
    url = git@codaset.com:elliottcable/paws-o.git

これを実行したら、を実行するとgit push Origin Master、両方Paws/MasterCodaset/Master順次にプッシュされ、人生が少し楽になります。


104
git config -e.git/configお好みのエディターでファイルを開きます。
Richard

3
念のため。2つのURLを持つリモートを使用しても、1.7.12.4でジョブが実行されることを確認します。ありがとう。
foob​​ar

26
私は「元の」リモートを「すべて」と名付け、ややクリーンなセマンティクスを与えました
ErichBSchulz 2013

1
@JamesWomackは、以下の@Malvineousの回答を参照してください。gitのコマンドラインがを使用してネイティブでこれをサポートしているため、これは「より正確」になりましたgit remote set-url ... --add
ELLIOTTCABLE

1
[branch "Master"]セットの下でremote = Origingit pull両方のリモコンを使用します。
ベングト

264

git 1.8(2012年10月)以降、コマンドラインからこれを行うことができます。

git remote set-url origin --push --add user1@repo1
git remote set-url origin --push --add user2@repo2
git remote -v

次にgit push、user1 @ repo1にプッシュし、次にuser2 @ repo2にプッシュします。


19
私はこの解決策を強くお勧めしません。私たちはそれを社内で使用しており、一方のリポジトリではフックが失敗し、他方では失敗しないという深刻な問題に直面しました。その場合、チェンジセットは1つのリポジトリにのみ存在していました。
MichaelSchmeißer2013年

4
@MichaelSchmeißer:おそらくプッシュ時にエラーメッセージが表示され、問題を修正してから、もう一度プッシュしてすべてをクリーンな状態に戻すことができますか?
Malvineous 2013年

7
問題は、拒否されたプッシュを修正するには、すでに他のリポジトリにプッシュされているコミットを変更する必要があることです。したがって、誰かがそれらのコミットを修正するまでにすでにその作業に基づいている場合、事態は非常に厄介なものになります。これは、私たちのオフィスではそうでした。
MichaelSchmeißer2013年

9
ええ、それはトリッキーになる可能性があります。しかし、私にはフックを再設計する必要があるようです。プッシュが失敗してもgitは正常に機能しません。そのため、新しい障害点を導入する(これにより、気の利いたgit機能を使用できなくなります)は、おそらく最善の解決策ではありません。もちろん、私はあなたの要件が何であるかを知らずにこれを言います...
Malvineous

3
いいえ。質問を書いてから、他のWeb投稿を読んでから、このことをテストしました。他の投稿を読んだところ、最初の行だけが使用されているのではないかと疑いました。私はこれをテストしました。実際、最初の行のURLのみがによって検査されgit fetchます。(これを考えると、git remote set-url --addなしでは何ができるのか理解できません--push。)
imz-Ivan Zakharyaschev '19

34

これらのエイリアスを〜/ .bashrcに追加しました:

alias pushall='for i in `git remote`; do git push $i; done;'
alias pullall='for i in `git remote`; do git pull $i; done;'

6
これはすごい!最終的にGitエイリアスができました:git config alias.pushall '!for i in git remote; do git push $i; done;'
Ciro Santilli冠状病毒审查六四事件法轮機能

新しいリモートを作成するよりも、エイリアスソリューションを好むと思います。stackoverflow.com/questions/41372919/…
donquixote

1
提案された小さな調整:alias pushall='for i in `git remote`; do echo "Pushing to " $i; git push $i; done;'
スコットCウィルソン

25

以下を使用してリモートを追加できます。

git remote add a urla
git remote add b urlb

次に、すべてのリポジトリを更新します。

git remote update

15

これが.gitconfigエイリアスセクション内のbashスクリプトの私の例です

[alias]
        pushall = "!f(){ for i in `git remote`; do git push $i; done; };f"

7

2つの個別のpushurlを.git congfigファイルのリモート "origin"に追加しました。私は実行すると、git push origin "branchName"その後は、を介して実行し、各URLにプッシュします。これを実現する簡単な方法があるかどうかはわかりませんが、これは私自身がGithubソースコードにプッシュすると同時にMy.visualStudioソースコードにプッシュするために機能します。

[remote "origin"]
  url = "Main Repo URL"
  fetch = +refs/heads/*:refs/remotes/origin/*
  pushurl = "repo1 URL"
  pushurl = "reop2 URl"

4

私は自由をもってnona-urbizからの答えを拡大しました。これを〜/ .bashrcに追加してください:

git-pullall () { for RMT in $(git remote); do git pull -v $RMT $1; done; }    
alias git-pullall=git-pullall

git-pushall () { for RMT in $(git remote); do git push -v $RMT $1; done; }
alias git-pushall=git-pushall

使用法:

git-pullall master

git-pushall master ## or
git-pushall

git-pullallにブランチ引数を指定しない場合、デフォルト以外のリモートからのプルは失敗します。gitに類似しているため、この動作はそのままにしました。


3

それらをループするスクリプトが必要です。Gitは「プッシュオール」を提供しません。理論的には複数のスレッドでプッシュを実行できますが、ネイティブメソッドは使用できません。

フェッチはさらに複雑なので、直線的に行うことをお勧めします。

あなたの最善の答えは、可能であれば、誰もがプッシュ/プルできるマシンを1つ持つことだと思います。


2
問題は、私が説明したように、常に利用可能な中心的なボックスがないことです。ループするbashスクリプトを作成する必要がある場合は、それもそうですが、分散VCを使用してもあまり役に立たないのはおかしいと
思い

2
配布されているため、誰もが利用できるわけではない、またはプッシュしたいと思っていると想定しています。また、さまざまな状態にあるさまざまなリポジトリ、および他のリポジトリがそれらに同時に取り組んでいるという仮定にも関係しています。一連のリポジトリからプッシュとプルを行う順序は、さまざまなリポジトリの状態に影響を与えるため、複数のパスを作成して、それらすべてを完全に同期させる必要があります。これが「プル/すべてプッシュ」がない理由です。その後、衝突があります...;)
ジェフ

3

リモコンを更新する(つまり、pullケース)ために、物事が簡単になりました。

ライナスの声明

悲しいことに、これをgitエイリアスで偽造する方法すらありません。

で参照されたエントリでGitのメーリングリストelliottcableの答えはもはや真実ではありません。

git fetch--all過去にどこかでパラメータを学習し、一度にすべてのリモートをフェッチできるようにしました。

すべてが要求されない場合は、--multiple複数のリモートまたはグループを指定するためにスイッチを使用できます。


3

VSO / TFSで作業し、準備ができたらGitHubに一般公開しました。プライベートVSOで作成された最初のリポジトリ。GitHubに追加する時が来たとき、私はしました:

git remote add mygithubrepo https://github.com/jhealy/kinect2.git
git push -f mygithubrepo master

チャンピオンのように働いた...

健全性チェックを行うには、「git remote -v」を発行して、プロジェクトに関連付けられているリポジトリを一覧表示します。

C:\dev\kinect\vso-repo-k2work\FaceNSkinWPF>git remote -v
githubrepo      https://github.com/jhealy/kinect2.git (fetch)
githubrepo      https://github.com/jhealy/kinect2.git (push)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (fetch)
origin  https://devfish.visualstudio.com/DefaultCollection/_git/Kinect2Work (push)

簡単な方法、私のために働いた...これが誰かを助けることを願って


4
git push -f理由なしに実行すること、たとえば、失敗しgit pushたり、何をしているのかを正確に把握することは、悪い考えです。これも質問の答えにはなりませんが、2番目のリモコンを追加する方法はわかります。
カールリヒター2017年

2

以下のコマンドでエイリアスをグローバルgitconfig(/home/user/.gitconfig)に追加します。

git config --global alias.pushall '!f(){ for var in $(git remote show); do echo "pushing to $var"; git push $var; done; }; f'

コードをコミットすると、私たちは言う

git push

デフォルトでオリジンにプッシュします。上記のエイリアスの後、私たちは言うことができます

git pushall

コードは、オリジンリモートを含むすべてのリモートに更新されます。


1

all使用する各マシンでセットアップする必要があるため、リモートを追加するのは少し面倒です。

また、提供されているエイリアスbashgit エイリアスはすべて、すべてのリモートにプッシュすることを前提としています。(例:sshagGitHubとGitLabで維持しているフォークがあります。アップストリームリモートを追加しましたが、それにプッシュする権限がありません。)

以下は、を含むプッシュURLを持つリモートにのみプッシュするgit エイリアスです@

psall    = "!f() { \
    for R in $(git remote -v | awk '/@.*push/ { print $1 }'); do \
    git push $R $1; \
    done \
    }; f"

-3

新しいリモコンを追加する

git remote add upstream https://github.com/example-org/example-repo.git

git remote -vv

複数の場所からフォームを取得する

git fetch --all

場所にプッシュ

git push -u upstream/dev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.