【Git學習筆記4】關於遠程倉庫的必知、創建與合併分支(fast foeward模式)及解決衝突

  • 2019 年 11 月 11 日
  • 筆記

一、遠程倉庫

(1)前言

【Git筆記1】本地項目與GitHub遠程倉庫互聯中,我們已經知道遠程倉庫這麼回事,但是並不知道這究竟是啥?

那麼,我們簡單說說吧。同一個Git倉庫可以分布在不同的機器上,他們是怎麼分布的?剛剛開始只有一台機器有一個原始版本庫,別的機器就「克隆」這個原始版本庫在每台機器上的版本庫是一樣的,沒有主次之分。

Github提供Git倉庫託管服務。只要註冊一個GitHub帳號。就可以免費獲得Git遠程倉庫。你可以從Github這個「伺服器」倉庫克隆項目到自己的電腦上,你和你的小夥伴各自把各自的提交推送到Github倉庫里,也可從github倉庫中拉取小夥伴的提交。

關於遠程倉庫的建立:可見【Git筆記1】本地項目與GitHub遠程倉庫互聯第3點介紹的遠程倉庫。

(2)添加遠程庫

場景:你已經在本地創建了一個Git倉庫後,又想在GitHub創建一個Git倉庫,並且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作。詳細操作請看【Git筆記1】本地項目與GitHub遠程倉庫互聯第4點介紹的將本地倉庫push到Github。

這裡說幾個點:

  1. 添加後,Git默認遠程庫的名字就是origin,也可以改成別的,但是origin這個名字一看就知道是遠程庫;
  2. 關於git push -u origin master的解讀是將本地的master分支推送到origin主機同時指定origin為默認主機,把本地庫的內容推送到遠程,用git push命令,實際上是把當前分支master推送到遠程;由於遠程庫是空的,我們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容;推送到遠程庫新的master分支,還會把本地的master分支和遠程的master分支關聯起來;在以後的推送或者拉取時就可以簡化命令直接使用git push,-u選項指定一個默認主機,(origin就是默認主機),不帶任何參數的git push,默認只推送當前分支,這叫做simple方式;此外,還有一種matching方式,會推送所有有對應的遠程分支的本地分支;Git 2.0版本之前,默認採用matching方法;
  3. 在經過2的指令後,只要本地作了提交,就可以通過命令:git push origin master,把本地master分支的最新修改推送至GitHub,現在,你就擁有了真正的分散式版本庫!
  4. 要關聯一個遠程庫,使用命令:git remote add origin git@server-name:path/repo-name.git;
  5. 關聯後,使用命令git push -u origin master,第一次推送master分支的所有內容,此後,每次本地提交後,只要有必要,就可以使用命令git push origin master推送最新修改;
  6. 分散式版本系統的最大好處之一,沒有聯網都可以正常工作,當有網路的時候,再把本地提交推送一下就完成了同步,而SVN在沒有聯網的時候是拒絕幹活的!

(3)從遠程庫克隆

假設我們從零開發,那麼最好的方式是先創建遠程庫,然後,從遠程庫克隆

  • 第一步:登陸GitHub,創建一個新的倉庫。建議不要勾選Initialize this repository with a README。創建完畢後,可以看到README.md文件;
  • 第二步:遠程庫已經準備好了,下一步是用命令git clone克隆一個本地庫:

注意:

如果有多個人協作開發,那麼每個人各自從遠程克隆一份就可以了。GitHub給出的地址不止一個,還可以用ssh。

Git支援多種協議,默認的git://使用ssh,但也可以使用https等其他協議。使用https除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http埠的公司內部就無法使用ssh協議而只能用https。

二、創建與合併分支

需要記住的命令:

  • git branch //查看分支
  • git branch <name> //創建分支
  • git checkout <name>或者git switch <name> //切換分支
  • git checkout -b <name>或者git switch -c <name> //創建+切換分支
  • git merge <name> //合併某分支到當前分支
  • git branch -d <name> //刪除分支

預備知識:

每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。

