HEAD错邦、master 與 branch

這一節(jié)主要是幾個概念的解釋:HEAD、master 以及 Git 中非常重要的一個概念: branch厦画。

引用:commit 的快捷方式

首先,再看一次 log

git log

第一行的 commit 后面括號里的 HEAD -> master, origin/master, origin/HEAD 滥朱,是幾個指向這個 commit 的引用根暑。在 Git 的使用中,經(jīng)常會需要對指定的 commit 進行操作徙邻。每一個 commit 都有一個它唯一的指定方式——它的 SHA-1 校驗和排嫌,也就是上圖中每個黃色的 commit 右邊的那一長串字符。兩個 SHA-1 值的重復概率極低鹃栽,所以你可以使用這個 SHA-1 值來指代 commit躏率,也可以只使用它的前幾位來指代它(例如第一個 78bb0ab7d541…16b77,你使用 78bb0ab 甚至 78bb 來指代它通常也可以)民鼓,但畢竟這種沒有任何含義的字符串是很難記憶的薇芝,所以 Git 提供了「引用」的機制:使用固定的字符串作為引用,指向某個 commit丰嘉,作為操作 commit 時的快捷方式夯到。

HEAD:當前 commit 的引用

上一段里說到,圖中括號里是指向這個 commit 的引用饮亏。其中這個括號里的 HEAD 是引用中最特殊的一個:它是指向當前 commit 的引用耍贾。所謂當前 commit這個概念很簡單,它指的就是當前工作目錄所對應的 commit路幸。

例如上圖中的當前 commit 就是第一行中的那個最新的 commit荐开。每次當有新的 commit 的時候,工作目錄自動與最新的 commit 對應简肴;而與此同時晃听,HEAD 也會轉(zhuǎn)而指向最新的 commit。事實上砰识,當使用 checkout能扒、reset 等指令手動指定改變當前 commit 的時候,HEAD 也會一起跟過去辫狼。

總之初斑,當前 commit 在哪里,HEAD 就在哪里膨处,這是一個永遠自動指向當前 commit 的引用见秤,所以你永遠可以用 HEAD 來操作當前 commit

branch

HEAD 是 Git 中一個獨特的引用真椿,它是唯一的秦叛。而除了 HEAD 之外,Git 還有一種引用瀑粥,叫做 branch(分支)挣跋。HEAD 除了可以指向 commit,還可以指向一個 branch狞换,當它指向某個 branch的時候避咆,會通過這個 branch 來間接地指向某個 commit仓犬;另外蜂厅,當 HEAD 在提交時自動向前移動的時候,它會像一個拖鉤一樣帶著它所指向的 branch 一起移動周瞎。

例如上面的那張圖里黄琼,HEAD -> master 中的 master 就是一個 branch 的名字樊销,而它左邊的箭頭 ->表示 HEAD 正指向它(當然,也會間接地指向它所指向的 commit)。

如果我在這時創(chuàng)建一個 commit围苫,那么 HEAD 會帶著 master 一起移動到最新的 commit

git commit

通過查看 log裤园,可以對這個邏輯進行驗證:

git log

從圖中可以看出,最新的 commit (提交信息:"Add feature1")被創(chuàng)建后剂府,HEADmaster 這兩個引用都指向了它拧揽,而在上面第一張圖中的后兩個引用 origin/masterorigin/HEAD 則依然停留在原先的位置。

master: 默認 branch

上面的這個 master 腺占,其實是一個特殊的 branch:它是 Git 的默認 branch(俗稱主 branch / 主分支)淤袜。

所謂的「默認 branch」,主要有兩個特點:

  1. 新創(chuàng)建的 repository(倉庫)是沒有任何 commit 的衰伯。但在它創(chuàng)建第一個 commit 時铡羡,會把 master 指向它,并把 HEAD 指向 master意鲸。
  1. 當有人使用 git clone 時蓖墅,除了從遠程倉庫把 .git 這個倉庫目錄下載到工作目錄中,還會 checkout (簽出) mastercheckout 的意思就是把某個 commit 作為當前 commit临扮,把 HEAD 移動過去论矾,并把工作目錄的文件內(nèi)容替換成這個 commit 所對應的內(nèi)容)。

另外杆勇,需要說一下的是贪壳,大多數(shù)的開發(fā)團隊會規(guī)定開發(fā)以 master 為核心,所有的分支都在一定程度上圍繞著 master 來開發(fā)蚜退。這個在事實上構(gòu)成了 master 和其它分支在地位上的一個額外的區(qū)別闰靴。

branch 的通俗化理解

盡管在 Git 中,branch 只是一個指向 commit 的引用钻注,但它有一個更通俗的理解:你還可以把一個 branch 理解為從初始 commitbranch 所指向的 commit 之間的所有 commits 的一個「串」蚂且。例如下面這張圖:

