1. Git 初學者詳細指南
今天我們要聊的是版本控制系統,也就是Git。
如果不了解和理解這個工具,您真的不能成為一名成熟的程序員。當然,您不必為了持續使用而將所有 Git 命令和功能都記在腦子裡。您需要了解一組命令,以幫助您了解正在發生的一切。
Git 基礎知識
Git 是我們代碼的分佈式版本控制系統。我們為什麼需要它?團隊需要某種系統來管理他們的工作。需要跟踪隨時間發生的變化。
也就是說,我們需要能夠逐步查看哪些文件已更改以及如何更改。當您調查在單個任務的上下文中發生了什麼變化時,這一點尤其重要,從而可以恢復更改。
讓我們想像以下情況:我們有工作代碼,其中的一切都很好,但後來我們決定改進或調整一些東西。沒什麼大不了的,但我們的“改進”破壞了程序的一半功能,使其無法運行。那麼現在怎麼辦?如果沒有 Git,你將不得不坐下來思考幾個小時,試圖記住一切最初的樣子。但使用 Git,我們只需回滾提交 — 僅此而已。
或者如果有兩個開發人員同時更改自己的代碼怎麼辦?沒有Git,他們就複製原來的代碼文件,單獨修改。有時兩者都想將他們的更改添加到主目錄。在這種情況下你會怎麼做?
如果你使用 Git 就不會出現這樣的問題。
安裝 Git
讓我們在您的計算機上安裝 Java 這個過程對於不同的操作系統略有不同。
在 Windows 上安裝
像往常一樣,您需要下載並運行一個 exe 文件。這裡的一切都很簡單:點擊第一個谷歌鏈接,執行安裝,就是這樣。為此,我們將使用 Windows 提供的 bash 控制台。
在 Windows 上,您需要運行 Git Bash。這是它在“開始”菜單中的樣子:
現在這是您可以使用的命令提示符。
為避免每次都必須轉到項目所在的文件夾才能在那裡打開 Git,您可以在項目文件夾中使用鼠標右鍵打開命令提示符,並輸入我們需要的路徑:
在 Linux 上安裝
通常 Git 是 Linux 發行版的一部分並且已經安裝,因為它是最初為 Linux 內核開發而編寫的工具。但有些情況下它不是。要檢查,您需要打開一個終端並輸入:git --version。如果你得到一個可理解的答案,那麼就不需要安裝任何東西。
打開終端並安裝。對於 Ubuntu,您需要編寫:sudo apt-get install git。就是這樣:現在您可以在任何終端中使用 Git。
在 macOS 上安裝
在這裡,同樣,您首先需要檢查 Git 是否已經存在(見上文,與 Linux 相同)。
如果您沒有,那麼最簡單的獲取方式就是下載最新版本。如果安裝了Xcode,那麼Git肯定會自動安裝。
設置
Git 為提交工作的用戶設置了用戶設置。這是有道理的,也是必要的,因為 Git 在創建提交時將此信息用於 Author 字段。
通過運行以下命令為所有項目設置用戶名和密碼:
如果您需要更改特定項目的作者(例如個人項目),您可以刪除“--global”。這將為我們提供以下內容:
一點理論
進入正題,我們應該給你介紹一些新的言行……否則,就沒什麼好談的了。當然,這是來自英語的行話,所以我會在括號中添加翻譯。
有什麼言行?
- git 倉庫
- 犯罪
- 分支
- 合併
- 衝突
- 拉
- 推
- 如何忽略一些文件(.gitignore)
等等。
Git 中的狀態
Git有幾個雕像需要理解和記住:
- 未追踪
- 修改的
- 上演
- 堅定的
你應該怎麼理解這個?
這些是適用於包含我們代碼的文件的狀態。換句話說,它們的生命週期通常是這樣的:
- 創建但尚未添加到存儲庫的文件具有“未跟踪”狀態。
- 當我們對已經添加到 Git 存儲庫的文件進行更改時,它們的狀態為“已修改”。
- 在我們更改的文件中,我們選擇我們需要的(例如,我們不需要編譯的類),這些類被更改為“暫存”狀態。
- 提交是從處於暫存狀態的準備文件創建的,並進入 Git 存儲庫。之後,沒有文件處於“暫存”狀態。但可能仍然存在狀態為“已修改”的文件。
這是它的樣子:
什麼是提交?
提交是版本控制的主要事件。它包含自提交開始以來所做的所有更改。提交像單鍊錶一樣鏈接在一起。
具體來說,有一個第一次提交。創建第二個提交時,它(第二個)知道第一個之後會發生什麼。並且以這種方式,可以跟踪信息。
提交也有自己的信息,即所謂的元數據:
- 提交的唯一標識符,可用於查找它
- 提交作者的名字,創建者
- 創建提交的日期
- 描述提交期間所做的事情的註釋
它看起來是這樣的:
什麼是分支?
分支是指向某個提交的指針。因為提交知道哪個提交在它之前,所以當一個分支指向一個提交時,所有那些先前的提交也適用於它。
因此,我們可以說您可以擁有任意數量的分支指向同一個提交。
工作發生在分支中,因此當創建新提交時,分支會將其指針移至最近的提交。
開始使用 Git
您可以單獨使用本地存儲庫,也可以使用遠程存儲庫。
要練習所需的命令,您可以將自己限制在本地存儲庫中。它只將所有項目的信息存儲在本地的 .git 文件夾中。
如果我們談論的是遠程存儲庫,那麼所有信息都存儲在遠程服務器上的某個地方:只有項目的副本存儲在本地。可以將對本地副本所做的更改推送 (git push) 到遠程存儲庫。
在這里和下面的討論中,我們討論的是在控制台中使用 Git。當然,您可以使用某種基於 GUI 的解決方案(例如 IntelliJ IDEA),但首先您應該弄清楚正在執行的命令及其含義。
在本地存儲庫中使用 Git
要創建本地存儲庫,您需要編寫:
這將在控制台的當前目錄中創建一個隱藏的 .git 文件夾。
.git 文件夾存儲有關 Git 存儲庫的所有信息。不要刪除它;)
接下來,將文件添加到項目中,並為它們分配“未跟踪”狀態。要檢查您的工作的當前狀態,請這樣寫:
我們在 master 分支,我們會一直呆在這裡,直到我們切換到另一個分支。
這顯示哪些文件已更改但尚未添加到“暫存”狀態。要將它們添加到“暫存”狀態,您需要編寫“git add”。我們在這裡有幾個選項,例如:
- git add -A — 將所有文件添加到“暫存”狀態
- 混帳添加。— 添加此文件夾和所有子文件夾中的所有文件。與上一個基本相同;
- git add <file name> — 添加特定文件。在這裡您可以使用正則表達式根據某種模式添加文件。例如,git add *.java:這意味著您只想添加擴展名為 java 的文件。
前兩個選項顯然很簡單。隨著最新的添加,事情變得更加有趣,所以讓我們寫:
要檢查狀態,我們使用我們已知的命令:
在這裡您可以看到正則表達式已正常工作:test_resource.txt 現在處於“暫存”狀態。
最後,使用本地存儲庫的最後階段(使用遠程存儲庫時還有一個階段;))——創建一個新的提交:
接下來是一個很棒的命令,用於查看分支上的提交歷史記錄。讓我們利用它:
在這裡您可以看到我們已經創建了第一個提交,它包括我們在命令行上提供的文本。理解這段文字應該盡可能準確地解釋這次提交期間做了什麼是非常重要的。這將在未來多次幫助我們。
尚未入睡的好奇讀者可能想知道 GitTest.java 文件發生了什麼。讓我們現在就知道。為此,我們使用:
如您所見,它仍處於“未跟踪”狀態,正在等待。但是,如果我們根本不想將它添加到項目中怎麼辦?有時會發生這種情況。
為了讓事情變得更有趣,讓我們現在嘗試更改我們的 test_resource.txt 文件。讓我們在那裡添加一些文本並檢查狀態:
在這裡您可以清楚地看到“未跟踪”和“已修改”狀態之間的區別。
GitTest.java 是“未跟踪的”,而 test_resource.txt 是“已修改的”。
現在我們有處於修改狀態的文件,我們可以檢查對它們所做的更改。這可以使用以下命令完成:
也就是說,您可以在這裡清楚地看到我添加到我們的文本文件中的內容:hello world!
讓我們將更改添加到文本文件並創建一個提交:
要查看所有提交,請編寫:
如您所見,我們現在有兩個提交。
我們將以相同的方式添加 GitTest.java。這裡沒有評論,只有命令:
使用 .gitignore
顯然,我們只想在存儲庫中單獨保留源代碼,而不是其他任何東西。那還能有什麼呢?至少,由開發環境生成的編譯類和/或文件。
要告訴 Git 忽略它們,我們需要創建一個特殊文件。這樣做:在項目的根目錄中創建一個名為 .gitignore 的文件。此文件中的每一行代表一個要忽略的模式。
在此示例中,.gitignore 文件將如下所示:
目標/
*.iml
.idea/
讓我們來看看:
- 第一行是忽略所有擴展名為.class的文件
- 第二行是忽略“目標”文件夾及其包含的所有內容
- 第三行是忽略所有擴展名為.iml的文件
- 第四行忽略.idea文件夾
讓我們嘗試使用一個例子。為了看看它是如何工作的,讓我們將編譯後的 GitTest.class 添加到項目中並檢查項目狀態:
顯然,我們不想以某種方式不小心將已編譯的類添加到項目中(使用 git add -A)。為此,創建一個 .gitignore 文件並添加前面描述的所有內容:
現在讓我們使用提交將 .gitignore 文件添加到項目中:
現在是關鍵時刻:我們有一個“未跟踪”的已編譯類 GitTest.class,我們不想將其添加到 Git 存儲庫中。
現在我們應該看到 .gitignore 文件的效果:
完美的!.gitignore +1 :)
使用分支機構
自然地,只在一個分支工作對於孤獨的開發人員來說是不方便的,而當團隊中有多個人時,這是不可能的。這就是為什麼我們有分支機構。
分支只是指向提交的可移動指針。
在這一部分中,我們將探索在不同的分支中工作:如何將一個分支的更改合併到另一個分支,可能會出現什麼衝突,等等。
要查看存儲庫中所有分支的列表並了解您所在的分支,您需要編寫:
你可以看到我們只有一個 master 分支。它前面的星號表示我們在其中。順便說一句,你也可以使用“git status”命令來找出我們在哪個分支。
然後有幾個創建分支的選項(可能有更多——這些是我使用的):
- 根據我們所在的分支創建一個新分支(99% 的情況)
- 根據特定提交創建分支(1% 的案例)
讓我們根據特定的提交創建一個分支
我們將依賴提交的唯一標識符。為了找到它,我們寫:
我們用註釋“added hello world...”突出顯示了提交,它的唯一標識符是 6c44e53d06228f888f2f454d3cb8c1c976dd73f8。我們想創建一個從此提交開始的“開發”分支。為此,我們寫:
創建一個分支時,只有來自 master 分支的前兩個提交。為了驗證這一點,我們首先確保切換到不同的分支並查看那裡的提交數量:
正如預期的那樣,我們有兩個提交。順便說一下,這裡有一個有趣的點:這個分支中還沒有 .gitignore 文件,所以我們的編譯文件 (GitTest.class) 現在以“未跟踪”狀態突出顯示。
現在我們可以通過編寫以下代碼再次查看我們的分支:
可以看到有兩個分支:“master”和“development”。我們目前正在開發中。
讓我們在當前的基礎上創建一個分支
創建分支的第二種方法是從另一個分支創建它。我們想在master分支的基礎上創建一個分支。首先,我們需要切換到它,下一步是創建一個新的。讓我們來看看:
- git checkout master——切換到master分支
- git status — 驗證我們實際上在 master 分支中
這裡可以看到我們切換到了master分支,.gitignore文件生效了,編譯後的類不再高亮為“untracked”。
現在我們在master分支的基礎上新建一個分支:
如果您不確定這個分支是否與“master”相同,您可以通過執行“git log”並查看所有提交來輕鬆檢查。應該有四個。
解決衝突
在我們探討什麼是衝突之前,我們需要討論將一個分支合併到另一個分支。
這張圖描繪了將一個分支合併到另一個分支的過程:
在這裡,我們有一個主要分支。在某些時候,從主分支創建一個輔助分支,然後對其進行修改。工作完成後,我們需要將一個分支合併到另一個分支中。
在我們的示例中,我們創建了 feature/update-txt-files 分支。正如分支名稱所示,我們正在更新文本。
現在我們需要為這項工作創建一個新的提交:
現在,如果我們想將 feature/update-txt-files 分支合併到 master 中,我們需要到 master 中編寫“git merge feature/update-txt-files”:
因此,master 分支現在還包含添加到 feature/update-txt-files 的提交。
添加了此功能,因此您可以刪除功能分支。為此,我們寫:
讓情況復雜化:現在假設您需要再次更改 txt 文件。但是現在這個文件也將在 master 分支中被更改。換句話說,它會平行變化。當我們想將我們的新代碼合併到 master 分支時,Git 將無法弄清楚該怎麼做。
我們將基於 master 創建一個新分支,對 text_resource.txt 進行更改,並為此工作創建一個提交:
...我們對文件進行更改
轉到 master 分支並在與 feature 分支相同的行上更新此文本文件:
…我們更新了 test_resource.txt
現在最有趣的一點是:我們需要將更改從 feature/add-header 分支合併到 master。我們在master分支,所以只需要寫:
但結果會在 test_resource.txt 文件中發生衝突:
在這裡我們可以看到 Git 無法自行決定如何合併這段代碼。它告訴我們需要先解決衝突,然後才執行提交。
好的。我們在文本編輯器中打開有衝突的文件並查看:
要了解 Git 在這裡做了什麼,我們需要記住我們做了哪些更改以及在哪裡,然後進行比較:
- 主分支中這一行的更改位於“<<<<<<< HEAD”和“=======”之間。
- feature/add-header 分支中的更改位於“=======”和“>>>>>>> feature/add-header”之間。
這就是 Git 告訴我們它無法弄清楚如何在文件中的這個位置執行合併的方式。它將本節分為來自不同分支的兩個部分,並邀請我們自己解決合併衝突。
很公平。我大膽地決定刪除所有內容,只留下“header”一詞:
讓我們看一下更改的狀態。描述會略有不同。我們沒有“修改”狀態,而是“未合併”。那麼我們可以提到第五種身份嗎?我不認為這是必要的。讓我們來看看:
我們可以說服自己,這是一個特殊的、不尋常的案例。讓我們繼續:
您可能會注意到描述建議只寫“git commit”。讓我們嘗試這樣寫:
就這樣,我們做到了——我們在控制台中解決了衝突。
當然,這在集成開發環境中可以做得更容易一些。例如,在 IntelliJ IDEA 中,一切都設置得非常好,您可以在其中執行所有必要的操作。但是 IDE 在“幕後”做了很多事情,我們常常不了解那裡到底發生了什麼。當沒有理解時,問題就會出現。
使用遠程存儲庫
最後一步是找出使用遠程存儲庫所需的更多命令。
正如我所說,遠程存儲庫是存儲存儲庫的地方,您可以從中克隆它。
有哪些遠程存儲庫?例子:
- GitHub 是最大的存儲庫和協作開發存儲平台。
- GitLab 是一個基於 Web 的開源 DevOps 生命週期工具。它是一個基於 Git 的系統,用於管理代碼存儲庫,具有自己的 wiki、錯誤跟踪系統、CI/CD 管道和其他功能。
- BitBucket 是一個基於 Mercurial 和 Git 版本控制系統的項目託管和協作開發的 Web 服務。有一段時間,它比 GitHub 有一個很大的優勢,因為它提供免費的私有存儲庫。去年,GitHub 也免費向大家推出了這個能力。
- 等等…
使用遠程存儲庫時,首先要做的是將項目克隆到本地存儲庫。
為此,我們導出了我們在本地製作的項目現在每個人都可以通過編寫自己克隆它:
現在有項目的完整本地副本。為了確保項目的本地副本是最新的,您需要通過編寫來拉取項目:
在我們的例子中,遠程存儲庫中目前沒有任何變化,所以響應是:已經是最新的。
但是,如果我們對遠程存儲庫進行任何更改,本地存儲庫會在我們拉取它們後更新。
最後,最後一個命令是將數據推送到遠程存儲庫。當我們在本地做了一些事情,想要發送到遠程倉庫時,首先要在本地創建一個新的commit。為了證明這一點,讓我們在文本文件中添加其他內容:
現在對我們來說很常見——我們為這項工作創建一個提交:
將其推送到遠程存儲庫的命令是:
就這樣吧!
有用的鏈接 |
---|
|
2. 如何在 IntelliJ IDEA 中使用 Git
在這一部分中,您將學習如何在 IntelliJ IDEA 中使用 Git。
所需輸入:
- 閱讀、跟進並理解前面的部分。這將有助於確保一切都已設置好並準備就緒。
- 安裝 IntelliJ IDEA。這裡的一切都應該井井有條:)
- 分配一個小時來完全掌握。
讓我們使用我在有關 Git 的文章中使用的演示項目。
在本地克隆項目
這裡有兩個選項:
- 如果你已經有一個 GitHub 帳戶並想稍後推送一些東西,最好 fork 項目並克隆你自己的副本。您可以在另一篇文章“分叉工作流示例”的標題下閱讀有關如何創建分叉的信息。
- 克隆存儲庫並在本地執行所有操作,但無法將整個操作推送到服務器。
要從 GitHub 克隆項目,您需要復制項目鏈接並將其傳遞給 IntelliJ IDEA:
-
複製項目地址:
-
打開 IntelliJ IDEA 並選擇“從版本控制獲取”:
-
複製粘貼項目地址:
-
系統將提示您創建一個 IntelliJ IDEA 項目。接受報價:
-
由於沒有構建系統,我們選擇“Create project from existing sources”:
-
接下來你會看到這個漂亮的屏幕:
現在我們弄清楚了克隆,你可以四處看看。
作為 Git UI 的 IntelliJ IDEA 第一眼
仔細查看克隆的項目:您已經可以獲得很多關於版本控制系統的信息。
首先,我們在左下角有版本控制面板。在這裡您可以找到所有本地更改並獲得提交列表(類似於“git log”)。
讓我們繼續討論 Log。有一定的可視化可以幫助我們準確地了解開發是如何進行的。例如,您可以看到創建了一個新分支,並在 txt commit 中添加了 header,然後將其合併到 master 分支中。如果單擊一個提交,您可以在右上角看到有關該提交的所有信息:所有更改和元數據。
此外,您可以看到實際的變化。我們還看到那裡解決了衝突。IDEA 也很好地展示了這一點。
如果您雙擊在此提交期間更改的文件,我們將看到衝突是如何解決的:
我們注意到在左側和右側我們有需要合併為一個的同一文件的兩個版本。在中間,我們有最終的合併結果。
當一個項目有很多分支、commit、用戶時,需要按分支、用戶、日期分別查找:
在開始之前,同樣值得解釋一下如何理解我們處於哪個分支。
在右下角,有一個標有“Git: master”的按鈕。“Git:”後面的內容是當前分支。如果單擊該按鈕,您可以做很多有用的事情:切換到另一個分支、創建一個新分支、重命名現有分支等等。
使用存儲庫
有用的熱鍵
為了以後的工作,你需要記住幾個非常有用的熱鍵:
- CTRL+T — 從遠程存儲庫 (git pull) 獲取最新更改。
- CTRL+K — 創建提交/查看所有當前更改。這包括未跟踪和修改的文件 (git commit)。
- CTRL+SHIFT+K — 這是將更改推送到遠程存儲庫的命令。所有在本地創建但尚未在遠程存儲庫中創建的提交都將被推送 (git push)。
- ALT+CTRL+Z — 將特定文件中的更改回滾到在本地存儲庫中創建的最後一次提交的狀態。如果在左上角選擇整個項目,則可以回滾所有文件中的更改。
我們想要什麼?
為了完成工作,我們需要掌握一個隨處可見的基本場景。
目標是在單獨的分支中實現新功能,然後將其推送到遠程存儲庫(然後您還需要創建到主分支的拉取請求,但這超出了本課的範圍)。
這樣做需要什麼?
-
獲取主分支中的所有當前更改(例如,“master”)。
-
從這個主要分支,為您的工作創建一個單獨的分支。
-
實施新功能。
-
去主分支檢查我們工作時是否有任何新的變化。如果沒有,那麼一切都很好。但是,如果有變化,那麼我們將執行以下操作:轉到工作分支並將更改從主分支重新設置為我們的分支。如果一切順利,那就太好了。但完全有可能會發生衝突。碰巧的是,它們可以提前解決,而不會在遠程存儲庫中浪費時間。
你想知道為什麼你應該這樣做嗎?這是一種禮貌,並且可以防止在將您的分支推送到本地存儲庫後發生衝突(當然,仍然有可能發生衝突,但會變得更小)。
-
將您的更改推送到遠程存儲庫。
如何從遠程服務器獲取更改?
我們通過新的提交向 README 添加了描述,並希望獲得這些更改。如果在本地存儲庫和遠程存儲庫中都進行了更改,那麼我們將被邀請在合併和變基之間進行選擇。我們選擇合併。
輸入 CTRL+T:
您現在可以看到 README 是如何更改的,即從遠程存儲庫中提取更改,並且在右下角您可以看到來自服務器的更改的所有詳細信息。
基於master新建一個分支
這裡的一切都很簡單。
轉到右下角並單擊Git: master。選擇+ 新分支。
選中Checkout branch複選框並輸入新分支的名稱。在我們的例子中:這將是readme-improver。Git: master然後將更改為Git: readme-improver。
讓我們模擬並行工作
要出現衝突,就必須有人製造它們。
我們將通過瀏覽器使用新的提交來編輯 README,從而模擬並行工作。就好像有人在我們處理同一個文件時對它進行了更改。結果會發生衝突。我們將從第 10 行中刪除單詞“fully”。
實現我們的功能
我們的任務是更改 README 並為新文章添加描述。也就是說,Git 中的工作是通過 IntelliJ IDEA 進行的。添加這個:
更改已完成。現在我們可以創建一個提交。按CTRL+K,這給了我們:
在創建提交之前,我們需要仔細查看此窗口提供的內容。
在Commit Message部分,我們編寫與提交相關的文本。然後要創建它,我們需要單擊Commit。
我們寫 README 已經更改並創建提交。左下角會彈出一個警告,其中包含提交的名稱:
檢查主分支是否發生變化
我們完成了任務。有用。我們編寫了測試。一切安好。但是在推送到服務器之前,我們仍然需要檢查主分支是否有變化。怎麼會這樣?很容易:有人在您之後收到任務,並且有人完成任務的速度比您完成任務的速度快。
所以我們需要去master分支。為此,我們需要執行以下屏幕截圖右下角所示的操作:
在 master 分支中,按CTRL+T從遠程服務器獲取其最新更改。查看發生了什麼變化,您可以輕鬆地看到發生了什麼:
“fully”這個詞被刪除了。也許營銷人員認為它不應該這樣寫,並給開發人員一個任務來更新它。
我們現在有一個最新版本的 master 分支的本地副本。返回readme-improver。
現在我們需要將更改從 master 分支重新設置為我們的。我們這樣做:
如果你做的一切都正確並跟著我,結果應該在 README 文件中顯示衝突:
在這裡,我們還有很多信息需要了解和吸收。此處顯示的是存在衝突的文件列表(在我們的示例中為一個文件)。我們可以從三個選項中進行選擇:
- 接受你的——只接受來自 readme-improver 的更改。
- 接受他們的——只接受主人的改變。
- 合併——自己選擇要保留的和丟棄的。
目前尚不清楚發生了什麼變化。如果 master 分支有變化,那肯定是那裡需要的,所以我們不能簡單地接受我們的變化。因此,我們選擇merge:
這裡我們可以看到分為三部分:
- 這些是自述文件改進程序的更改。
- 合併的結果。目前,它是更改之前存在的內容。
- 來自 master 分支的更改。
我們需要產生一個讓每個人都滿意的合併結果。查看我們更改之前更改的內容,我們意識到他們只是刪除了“fully”這個詞。好的沒問題!這意味著我們還將在合併結果中刪除它,然後添加我們的更改。更正合併結果後,我們可以單擊Apply。
然後會彈出一個通知,告訴我們變基成功了:
那裡!我們通過 IntelliJ IDEA 解決了第一個衝突。
將更改推送到遠程服務器
下一步是將更改推送到遠程服務器並創建拉取請求。為此,只需按CTRL+SHIFT+K即可。然後我們得到:
在左側,將有一個尚未推送到遠程存儲庫的提交列表。右側將是所有已更改的文件。就是這樣!按Push,你會體驗到快樂 :)
如果推送成功,你會在右下角看到這樣的通知:
獎勵:創建拉取請求
讓我們轉到 GitHub 存儲庫,我們看到 GitHub 已經知道我們想要什麼:
單擊比較和拉取請求。然後單擊創建拉取請求。因為我們提前解決了衝突,現在在創建一個pull request的時候,我們可以立即合併它:
就這樣吧!
GO TO FULL VERSION