Git 分支的建立與切換 —— Git 學習筆記 14
Git 分支的建立與切換
幾乎所有的版本控制系統都以某種形式支援分支。 使用分支意味著你可以把你的工作從開發主線上分離開來,以免影響主線的開發。 在很多版本控制系統中,這是一個略微低效的過程 —— 常常需要完全建立一個原始碼目錄的副本。對於大專案來說,這樣的過程會耗費很多時間。
有人把 Git 的分支模型稱為它的“必殺技特性”,也正是因為這一特性,使得 Git 從眾多版本控制系統中脫穎而出。 為何 Git 的分支模型如此出眾呢? Git 處理分支的方式可謂是超級輕量,建立新分支這一操作幾乎能在瞬間完成,並且在不同分支之間切換也是一樣便捷。
與許多其它版本控制系統不同,Git 鼓勵在工作流程中頻繁地使用分支與合併。理解和精通這一特性,你便會意識到 Git 是如此強大而又獨特,並且從此真正改變你的開發方式。
Git 分支的本質
Git 的分支,其本質上僅僅是指向提交物件的可變指標。說它“可變”是因為它會在每次的提交操作中自動向前移動。 Git 的預設分支名字是 master。 在多次提交操作之後,你其實已經有一個指向最後那個提交物件的 master 分支。
Git 的 “master” 分支並不是一個特殊分支。 它跟其它分支完全沒有區別。 之所以幾乎每一個倉庫都有 master 分支,是因為 git init 命令預設建立它,並且大多數人都懶得去改動它。
分支建立
Git 是怎麼建立新分支的呢? 很簡單,它只是為你建立了一個可以移動的新的指標。 比如,建立一個 testing 分支, 你需要使用 git branch 命令:
$ git branch testing
這會在當前所在的提交物件上建立一個指標。
那麼,Git 又是怎麼知道當前在哪一個分支上呢? 也很簡單,它有一個名為 HEAD
的特殊指標。
請注意它和許多其它版本控制系統(如 Subversion 或 CVS)裡的 HEAD 概念完全不同。 在 Git 中,它是一個指標,指向當前所在的本地分支(譯註:將 HEAD
想象為當前分支的別名)。 在本例中,你仍然在 master 分支上。 因為 git branch
命令僅僅建立一個新分支,並不會自動切換到新分支上去。
你可以簡單地使用 git log
命令檢視各個分支當前所指的物件。 提供這一功能的引數是 --decorate
。
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new
34ac2 fixed bug #1328 - stack overflow under certain conditions
98ca9 initial commit of my project
正如你所見,當前 “master” 和 “testing” 分支均指向校驗和以 f30ab 開頭的提交物件,且當前在 master 分支(因為 HEAD 指向 master)。
分支切換
要切換到一個已存在的分支,你需要使用 git checkout
命令。 現在切換到新建立的 testing 分支去:
$ git checkout testing
這樣 HEAD 就指向 testing 分支了。
那麼,切換分支會給我們帶來什麼影響呢? 現在不妨再提交一次:
$ vim test.rb
$ git commit -a -m 'made a change'
提交後的示意圖如下:
看到了嗎?你的 testing 分支向前移動了,但是 master 分支卻沒有,它仍然指向執行 git checkout 時所指的物件。 這就有意思了,現在我們切換回 master 分支看看:
$ git checkout master
這條命令做了兩件事。 一是使 HEAD 指回 master 分支,二是將工作目錄恢復成 master 分支所指向的快照內容。 也就是說,你現在做修改的話,專案將始於一個較舊的版本(f30ab)。 本質上來講,這就是忽略 testing 分支所做的修改,以便於向另一個方向進行開發。
分支切換會改變你工作目錄中的檔案
在切換分支時,一定要注意你工作目錄裡的檔案會被改變。 如果是切換到一個較舊的分支,你的工作目錄會恢復到該分支最後一次提交時的樣子。 如果 Git 不能幹淨利落地完成這個任務,它將禁止切換分支。
我們不妨再做些修改並提交:
$ vim test.rb
$ git commit -a -m 'made other changes'
現在,這個專案的提交歷史已經產生了分叉。 因為剛才你建立了一個新分支,並切換過去進行了一些工作,隨後又切換回 master 分支進行了另外一些工作。
你可以簡單地使用 git log 命令檢視分叉歷史。 執行git log --oneline --decorate --graph--all
,它會輸出你的提交歷史、各個分支的指向以及專案的分支分叉情況。
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD -> master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
由於 Git 的分支實質上僅是包含所指物件校驗和(長度為 40 的 SHA-1 值字串)的檔案,所以它的建立和銷燬都非常高效。 建立一個新分支就相當於往一個檔案中寫入 41 個位元組(40 個字元和 1 個換行符),如此之簡單能不快嗎?
這與過去大多數版本控制系統形成了鮮明的對比:它們在建立分支時,將所有的專案檔案都複製一遍,並儲存到一個特定的目錄。 完成這樣繁瑣的過程通常需要好幾秒鐘,有時甚至需要好幾分鐘。所需時間的長短,完全取決於專案的規模。而在 Git 中,任何規模的專案都能在瞬間建立新分支。
參考資料
《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)
相關文章
- git建立與切換分支Git
- Git分支切換Git
- git的跟蹤分支和遠端跟蹤分支學習筆記Git筆記
- Git 的安裝與初次使用 —— Git 學習筆記 03Git筆記
- 如何更優雅地切換 Git 分支Git
- git學習筆記Git筆記
- Git 的特點—— Git 學習筆記 02Git筆記
- git checkout 和 git reset 的區別 —— Git 學習筆記 09Git筆記
- Pro Git 學習筆記Git筆記
- git學習筆記 1Git筆記
- git學習筆記1Git筆記
- git rebase(變基)—— Git 學習筆記 19Git筆記
- 取得 Git 倉庫 —— Git 學習筆記 04Git筆記
- 2024-07-15 git新建分支然後git checkout 到新分支發現無法切換 ==》git pull 拉一下再切Git
- Git和Maven的學習筆記GitMaven筆記
- git checkout 命令詳解—— Git 學習筆記 16Git筆記
- git status 命令總結 —— Git 學習筆記 06Git筆記
- git入門學習筆記Git筆記
- Git極簡學習筆記Git筆記
- git 從master建立新的分支GitAST
- Git使用gh-pages分支切換到master分支錯誤pathspec master did not match any files known to gitGitAST
- Git 系列教程(14)- 遠端分支Git
- git切換遠端分支並拉取最新程式碼Git
- Git分支建立和刪除Git
- Myth 關於Git的學習筆記Git筆記
- Git 分支 - 分支的新建與合併Git
- git cherry-pick 詳解 —— Git 學習筆記 18Git筆記
- git reset 命令詳解(一)—— Git 學習筆記 07Git筆記
- git reset 命令詳解(二)—— Git 學習筆記 08Git筆記
- 廖雪峰Git學習筆記1-Git簡介Git筆記
- 20190228 學習筆記——廖雪峰 git筆記Git
- Git 簡單使用學習筆記Git筆記
- 切換分支時:pathspec master did not match any file(s) known to gitASTGit
- Git(12)-- Git 分支 - 分支簡介Git
- fetch 與引用規格(refspec)—— Git 學習筆記 23Git筆記
- Git檢視分支建立時間Git
- IDEA如何快速地切換git分支程式碼,本地和遠端的IdeaGit
- git checkout 對工作目錄的影響 —— Git 學習筆記 21Git筆記