master 的本質(zhì)是一個指向 3 的引用,但你也可以把 master 理解為是 1 2 3 三個 commit 的「串」幅恋,它的起點是 1杏死,終點是 3

這種理解方式比較符合 branch 這個名字的本意(branch 的本意是樹枝捆交,可以延伸為事物的分支)淑翼,也是大多數(shù)人對 branch 的理解。不過如果你選擇這樣理解 branch品追,需要注意下面兩點:

  1. 所有的 branch 之間都是平等的玄括。
例如上面這張圖,`branch1` 是 `1` `2` `5` `6` 的串肉瓦,而不要理解為 `2` `5` `6` 或者 `5` `6` 遭京。其實胃惜,起點在哪里并不是最重要的,重要的是你要知道哪雕,所有 `branch` 之間是平等的船殉,`master` 除了上面我說的那幾點之外,并不比其他 `branch` 高級热监。這個認知的理解對于 `branch` 的正確使用非常重要。

換個角度來說饮寞,上面這張圖我可以用別的畫法來表達孝扛,它們的意思是一樣的:
通過這張動圖應該能夠?qū)Α钙降取惯@個概念更好地理解了吧?
  1. branch 包含了從初始 commit 到它的所有路徑幽崩,而不是一條路徑苦始。并且,這些路徑之間也是彼此平等的慌申。
像上圖這樣陌选,`master` 在合并了 `branch1` 之后,從初始 `commit` 到 `master` 有了兩條路徑蹄溉。這時咨油,`master` 的串就包含了 `1` `2` `3` `4` `7` 和 `1` `2` `5` `6` `7` 這兩條路徑。而且柒爵,這兩條路徑是平等的役电,`1` `2` `3` `4` `7` 這條路徑并不會因為它是「原生路徑」而擁有任何的特別之處。

如果你喜歡用「樹枝」的概念來理解 Git 的 branch棉胀,一定要注意上面說的這兩點法瑟,否則在今后使用 branch 的時候就可能與出現(xiàn)理解偏差或者使用方式不當?shù)膯栴}。事實上我本人并不喜歡用這種方式來理解 branch唁奢,因為覺得它有點舍近求遠的味道:我為了「直觀」地思考霎挟,給它了一個形象的比喻,但由于它的本質(zhì)含義其實更加簡單麻掸,導致我的這種比喻反而增加了思考它時的復雜度酥夭,未免有點畫蛇添足。不過這是我自己的感受脊奋,怎么理解 branch 是個個人偏好的問題采郎,這兩種理解方式你選一個喜歡的就好。

branch 的創(chuàng)建狂魔、切換和刪除

創(chuàng)建 branch

如果你想在某處創(chuàng)建 branch 蒜埋,只需要輸入一行 git branch 名稱。例如你現(xiàn)在在 master 上:

你想在這個 commit 處創(chuàng)建一個叫做 "feature1" 的 branch最楷,只要輸入:

git branch feature1

你的 branch 就創(chuàng)建好了:

切換 branch

不過新建的 branch 并不會自動切換整份,你的 HEAD 在這時依然是指向 master 的待错。你需要用 checkout來主動切換到你的新 branch 去:

git checkout feature1

然后 HEAD 就會指向新建的 branch 了:

除此之外,你還可以用 git checkout -b 名稱 來把上面兩步操作合并執(zhí)行烈评。這行代碼可以幫你用指定的名稱創(chuàng)建 branch 后火俄,再直接切換過去。還以 feature1 為例的話讲冠,就是:

git checkout -b feature1

在切換到新的 branch 后瓜客,再次 commitHEAD 就會帶著新的 branch 移動了:

git commit

而這個時候,如果你再切換到 mastercommit竿开,就會真正地出現(xiàn)分叉了:

git checkout master
...
git commit

刪除 branch

刪除 branch 的方法非常簡單:git branch -d 名稱谱仪。例如要刪除 feature1 這個 branch:

git branch -d feature1

需要說明的有兩點:

  1. HEAD 指向的 branch 不能刪除。如果要刪除 HEAD 指向的 branch否彩,需要先用 checkoutHEAD 指向其他地方疯攒。

  2. 由于 Git 中的 branch 只是一個引用,所以刪除 branch 的操作也只會刪掉這個引用列荔,并不會刪除任何的 commit敬尺。(不過如果一個 commit 不在任何一個 branch 的「路徑」上,或者換句話說贴浙,如果沒有任何一個 branch 可以回溯到這條 commit(也許可以稱為野生 commit砂吞?),那么在一定時間后崎溃,它會被 Git 的回收機制刪除掉呜舒。)

  3. 出于安全考慮,沒有被合并到 master 過的 branch 在刪除時會失敱康臁(因為怕你誤刪掉「未完成」的 branch 跋取):

這種情況如果你確認是要刪除這個 `branch` (例如某個未完成的功能被團隊確認永久斃掉了,不再做了)般婆,可以把 `-d` 改成 `-D`到腥,小寫換成大寫,就能刪除了蔚袍。

「引用」的本質(zhì)

所謂「引用」(reference)乡范,其實就是一個個的字符串。這個字符串可以是一個 commit 的 SHA-1 碼(例:c08de9a4d8771144cd23986f9f76c4ed729e69b0)啤咽,也可以是一個 branch(例:ref: refs/heads/feature3)晋辆。

Git 中的 HEAD 和每一個 branch 以及其他的引用,都是以文本文件的形式存儲在本地倉庫 .git 目錄中宇整,而 Git 在工作的時候瓶佳,就是通過這些文本文件的內(nèi)容來判斷這些所謂的「引用」是指向誰的。

小結(jié)

這一節(jié)介紹了 Git 中的一些「引用」:HEAD鳞青、master霸饲、branch为朋。這里總結(jié)一下:

  1. HEAD 是指向當前 commit 的引用,它具有唯一性厚脉,每個倉庫中只有一個 HEAD习寸。在每次提交時它都會自動向前移動到最新的 commit
  2. branch 是一類引用傻工。HEAD 除了直接指向 commit霞溪,也可以通過指向某個 branch 來間接指向 commit。當 HEAD 指向一個 branch 時中捆,commit 發(fā)生時鸯匹,HEAD 會帶著它所指向的 branch 一起移動。
  3. master 是 Git 中的默認 branch轨香,它和其它 branch 的區(qū)別在于:
    1. 新建的倉庫中的第一個 commit 會被 master 自動指向忽你;
    2. git clone 時幼东,會自動 checkoutmaster臂容。
  4. branch 的創(chuàng)建、切換和刪除:
    1. 創(chuàng)建 branch 的方式是 git branch 名稱git checkout -b 名稱(創(chuàng)建后自動切換)根蟹;
    2. 切換的方式是 git checkout 名稱脓杉;
    3. 刪除的方式是 git branch -d 名稱
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末简逮,一起剝皮案震驚了整個濱河市球散,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌散庶,老刑警劉巖蕉堰,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異悲龟,居然都是意外死亡屋讶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門须教,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皿渗,“玉大人,你說我怎么就攤上這事轻腺±纸” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵贬养,是天一觀的道長挤土。 經(jīng)常有香客問我,道長误算,這世上最難降的妖魔是什么耕挨? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任细卧,我火速辦了婚禮,結(jié)果婚禮上筒占,老公的妹妹穿的比我還像新娘贪庙。我一直安慰自己,他們只是感情好翰苫,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布止邮。 她就那樣靜靜地躺著,像睡著了一般奏窑。 火紅的嫁衣襯著肌膚如雪导披。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天埃唯,我揣著相機與錄音撩匕,去河邊找鬼。 笑死墨叛,一個胖子當著我的面吹牛止毕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播漠趁,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼扁凛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闯传?” 一聲冷哼從身側(cè)響起谨朝,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甥绿,沒想到半個月后字币,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡共缕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年洗出,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骄呼。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡共苛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜓萄,到底是詐尸還是另有隱情隅茎,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布嫉沽,位于F島的核電站辟犀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绸硕。R本人自食惡果不足惜堂竟,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一魂毁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧出嘹,春花似錦席楚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至郎仆,卻和暖如春只祠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扰肌。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工抛寝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人曙旭。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓盗舰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夷狰。 傳聞我的和親對象是個殘疾皇子岭皂,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Git 命令行學習筆記 Git 基礎 基本原理 客戶端并不是只提取最新版本的文件快照郊霎,而是把代碼倉庫完整的鏡像下來...
    sunnyghx閱讀 3,904評論 0 11
  • GIT分布式版本控制系統(tǒng)最佳實踐 這篇文章來自于老男孩教育高級架構(gòu)師班12期的徐亮偉同學沼头。 首先感謝老男孩架構(gòu)師班...
    meng_philip123閱讀 3,394評論 4 36
  • 1,查看所有遠程分支:%git branch -r 2, 拉取遠程分支并創(chuàng)建本地分支git checkout -...
    will666閱讀 2,055評論 0 18
  • 查看倉庫狀態(tài)和文件更改 查看工作區(qū)狀態(tài):git status與最近的一次add或commit比較文件的不同:git...
    burningalive閱讀 356評論 0 0
  • 我的文章告訴我书劝,我上次發(fā)布文章的時間进倍,是2017年6月26日。 11個月购对,我的文章毫無建樹猾昆。 在這里要說一下,我是...
    早安美夕閱讀 350評論 2 1