﻿# 介紹好用工具：GitFlow for Visual Studio 使用教學與衝突處裡方式

最近發現終於有 [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 擴充套件可以用了，這讓使用 GitFlow 版控流程的團隊可以更方便的將流程整合到 Visual Studio 之中，本篇文章將完整說明 [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 擴充套件的使用方法與注意事項。如果你還不了解 [Git](http://git-scm.com/) 或 [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/) 的話，也歡迎到 [多奇教育訓練課程一覽](http://bit.ly/miniasp_kktix) 報名【Git 版本控管實戰】相關課程。

### **學習前的準備**

1.  請先在 Visual Studio 2013 中安裝 [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 擴充套件  
    ※注意：你至少要先安裝 Visual Studio 2013 Update 3 以上版本才能安裝這個擴充套件
2.  各位可以拿 [https://github.com/doggy8088/MVC5\_Add\_WebAPI](https://github.com/doggy8088/MVC5_Add_WebAPI "https://github.com/doggy8088/MVC5_Add_WebAPI") 專案回來練習，本篇文章將會以這個 GitHub 專案當成教學的範本。
3.  版控功能都已經整合進 Visual Studio 2013 的 Team Explorer 工作窗格中，請透過 \[檢視\] –> \[Team Explorer\] 開啟這個工作窗格。  
    ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/5e4f49657c9cfdb8e875-image_2612.png)
4.  要使用 [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 擴充套件之前，請務必先行了解 [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/) 運作原理，否則用起來會很不順利，請各位務必先行理解。  
    

### **複製 Git 專案 ( git clone ) 並開啟專案**

在 Team Explorer 中點擊「**連接到 Team 專案**｣的圖示

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d9a62c7de7f7ee6c7cac-image_2613.png)

點擊「本機 Git 儲存機制」的「複製」

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b7b17800b3563b98b83e-SNAGHTML800afbe.png)

貼上 GitHub 專案網址，並按下「複製」按鈕

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/0c595e4987413d639f21-SNAGHTML8027396.png)

滑鼠雙擊剛剛 **複製** (clone) 回來的專案

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c3342b0c47cb5595c1c8-SNAGHTML806434b.png)

滑鼠雙擊 \*.sln 方案，就可以開啟此專案

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/289ddd3acb88eccbdc30-image_2614.png)

專案開啟後，請先進行一次成功的建置 (Build)！  

### **初始化 GitFlow 版控環境**

目前，你得到一個只有 master 分支的 Git 本地儲存庫，我們可以從 Team Explorer 窗格中先進入 Git 版控的「首頁」，然後點擊 GitFlow 進入 GitFlow 的相關操作畫面。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7cbabef5e87c619bece9-image_2615.png)

點選 Initialize 準備初始化 GitFlow 版控環境

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b654bba83d0c95283bd8-image_2616.png)

由於 GitFlow 版控流程會有**兩個主要分支** (master, develop) 與**三個支援分支** (feature, release, hotfix)，基本上預設值都可以不用改，直接按下 **OK** 按鈕即可讓 GitFlow 初始化完成，這些設定都會儲存在 **.git\\config** 設定檔之中。預設他會自動幫你額外建立一個 develop 分支。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/6dec9bf273b5037494c4-image_2617.png)

此時你可以看到 GitFlow 設定完成後的畫面，未來 GitFlow 版控流程也都會在這裡操作！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/36da934df88131384675-image_2618.png)

我改用 TortoiseGit 的 Show log 你可以看見如下圖示，目前 Git 工作目錄將會自動切換到 develop 分支上。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/832aaa572a21ff05d500-image_thumb_206.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a49537ccd0f9f13d21b6-image_2619.png)  

### 概要說明 [GitFlow](http://nvie.com/posts/a-successful-git-branching-model/) 版控流程

-   初始化 GitFlow

-   從 master 建立 develop 分支

-   功能分支 ( Feature Branch )

-   Start: 從 develop 建立 Feature 分支
-   Finish: 將 Feature 分支合併回 develop 分支

-   發行分支 ( Release Branch )

-   Start: 從 develop 建立 Release 分支
-   Finish: 將 Release 分支依序合併回 master 與 develop 分支

-   修補分支 ( Hotfix Branch )

-   Start: 從 master 建立 Hotfix 分支
-   Finish: 將 Hotfix 分支依序合併回 master 與 develop 分支

※ 注意：有合併，就會有衝突的可能，GitFlow 原則上不會幫你處理衝突，有衝突要自行處裡，所以上述說明的版控流程很重要，使用 GitFlow 的人務必牢記！  
  

**完成一個 Feature 分支開發的版控流程**

假設我們現在想要開發一個新的 ASP.NET MVC 控制器，這時我們將會建立一個 Feature 分支，以下就是透過 GitFlow for Visual Studio 建立 Feature 分支的步驟。

在 Team Explorer 的 GitFlow 畫面點擊 Start Feature 並輸入一個新的 Feature 分支名稱，並點擊 Create Feature 建立分支。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b208e541efef6d95c10f-image_2620.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e8307f97280f0899f04a-image_2621.png)

假設你想建立的 Feature 分支名稱為 add\_profile\_controller 的話，這個過程 GitFlow for Visual Studio 就會自動幫你建立起一個名為 feature/add\_profile\_controller 分支，我們可以利用 TortoiseGit 的 Show log 看到這個真正的分支名稱，而且目前工作目錄也已經自動切換到這個新分支了。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ca107f733eecb691b8b3-image_2622.png)

接著我們在專案中新增一個 Controllers/ProfileController.cs 控制器，並且新增一些 View 上去，然後建立一個新版本。

註：不熟悉在 Visual Studio 操作基礎 Git 版控的人，可以先從 Visual Studio Online 與 Git 版本控管實戰 學習到相關知識。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a66c1650427c74a9eb62-image_2623.png "image")  
當執行完 **認可 (Commit)** 動作後，你將會在 feature/add\_profile\_controller 分支中建立起一個新版本，這時的版本線圖 (Version Graph) 如下圖示：

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3e9c34b210cec261a1b3-image_thumb_207.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b30f28ce2ab5a5f07bd4-image_2624.png)

假設你的所有變更已經完成，這時我們就要準備進入 GitFlow 版控流程的另一個動作，也就是完成這個 Feature 分支。此時請你參考下圖，點選這個下拉選單，將畫面切換到 GitFlow 去。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7418efc542f07ebbbc11-image_2625.png)

通常這個時候，你可能會有幾種選擇：

-   將現有的 feature/add\_profile\_controller 分支發行 (Publish) 到遠端儲存庫 (讓其他人看的到你正在開發中的分支)  
    [![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b554c120f0dcdbb6b247-image_thumb_208.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/39489eb6855196afb48e-image_2626.png)
-   完成這個 feature/add\_profile\_controller 分支，並刪除本地分支  
    [![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b4c35587b84f63900e58-image_thumb_209.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c55f31f1badaae53ba61-image_2627.png)
-   完成這個 feature/add\_profile\_controller 分支前先 Rebase develop 分支，然後刪除本地分支  
    ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d6836547ead4742afdb6-image_2628.png)

假設我們選擇第二種，並按下 OK 按鈕，你會發現所有 Feature 已經都完成了合併，而且是合併回 develop 分支。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/4102d9e57a88edd942db-image_thumb_210.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ca8f81e722d807b5cc6c-image_2629.png)

如果透過 TortoiseGit 的 Show log 查看版本線圖，你會發現 develop 在合併 feature/add\_profile\_controller 分支時，自動引發了 Git 的快轉機制 (Fast-Forward)，所以你會看見 develop 分支直接往上跳一個版本。

[![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3dc3fa37666c781d45e8-image113_thumb.png "image")](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7638f19a067281160ac2-image113.png)

因為 [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 骨子裡其實就是執行 git flow 指令而已，因此所有的版控操作其實都是在下指令罷了，關於這點你可以透過「輸出」窗格得知所有 git flow 執行的細節與訊息。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/14fac70edadd1d8aaedc-image_2630.png)

如果你想要強迫指定 No Fast-Forward 的方式進行合併，則必須去修改 "C:\\Program Files (x86)\\Git\\bin\\git-flow-feature" 這個檔案，這是一個 Shell Script 檔案，git flow 在執行的時候，會去呼叫這支程式出來執行，所以如果要強迫使用 No Fast-Forward 方式合併，請搜尋到以下字串：

```
git_do merge --ff "$BRANCH"
```

並且修改成以下即可：

```
git_do merge --no-ff "$BRANCH"
```

在了解完一整個 Feature 分支的版控流程，其他支援分支的操作方式也都大同小異，必較需要注意的地方，應該就是開發人員必須先了解 GitFlow 的版控流程，不要光只是用工具，因為 Git 版控的觀念遠比透過工具操作來的重要多了！

  

### 處裡 Feature 分支完成時的衝突問題

上一個例子我們很順利的完成了 Feature 分支的合併動作，當你有多條 Feature 分支同時進行中時，發生衝突的機會自然也就多了，所以學習如何處裡衝突，絕對是個必修的功課！

假設我們在此時同時建立兩個 Feature 分支，分別命名為 ErrorOn1 與 ErrorOn2

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/11e53b6c9bf4ed00792c-image_2631.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/b94adfdda80528ea57af-image_2632.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/6e888f103560c775eea0-image_2633.png)

然後我們先切換到 ErrorOn1 這個 Feature 分支

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/43d7ecd13b7904c8ca82-image_2634.png)

然後我們打開 web.config 檔案，並加上 <customErrors> 設定如下，並建立新版本：

```
<customErrors mode="Off"></customErrors>
```

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/317f7efa120681817645-image_2635.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/db5c891b00b6a7b83c03-image_2636.png)

我們可以先完成 ErrorOn1 功能分支

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/72a3fffdf60aee5401ee-image_2637.png "image")

