筆記-git中的幾個基本概念
這篇筆記旨在理解幾個核心的git基本概念,如果對git了解較少,可以先看git基本教程。
這裏推薦一個:廖雪峰-Git教程
commit(提交) 與 branch(分支)
版本號
commit是git管理的基本單位,在有多個分支的情況下,這些commit就構成了一顆commit樹。
每個提交會有一個版本號(commit id
),類似3628164fb26d48395383f8f31179f24e0882e1e0
,即這個提交的命名,是用十六進制表示的一個SHA1計算出來的一個非常大的數字。
實際使用中,不必要寫全這串字符,使用前面一部分,如前8位,git能唯一識別出來某個提交就可以了。
文中的提交
二字,就是指一次commit
,也就是一個版本,可以用版本
二字代替,習慣使用提交這個說法了。
分支
從形式上看,分支(branch)就是從樹的葉子節點到跟節點的一條線(可能有分叉),那git中是如何表示這條線的呢?或者換個問法,git中的分支名,究竟是表示什麽呢。
其實分支名,如dev
表示的只是dev這個分支上最新的那次提交,或者說,dev
這三個字母,這個字符串,就是dev分支上最新的那個提交的別名,或者理解為那個最新提交的一個引用。
git中“並沒有”分支,只有
commit
; 分支只是對某個特定commit
的引用
如下圖所示,dev
只是 commit-6 的一個引用,如果在 commit-6 的基礎上,做了一次新的提交,則dev指向這次新的提交。每個提交(除了第一次提交)都會有一個或者兩個父節點提交,如圖中的 commit-4 ,就是一次合並提交,擁有兩個父節點。
HEAD
git中用 HEAD
表示當前分支的最新的那個提交,即如果在dev分支,則 HEAD
表示(指向)的就是dev,也就是指向commit-6。HEAD^
表示 HEAD
的前一個提交,即 commit-5; HEAD^^
表示 HEAD
的前兩個提交,前100個可以寫成 HEAD~100
,相應的,前一個也可以寫成 HEAD~1
。
本地倉庫 和 遠程倉庫
常見的GIT 工作區
、 暫存區
、 本地倉庫
和 遠程倉庫
的示意圖。
看這幅圖會理解git只有兩個倉庫,本地倉庫
和 遠程倉庫
;但如果理解為三個倉庫,才能更好地理解有些git命令或操作是什麽回事。哪三個倉庫?
本地工作倉庫
、 本地遠程倉庫
遠程倉庫
名字是隨便取的,重點在於便於理解。看下面這幅圖。
這其中多了一個Local Remote repository
, 即上面提到的本地遠程倉庫
,這個倉庫就是遠程倉庫在本地的一個拷貝,目的是為了和遠程倉庫保持一致。
常聽到關於pull
命令的解釋就是,pull 是 fetch 和 merge 的結合,完成的實際上是先fetch,再merge。 如果沒有本地遠程倉庫
這個概念,其實不是特別好理解這句話。
git fetch
做的其實是把遠程倉庫
的更新全部拉取到本地遠程倉庫
(註意,是全部,不只是當前分支)。而這裏的merge,完整的寫出來應該是這樣(假設在dev分支):
/* pull */
git pull origin dev
/* fetch + merge */
git fetch
git merge origin/dev
這裏的origin/dev
指的就是本地遠程倉庫
中的dev分支,它剛剛通過fetch命令,從真正的遠端倉庫拉取到了最新的數據,然而,你自己的dev分支並沒有更新,需要將本地遠程倉庫
中的dev分支(名字是origin/dev
)merge到本地的dev分支。 pull就是完成的上面兩步。 所以pull之後,本地的dev就直接更新了,所以才感受不到origin/dev的存在。
理解了 本地遠程倉庫
,可以方便地完成一些操作。如,現在正在 dev 分支,需要合並遠端最新的 master 分支的代碼,如何做?
之前的作法可能是這樣:
git checkout master // 切換到 master 分支
git pull origin master // 拉取遠端代碼到 master 分支
git checkout dev // 切換回 dev 分支
git merge master // 合並 master 分支
而實際上,不需要切換分支,這樣就可以:
git fetch // 更新本地遠端倉庫
git merge origin/master // 從 本地遠端倉庫 合並 master 分支
需要註意的是,這裏必須先使用 git fetch
命令,直接使用 origin/master
並不會讓本地遠端倉庫自動去遠端拉取最新的代碼。
END
筆記-git中的幾個基本概念