在軟件開發(fā)過程中,Git是一種服務(wù)于項目版本管理的重要工具故硅,世界上各個開源項目倉庫諸如Github均使用git進行代碼倉庫的操作蘑险。
一般地,有兩種途徑來使用Git工具决乎,一種是第三方開發(fā)的交互式界面軟件队询,另一種則是直接使用命令行指令。使用Git交互式界面軟件來操作代碼倉庫构诚,好處是操作簡單直觀蚌斩,學(xué)習(xí)成本低。而本文的主旨在于從代碼層面上了解Git工具的操作原理范嘱,做到知其然知且其所以然送膳,遇到相關(guān)問題能夠找到正確的方法進行解決,故僅對命令行進行使用說明詳述丑蛤。
使用前須知
“The three trees” - “三棵樹”
在使用Git指令之前叠聋,各位小伙伴須將一概念熟記于心,這個概念被稱作“The three trees”受裹。下面我們用一張圖來進行理解:
Working Directory - 工作目錄
即項目所在文件夾碌补,也就是你的項目根目錄。Staged Snapshot - 臨時快照
即當(dāng)你對Working Directory中的文件進行了任何CRUD操作棉饶,并且對這些操作執(zhí)行了git add
命令厦章,此時這些文件便進入到了Staged狀態(tài)。進入到Staged狀態(tài)的文件照藻,即可以進行commit操作進入到Commit History袜啃,也可以進行reset操作回退到Unstaged狀態(tài)。下面用兩張圖來進行理解:
上圖中岩梳,對Working Directory中的www文件進行了修改囊骤,執(zhí)行g(shù)it status可以看到,www進入了git的檢測列表冀值,狀態(tài)為Unstaged也物。此時,我們再執(zhí)行git add .
列疗,得到下圖結(jié)果滑蚯,此時,www進入到了Staged Snapshot中:
- Commit History
即已提交歷史,對項目的任何修改已被提交到本地倉庫中告材,該記錄已進入到提交歷史中坤次,可通過git log
進行查詢。下圖為提交后結(jié)果:
注意:完成commit操作不等同于push到遠程分支斥赋,并不會對遠程分支造成任何影響缰猴,同時
pull
、push
以及分支概念不在本文的研究范圍中疤剑,故不做贅述滑绒。
Scope - 作用范圍
作用范圍也是Git使用中必須要掌握的一個概念,所謂作用范圍隘膘,是指Git指令所起作用的兩種對象(層級)疑故,分別是File-level和Commit-level。就之前的圖2為例弯菊,當(dāng)www文件被修改之后纵势,此時可對該修改文件進行2種操作,一種是git add
使其進入到Staged Snapshot中管钳,另一種則是git checkout
令其還原到修改前的狀態(tài)钦铁。
- File-level
文件層級為Git指令對單個或者多個文件(指令中反映為文件路徑)進行的操作,git checkout
蹋嵌、git reset
均可作用于該層級育瓜。
注意:
git revert
沒有File Scope操作。
- Commit-level
提交層級為Git指令對Commit History中的單條或多條commit進行的操作栽烂,git checkout
躏仇、git reset
、git revert
均可作用于該層級腺办。下面附上三種指令對應(yīng)Scope的表格:
Git指令 | 作用范圍 | 常用場景 |
---|---|---|
git checkout | Commit-level | 1. 分支間切換 2. 切換到同一分支下的指定commit進行代碼瀏覽(分離狀態(tài)焰手,下文會進一步闡述說明) |
git checkout | File-level | 還原對某個或多個文件的修改(該操作不可逆,慎用) |
git reset | Commit-level | 還原某一分支上已提交的某條或多條commits(適用于個人分支怀喉,該操作不可逆书妻,慎用) |
git reset | File-level | 將Staged狀態(tài)下的某個或多個文件,還原到Unstaged狀態(tài) |
git revert | Commit-level | 撤銷某分支上的已提交內(nèi)容(適用于公共分支) |
git revert | File-level | 無文件層級操作 |
git checkout
分支切換
git checkout
指令用于更新當(dāng)前項目所處狀態(tài)躬拢,若指令所指定的值為分支名躲履,則切換到該指定分支。例如聊闯,我們打算將當(dāng)前所處master分支工猜,切換到hotfix分支上,執(zhí)行如下代碼:
git checkout hotfix
此時菱蔬,若當(dāng)前分支上的修改可能對目標(biāo)分支上的文件造成覆寫篷帅,則Git會強制中斷此次操作史侣,并提示哪些文件可能導(dǎo)致覆寫,提出操作建議魏身。當(dāng)你完成修改后惊橱,即能夠進行成功切換,git checkout
指令的執(zhí)行機制如下圖所示箭昵,其中税朴,HEAD可以理解為頭指針,用于指向當(dāng)前項目代碼所處的分支家制,以及commit history位置:
切換前掉房,HEAD指向Master分支的最近一次代碼提交位置;切換后慰丛,HEAD指向Hotfix分支的最近一次代碼提交位置。
指定commit history位置切換
git checkout
也可以用于切換到某一分支上的指定commit位置瘾杭,當(dāng)指令值為commit id時诅病,則能夠?qū)EAD指向該次commit,例如粥烁,我們想要將代碼回溯到上上一次commit位置進行快速瀏覽時贤笆,則可以運行以下指令:
git checkout HEAD~2
為了方便理解,下圖表示了此次指令的執(zhí)行機制:
可以看到讨阻,執(zhí)行完畢后芥永,HEAD已經(jīng)指向了上上一次commit的位置。git checkout
的這項特性使得用戶能夠快速地切換到目標(biāo)commit對代碼進行查閱钝吮,并且不會對當(dāng)前分支造成任何影響埋涧,此時HEAD指向的代碼位置不屬于任何一個分支的任何一次commit,這樣的狀態(tài)叫做'detached HEAD' state奇瘦,執(zhí)行結(jié)果見下圖所示:
需要注意的是棘催,處于detached HEAD狀態(tài)的代碼,在你切換到任何分支后耳标,都會丟失得不到保存醇坝,所以,如果你想要在該commit上進行修改并提交次坡,請務(wù)必在修改前執(zhí)行git checkout -b <new-branch-name>
呼猪,這樣,你可以得到一個同該commit代碼一模一樣的新分支砸琅,并進行任何能夠得到記錄的操作宋距。
還原Unstaged狀態(tài)的文件
git checkout
還能夠作用于Unstaged狀態(tài)下的文件,執(zhí)行后明棍,該文件的任何修改都會還原到此次修改前的狀態(tài)乡革,這種場景常見于當(dāng)你進行了某些實驗性質(zhì)的修改或者因某些原因需要放棄此次修改時。執(zhí)行指令如下:
git checkout -- <single file path> // 還原單個文件
git checkout -- . // 還原所有此次修改文件
本章完。
下一章節(jié)將主要介紹git reset指令沸版。
文中部分圖片源于www.atlassian.com嘁傀。
參考文獻
https://git-scm.com/docs/git-checkout
https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting