一篇文章學會Git版本管理

本文主要介紹Git版本控制工具的具體使用,並不介紹其安裝,具體安裝可自行上網搜索。 本文全部操做均在Linux環境進行,但命令自己並不區分平臺,在Windows平臺也可正常運行。 爲了便於你們進行實操練習,本文使用的遠程Git庫是GitHub,能夠很方便的申請一個帳戶。 做者: SunnyZhanggit

簡述

Git是一個分佈式的版本控制工具,其在使用上要比SVN等版本控制工具稍顯複雜。爲了便於理解,本文經過圖文方式詳細介紹Git的使用,以便於快速掌握Git。Git涉及的主要概念和命令如圖所示。理解上述概念後,基本可使用Git完成平常開發工做。github

圖1 Git數據流圖

從上圖能夠看出Git從概念上分爲3個大的區域,分別是工做空間、本地倉庫和遠程倉庫。另外還有一個暫存區域,也稱爲索引區。下面咱們看一下各個區域是作什麼的。體現Git是分佈式版本控制的關鍵點是它具有一個本地倉庫,其實平時的版本控制工做都是在本地庫操做,若是不涉及團隊協做或者備份,甚至能夠只使用本地庫便可。bash

  1. 工做空間:其實就是咱們在操做系統上的工做目錄。咱們可以經過操做系統的文件管理命令進行查看(例如在Linux上經過ls命令)。
  2. 本地倉庫:工做空間有一個隱藏目錄.git,這個目錄及其內容並隸屬工做空間,而是Git的本地倉庫。它是用來實現版本控制的。
  3. 遠程倉庫: 遠程倉庫是存儲在遠程服務器上的倉庫,主要實現多用戶的協同。
  4. 暫存區: 暫存區通常存放在 ".git目錄下" 下的index文件(.git/index)中,因此咱們把暫存區有時也叫做索引(index)。

建立工做空間

爲了保持文章的完整性,這裏囉嗦一下。建立工做空間其實就是建立一個本地目錄。在Linux平臺執行以下命令便可。服務器

mkdir gittest
複製代碼

而後切換到該目錄,並在裏面隨便建立一個文件,能夠執行以下命令。微信

cd gittest
    echo "hello itworld123" > test.md
複製代碼

完成上述操做後,咱們能夠看一下工做空間(其實就是一個本地目錄,沒有什麼高大上的)。 分佈式

圖2 本地工做空間

建立本地倉庫(git init)

建立本地倉庫其實很是簡單,保持在剛纔建立的文件夾內部(工做空間)。經過執行git init命令就能夠初始化一個本地倉庫。工具

git init
複製代碼

完成本地倉庫的建立以後,咱們能夠看到在目錄下多出一個.git的隱藏目錄,Git就是經過這個目錄裏面的內容實現版本控制的。 測試

圖3 本地倉庫的原理
咱們能夠看一下這個目錄裏面都包含什麼內容。具體文件的含義超出本文的介紹範圍,本文不作過多解釋。這裏只是對該目錄有個感性的認識。
圖4 git目錄的介紹

查看狀態(git status)

建立完成本地倉庫以後就能夠查看工做區的狀態了。經過git status命令能夠查看工做空間的狀態(也就是文件的被管理狀況)。字體

git status
複製代碼

執行該命令後,能夠看到在該工做區有一個文件,且處於未管理狀態。fetch

圖5 工做區狀態

若是在沒有建立本地倉庫的狀況下執行該命令會有相應的報錯,其內容大概是這樣的:fatal: Not a git repository (or any of the parent directories): .git

添加文件(git add)

好吧,通過上面的操做其實咱們已經有了一個本地倉庫了,可是本地倉庫內部並無管理任何內容。咱們這一步作的就是讓他管理一個文件。咱們在前面工做空間中已經建立了一個名爲'test.md'的文件了,這是個普通的文本文件,內容是"hello itworld123"。咱們這步先把它管理起來,具體執行以下命令。

git add test.md
複製代碼

此時就將該文件添加到了暫存區。而後咱們在執行如下git status命令,能夠看到以下結果。此時該文件已經被管理起來了,從提示咱們能夠看到這個文件尚未提交。沒有提交的意思就是尚未真正在本地倉庫裏面,只是在暫存區而已。

圖6 添加文件後狀態

提交文件(git commit)

提交文件其實就是將文件提交到本地庫,也就是開始進行真正的版本管理了。具體能夠經過執行以下命令,其後面的-m選項表示該次提交的註釋內容。

git commit -m "add new file"
複製代碼

完成提交後會有相應的返回,提示提交的結果是怎樣的。

圖7 提交提示

完成提交後,咱們能夠在看一下這個工做空間的狀態。能夠看到此時工做空間的內容已經與本地倉庫徹底一致。

圖8 提交後狀態

查看提交日誌(git log)

完成提交以後,在本地倉庫已經有了咱們剛纔提交的內容。也就是說如今本地倉庫已經對咱們的內容進行版本控制了。那麼,咱們怎麼知道已經作了哪些提交呢?這個時候git log命令就派上用場了。從字面上咱們也能猜出大概用途來,這個命令是用來查看提交日誌的。

git log
複製代碼

圖9 提交日誌查詢

從上圖能夠看到提交的基本信息,包括提交的UUID(黃色字體)、做者、日誌和描述信息等內容。

查看提交詳情(git show)

若是咱們想看一下提交的詳細內容又該怎麼辦呢?經過git show命令能夠查看某一次提交的詳細內容。以上次提交爲例:

git show 4909da5e6097e2f50c36ad892a18fd6f2527d4c1
複製代碼

圖10 提交日誌詳情

由上圖能夠看到提交的詳細內容,除了上一個命令所涉及的簡要信息外,還包括具體修改的那個文件,哪一行,以及具體修改的內容等等。

查看工做空間修改狀況(git diff)

咱們在本地進行修改後,有的時候想了解當前工做區的內容做了哪些修改,這個時候可使用git diff命令進行查看。

git diff
複製代碼

執行該命令是查看工做空間與暫存區的差別狀況。好比咱們在test.md文件中增長一行,此時執行git diff命令,如圖綠色的部分就是咱們新加的內容。

圖11 工做區差別詳情

可是若是咱們把這個文件加入暫存區,而後在執行相同的命令,這時咱們將看不到任何差別提示。固然該命令不只僅可以實現工做區與暫存區的對比,還能實現更復雜的對比功能。這裏本文暫時不作介紹,後面再詳細介紹。

恢復到某個點(git reset)

在修改代碼的時候常常會出現改了不少代碼致使程序沒法正常運行的狀況,這個時候想回退到某個版本,而後把修改的代碼慢慢加進去。Git提供了git reset命令來解決代碼回退的問題。好比咱們對剛纔添加的代碼不滿意,想經過Git命令回退到以前的版本。這是須要找到指望回退版本的commit id,而後執行以下命令。

git reset --hard 4909da5e6097e2f50c36ad892a18fd6f2527d4c1
複製代碼

執行成功後,能夠看到以下提示,而且文件的內容已經被回退到該版本。

圖12 回退代碼

該命令一樣有更爲豐富的功能,不只能夠實現上述的代碼回退,還能夠實現本地倉庫、暫存區和遠程倉庫的回退,本文暫時不作介紹。

建立分支(git branch)

首先介紹一下什麼是分支,分支( branches ) 是指在開發主線中分離出來,作進一步開發(好比新特性)而不影響到原來主線。實際上在咱們建立完本地倉庫時,就已經有一個_分支_了,只不過這個分支是主分支,也叫主線(master)。如圖所示,在實際應用中除了主分支外還會有其它分支,好比dev分支用於開發新特性。當完成新特性開發後,將代碼統一合併到主分支中。

圖13 分支的概念

咱們先了解一下咱們工做空間的分支狀況,經過命令git branch -l能夠看到本地分支。在咱們的測試環境運行該命令能夠看到當前以及存在的分支。

圖14 建立分支

咱們前面提交的內容都是直接提交到主線的。若是咱們開發一個新的特性,直接提交到主線在人多的狀況下會很是亂。所以咱們能夠建立一個分支,等特性開發完成後再合併到主線。執行git branch命令能夠建立一個新的分支。

git branch branch0
複製代碼

建立完成後,咱們經過git branch -l能夠看到已經有一個新的分支,名稱爲branch0。

圖15 建立分支後狀態

若是仔細觀察就會發現,此時master分支的顏色是綠色的,並且前面有個*,這說明當前工做空間仍然在master分支。若是想切換到新的分支怎麼辦呢?可使用下面介紹的命令。

切換分支(git checkout)

經過git checkout命令能夠將工做空間切換到新建立的分支。執行該命令進行分支切換,而後經過git branch -l能夠看到發生的變化,此時branch0分支變成了綠色。

git checkout branch0
複製代碼

圖15 切換分支後狀態

切換分支之後,再提交的代碼就位於新的分支。須要注意的是,若是在分支作了一些修改,但尚未提交,這時切換分支會丟失已經作得的修改,所以切換以前須要提交代碼。

合併分支(git merge)

假設咱們在branch0分支已經添加了一些內容,並進行了提交。此時咱們想將這些內容合併到主分支中。合併的方法就是先切換到主分支,而後執行git merge命令。

git merge branch0
複製代碼

以下圖是整個合併分支的過程,紅線上面的是branch0分支的test.md文件的內容,綠線上面是master分支中test.md文件的內容,前者比後者多3行內容(含1行空行),執行合併命令後再看master分支中test.md的內容已經與branch0中的一致了。

圖16 合併分支

添加遠程庫(git remote add)

其實咱們前面玩了半天,都是在本地玩的,壓根沒有涉及Git服務器的任何事情。若是要多人協同確定要涉及到一個服務節點,這個服務節點其實相似於中轉站的概念,跟SVN服務有着本質的區別。前面說了咱們以github爲例進行介紹。假設咱們在github上已經有了一個空的遠程庫(假設遠程庫路徑爲https://github.com/xxx/test.git),此時遠程庫沒有任何內容。此時咱們能夠經過git remote add命令添加遠程庫。

git remote add origin https://github.com/xxx/test.git
複製代碼

添加遠程庫後,其實並無對遠程庫作任何事情,遠程庫仍是空的。這裏只是添加了本地倉庫與遠程倉庫的關聯關係。其中origin是遠程倉庫的一個代名詞,可使用其它任何名稱,這裏只是慣用法而已。

本地推送到遠程(git push)

添加完關聯關係以後,咱們就能夠將本地倉庫推送到遠程服務器上,例如咱們將本地的master分支推送到github上,執行以下命令,過程當中須要咱們輸入github上註冊的用戶名及對應的密碼。

git push origin master
複製代碼

圖17 推送本地倉庫到遠程

完成該操做後,能夠登陸github看一下遠程倉庫的狀況。能夠看到在github上的遠程倉庫已經具有了一個master分支,且包含與本地倉庫同樣的內容。

圖18 推送本地倉庫到遠程

除了第一次向遠程倉庫推送內容外,咱們後面修改代碼後想向遠程倉庫提交代碼使用的也是這個命令。默認狀況下,git會將代碼推送到與本地分支同名的遠程分支。

咱們提交代碼的通常流程是這樣的:添加到暫存區(git add),提交到本地倉庫(git commit),最後推送到遠程倉庫(git push),具體能夠參考圖1。

克隆遠程倉庫(git clone)

若是咱們來了一個新同事,須要下載遠程倉庫的代碼進行開發怎麼辦?這個使用就用到了克隆命令,克隆命令能夠將遠程倉庫的內容克隆一份,生成一個如出一轍的本地倉庫,同時會生成工做空間的內容。須要知道的是,默認狀況下工做空間的內容是master分支的內容,若是須要其餘分支,則須要建立本地分支,而且進行切換。例如咱們從測試用的github上克隆上文推送的代碼,假如咱們克隆到一個新的文件夾gittest1,執行以下命令後,能夠看到克隆後gittest1下面已經具備master分支的內容。

git clone https://github.com/xxx/test.git gittest1
複製代碼

圖19 克隆遠程倉庫

下載遠程倉庫的更新(git fetch/pull)

在多人協同的狀況下,會不斷的有人向遠程倉庫提交新內容。爲了保證代碼的同步,咱們須要將遠程代碼拉到本地,git有2個命令能夠將遠程倉庫的內容拉到本地,一個是pull,能夠將遠程倉庫的代碼拉到本地倉庫,同時合併到本地工做空間;另外一個是fetch命令,這個命令只將遠程倉庫的內容更新到本地倉庫。

git fetch
複製代碼

執行上面命令能夠將遠程倉庫的內容拉取到本地倉庫,但並不會更新本地工做空間。如圖所示,咱們將gittest中文件添加一行(a5),而後同步到遠程倉庫。而後切換到目錄gittest1,並經過git fetch命令拉取遠程倉庫的內容。能夠看到gittest1中test.md文件中的內容並無變化。而後咱們再執行git merge命令,該命令會將本地倉庫相同分支的內容更新到工做空間,此時再查看文件內容,已經更新爲最新的內容。

圖19 拉取遠程倉庫內容

使用git pull命令能夠直接將文件內容更新到工做空間,如圖咱們在gittest文件夾中test.md添加一行a6,並同步到遠程倉庫。而後,咱們切換到gittest1文件夾執行git pull命令,能夠看到文件內容已經更新。

圖19 拉取遠程倉庫內容

查看代碼的做者(git blame)

在很大的項目中,團隊成員會不少,有時候咱們須要知道某一段代碼的做者。這時可使用git blame命令。經過該命令能夠獲取提交的ID、做者和時間等信息。

git blame -L 5 test.md
複製代碼

圖19 拉取遠程倉庫內容

寫到這裏其實已經涵蓋了Git的大部分經常使用命令,基本上能夠知足咱們平常開發使用。可是,Git的功能是如此的強大,以致於咱們介紹三天三夜也沒法講完。本文先介紹到這裏,後面再詳細介紹每條命令的用法。

關注做者微信公衆號,更及時的獲取原創IT技術文章。

公衆號二維碼
相關文章
相關標籤/搜索