一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點,HEAD指向誰,誰就是當前分支。

每次提交,master分支都會向前移動一步,這樣,隨著你不斷提交,master分支的線也越來越長。當我們創建新的分支,例如dev時:

Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上,圖示:

這裡,git checkout -b dev 相當於兩句話,git branch dev(建一個分支),git checkout dev (切換到這個分支)。可以使用git branch命令查看當前分支。

git branch命令會列出所有分支,當前分支前面會標一個*號,然後,我們就可以在dev分支上正常提交。你也可以使用 git branch -a (顯示的是本地版本區和遠程庫的全部分支)

對readme.txt做個修改,加上一行:Creating a new branch is quick。難道你每次都是打開txt,然後添加?我可是用vim,以後有機會出點關於vim的學習筆記。

我這裡以添加Creating a new branch is quick為例,簡單說下步驟吧vim <file>打開文件。

輸入vim readme.txt,進入是命令行模型,不能編輯,按i進入編輯模式,然後寫上需要編輯的內容,然後按esc進行命令行模型,輸入:wq(保存退出)。:wq在介面的最下面會出現的。

因為我已經保存了,所以我用:q!(不保存文件,退出vi編輯器 )。然後提交,切換到master分支,查看一下readme.txt.

發現剛才添加的內容不見了!

不慌,因為那個提交是在dev分支上,而master分支此刻的提交點並沒有變:

我們把dev分支的工作成果合併到master分支上:

git merge命令用於合併指定分支到當前分支。合併後,再查看readme.txt的內容,就可以看到,和dev分支的最新提交是完全一樣的:

注意:git merge命令後,有Fast-forward資訊,Git告訴我們,這次合併是「快進模式」,也就是直接把master指向dev的當前提交,所以合併速度非常快。

當然,也不是每次合併都能Fast-forward,因為還有衝突需要解決,我們後面會學習其他方式的合併。合併完成後,就可以放心地刪除dev分支了:

Switch了解一波,實際上,切換分支這個動作,用switch更科學,因為我們注意到切換分支使用git checkout <branch>,而前面講過的在工作區進行撤銷修改則是git checkout — <file>,同一個命令,有兩種作用,確實有點令人迷惑。

因此,最新版本的Git提供了新的git switch命令來切換分支,創建並切換到新的dev分支,可以使用:git switch -c dev,直接切換到已有的master分支,可以使用:git switch master

三、解決衝突

合併分支往往也不是一帆風順的,當Git無法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。解決衝突就是把Git合併失敗的文件手動編輯為我們希望的內容,再提交。

什麼情況會有衝突?請看下面例子,我們一起學習鴨。創建feature1分支,繼續我們的新分支開發:

修改readme.txt最後一行,改為:Creating a new branch is quick AND simple.

在feature1分支上提交:

切換到master分支,Git還會自動提示我們當前master分支比遠程的master分支要超前7個提交。

在master分支上把readme.txt文件的最後一行改為:Creating a new branch is quick & simple.

現在,master分支和feature1分支各自都分別有新的提交,變成了這樣:

這就有衝突啦,這種情況下,Git無法執行「快速合併」,只能試圖把各自的修改合併起來,但這種合併就可能會有衝突。你可以試一下git merge feature1

Git告訴我們,readme.txt文件存在衝突,必須手動解決衝突後再提交。

git status也可以告訴我們衝突的文件,如下圖:

我們可以直接查看readme.txt的內容:

Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,我們vim打開修改如下後保存:

再提交:

現在,master分支和feature1分支變成了下圖所示:

用git log –graph命令可以看到分支合併圖。為了簡單查看:git log –graph –pretty=oneline –abbrev-commit

別忘記了把分支刪除哈,git branch -d feature1

至此,【Git學習筆記4】關於遠程倉庫的必知、創建與合併分支(fast foeward模式)及解決衝突內容已經講述完畢,前三期的內容在下面的往期回顧中查看。Git系列是一個偏向於實踐的,建議邊看邊實踐,或收藏待看。