﻿# 如何讓 Git 可以用一個 git push 同時推送到多個遠端儲存庫

Git 的工作目錄其實可以一次處理多個遠端儲存庫，這篇文章我打算分享幾個 Git Remote 設定技巧，讓你更輕鬆的面對多個遠端儲存庫。

### 一個工作目錄設定不同的 `push` 與 `fetch` 遠端儲存庫

有一種情境是這樣的，我們想從一個開源專案 Fork 到我們的帳號下，最新版都在**上游專案**(upstream)，但 Fork 過的專案才有權限能夠 Push 新版本，你只能透過 Pull Request (PR) 的方式才能將變更提交回去。

這種情況下，我們會這樣調整我們的本地專案：

1.  先從 **上游專案**(upstream) 複製專案回來
    
    ```bash
    git clone https://github.com/angular/angular-cli.git --depth=1
    ```
    
2.  查看目前的 `origin` 遠端資訊
    
    ```bash
    # git remote -v
    origin  https://github.com/angular/angular-cli.git (fetch)
    origin  https://github.com/angular/angular-cli.git (push)
    ```
    
3.  變更 `push` 的位址，改到 Fork 到自己帳號下的 Repo
    
    ```bash
    git remote set-url --push origin https://github.com/doggy8088/angular-cli.git
    ```
    
4.  查看修改過的 `origin` 遠端資訊
    
    ```bash
    # git remote -v
    origin  https://github.com/angular/angular-cli.git (fetch)
    origin  https://github.com/doggy8088/angular-cli.git (push)
    ```
    

### 一個工作目錄設定兩個不同的 `push` 遠端儲存庫

有時候我們會需要一次推送變更到多個不同的 Git 遠端儲存庫，你其實可以設定一個 `git push` 命令就能同時推送到兩個不同的遠端儲存庫！

我們假設有兩個遠端儲存庫如下：

1.  https://MyOrg@dev.azure.com/MyOrg/\_git/demo1
2.  https://MyOrg@dev.azure.com/MyOrg/\_git/demo2

那麼我們本地開發目錄的設定步驟如下：

1.  取得原始碼 (取出 `develop` 分支)
    
    ```bash
    git clone https://MyOrg@dev.azure.com/MyOrg/_git/demo1 -b develop
    cd demo1
    ```
    
    > 此時會有一組名為 `origin` 的遠端儲存庫設定，你可以用 `git remote -v` 得知結果。
    
2.  檢查 Git Remote 位址
    
    你只要是用 `git clone` 複製回來的，預設遠端名稱為 `origin`，而且會有一組，分別是 `fetch` 與 `push` 兩個不同的位址。
    
    ```bash
    # git remote -v
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (fetch)
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (push)
    ```
    
    當你在執行 `git fetch` 或 `git pull` 的時候，預設會以 `fetch` 的遠端位址為主。
    
    當你在執行 `git push` 的時候，預設會以 `push` 的遠端位址為主。
    
3.  設定多組 `push` 遠端儲存庫位址
    
    如果你想要用一個 `git push` 就同時 Push 到兩個 Repos，那就只要在 `origin` 設定兩個 `push` 的位址即可：
    
    ```bash
    git remote set-url --add --push origin https://MyOrg@dev.azure.com/MyOrg/_git/demo1
    git remote set-url --add --push origin https://MyOrg@dev.azure.com/MyOrg/_git/demo2
    ```
    
    設定完後你會得到以下結果：
    
    ```bash
    # git remote -v
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (fetch)
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (push)
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo2 (push)
    ```
    
    這樣的設定，不僅僅只會套用在 Git 命令列工具，所有 Git 工具也都會自動生效，只要 Git Push 一次就會自動推送到多個 Repos！
    

### 一個工作目錄設定兩組不同的遠端儲存庫

還有一種情境是，你在工作目錄想同時保有兩個不同的遠端儲存庫，而且兩個遠端儲存庫你都有權限，都有可能會做 Push 或 Pull/Fetch 動作。

那麼我們本地開發目錄的設定步驟如下：

1.  取得原始碼 (取出 `develop` 分支)
    
    ```bash
    git clone https://MyOrg@dev.azure.com/MyOrg/_git/demo1 -b develop
    cd demo1
    ```
    
2.  設定第二組遠端儲存庫位址
    
    ```bash
    git remote add demo2 https://MyOrg@dev.azure.com/MyOrg/_git/demo2
    ```
    
    > 如果第二組遠端儲存庫位址是 `origin` 的 **上游專案**(upstream)，我們有時候會直接設定 Remote 名稱為 `upstream`，如此一來**語意**就會非常清楚。
    
3.  檢查 Git Remote 位址
    
    此時你應該會看見兩組 Remote 位址，個別都有 `fetch` 與 `push` 位址：
    
    ```bash
    # git remote -v
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (fetch)
    origin  https://MyOrg@dev.azure.com/MyOrg/_git/demo1 (push)
    demo2  https://MyOrg@dev.azure.com/MyOrg/_git/demo2 (fetch)
    demo2  https://MyOrg@dev.azure.com/MyOrg/_git/demo2 (push)
    ```
    
    當你想取回 `origin` 的新版本時，使用 `git pull` 或 `git fetch` 就可以取得。
    
    當你想取回 `demo2` 的新版本時，使用 `git pull demo2` 或 `git fetch demo2` 就可以取回新版。
    
    當你想取回所有 Remote 的新版本時，就不能用 `git pull` 命令了，因為 Git 不會知道你想合併哪一條遠端分支。你只能用 `git fetch --all` 取回所有新的版本(Commits)，但你就要自行決定如何合併遠端的版本變更了！
    

### 相關連結

-   [2.5 Git 基礎 - 與遠端協同工作](https://git-scm.com/book/zh-tw/v2/Git-%E5%9F%BA%E7%A4%8E-%E8%88%87%E9%81%A0%E7%AB%AF%E5%8D%94%E5%90%8C%E5%B7%A5%E4%BD%9C)
-   [Working with Git remotes and pushing to multiple Git repositories | Jigarius.com](https://jigarius.com/blog/multiple-git-remote-repositories)