接著我們切換到 ErrorOn2 功能分支

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/6ddbc419be46f6c48aab-image_2638.png)

這次我們打開 web.config 檔案，並加上有點不太一樣的 <customErrors> 設定如下，並建立新版本：

```
<customErrors mode="RemoteOnly" />
```

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c685664bf5e20f2b4075-image_2639.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3ecc90e7a36ad4fb6290-image_2640.png)

這時如果你想完成 ErrorOn2 功能分支，由於 Feature 分支一定會合併回 develop 分支，而之前的 ErrorOn1 功能分支已經成功合併回 develop 分支，而這次的 ErrorOn2 功能分支因為改到完全相同的一行，且內容還不太一樣，所以這次的合併勢必會引發合併衝突，我們先來看看在完成 Feature 分支的過程中會發生什麼事。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/7488ba284eeba0c31abe-image_2641.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/3aeb2259ab6b87e0f99f-image_2642.png)

執行完後，你會發現沒有任何錯誤訊息，從上圖也可以發現 ErrorOn2 功能分支本來應該被刪除，但是卻還存在，**這種有點「怪怪的」情況，完全是個大陷阱啊**！因為衝突已經發生了，等待你去解決它！

如果你 web.config 檔案還開著，就會看到 Git 在合併時修改掉原本內容的情況，也代表著你的專案已經跑不動了，因為這已經完全破壞掉 Web.config 原本的 XML 格式，所以你不會沒發現這件事，發生衝突，就是要你當下立刻解決衝突！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e3f791a246980510b413-image_2643.png)

事實上你可以從「輸出」窗格看見完整的 git flow 指令回應的錯誤訊息：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/2681b178b2868fb87e44-image_2644.png)

這時我們直接對專案在執行一次「認可 (Commit)」動作，你就會發現一段【**合併正在進行中，請解決衝突，並認可結果。**】的提示訊息，請點選「**請解決衝突**」連結：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/0557c3bc24ff1b856481-image_2645.png)

我們從「衝突」分類中選取 Web.config 衝突中的檔案，並按下「**合併**」按鈕，讓 Visual Studio 2013 幫我們來解決衝突的問題。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/0299b7fc48ba173d6097-image_2646.png)

我個人覺得 Visual Studio 2013 內建的版本衝突處理工具是所有 Git 合併工具中做得最漂亮的！

你可以從左邊或右邊選擇任何一邊的內容，在某些合併的情況下，你可能會需要兩邊都選，選擇完之後，還可以手動修改中間的合併結果，最後只要按下左上角的「接受合併」即可完成衝突解決！

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c1605b930a915c863756-image_thumb_211.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/25fef2694af64b8c58b5-image_2647.png)

衝突解決之後，就可以看到 Web.config 已經被列入到「已解決」這個分類下了，請按下「認可合併」按鈕

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/f0b17e15c2292bd4bc8c-image_2648.png)

最後輸入一些變更紀錄，並按下「認可 (Commit)」即可完成本次合併

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/9b6da13c71d890b3a4cb-image_2649.png)

這個時候其實 ErrorOn2 功能分支已經完成了合併，如果你要把這個功能分支刪除的話，只要再執行一次 Finish Feature 動作即可！

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a299974920d4ba3f60f3-image_2650.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/9af54f596c02943ff5c7-image_2651.png)

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/a20ef59dfafabc2a1647-image_2652.png)

  
  
有了以上說明，剩下的 Release 與 Hotfix 分支，應該就不用額外說明了，不過還是建議大家多練習個幾次，以免導入 GitFlow 遇到問題時手忙腳亂的！ ^\_^

**相關連結**

-   [GitFlow for Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-57624.GitFlowforVisualStudio) 擴充套件
-   [Introducing GitFlow for Visual Studio](http://geekswithblogs.net/jakob/archive/2015/02/12/introducing-gitflow-for-visual-studio.aspx)
-   Visual Studio Online 與 Git 版本控管實戰
-   [Create, Connect, and Publish using Visual Studio with Git - Microsoft ALM](https://devblogs.microsoft.com/devops/create-connect-and-publish-using-visual-studio-with-git-2/)
-   [Getting Started with Git in Visual Studio and Team Foundation Service - Microsoft ALM](https://devblogs.microsoft.com/devops/getting-started-with-git-in-visual-studio-and-team-foundation-service-2/)
-   [Share your code in Git](https://learn.microsoft.com/en-us/azure/devops/repos/git/share-your-code-in-git-vs?view=azure-devops)
-   [Visual Studio and GitHub: The Basics of Working with Existing Repositories | Rick Rainey](http://rickrainey.com/2013/07/27/visual-studio-and-gitub-the-basics-of-working-with-existing-repositories-2/)
-   GitFlow: [A successful Git branching model » nvie.com](http://nvie.com/posts/a-successful-git-branching-model/)
-   [nvie/gitflow](https://github.com/nvie/gitflow)
-   [Always use --no-ff to merge feature branches regaredless of commit count... #298](https://github.com/nvie/gitflow/pull/298)
