此為git第九篇記錄
整理提交記錄
git cherry-pick
互動式的 rebase
git tags
之前我們已經學習了 git 的基礎知識 —— 提交、分支以及在提交樹上移動。 這些概念涵蓋了 git 90% 的功能,同樣也足夠滿足開發者的日常需求
然而, 剩餘的 10% 在處理複雜的工作流時(或者當你陷入困惑時)可能就顯得尤為重要了。接下來要討論的這個話題是「整理提交記錄」 —— 開發人員有時會說「我想要把這個提交放到這裡, 那個提交放到剛才那個提交的後面」, 而接下來就講的就是它的實現方式,非常清晰、靈活,還很生動。
看起來挺複雜, 其實是個很簡單的概念。
如果你想將一些提交複製到當前所在的位置(head
)下面的話, cherry-pick 是最直接的方式了。我個人非常喜歡cherry-pick
,因為它特別簡單。
咱們還是通過例子來看一下!
這裡有乙個倉庫, 我們想將side
分支上的工作複製到master
分支,你立刻想到了之前學過的rebase
了吧?但是咱們還是看看cherry-pick
有什麼本領吧
執行命令:git cherry-pick c2 c4
這就是了!我們只需要提交記錄c2
和c4
,所以 git 就將被它們抓過來放到當前分支下了。 就是這麼簡單!
當你知道你所需要的提交記錄(並且還知道這些提交記錄的雜湊值)時, 用 cherry-pick 再好不過了 —— 沒有比這更簡單的方式了。
但是如果你不清楚你想要的提交記錄的雜湊值呢? 幸好 git 幫你想到了這一點, 我們可以利用互動式的 rebase —— 如果你想從一系列的提交記錄中找到想要的記錄, 這就是最好的方法了
咱們具體來看一下……
互動式 rebase 指的是使用帶引數--interactive
的 rebase 命令, 簡寫為-i
如果你在命令後增加了這個選項, git 會開啟乙個 ui 介面並列出將要被複製到目標分支的備選提交記錄,它還會顯示每個提交記錄的雜湊值和提交說明,提交說明有助於你理解這個提交進行了哪些更改。
在實際使用時,所謂的 ui 視窗一般會在文字編輯器 —— 如 vim —— 中開啟乙個檔案。
來看乙個在開發中經常會遇到的情況:我正在解決某個特別棘手的 bug,為了便於除錯而在**中新增了一些除錯命令並向控制台列印了一些資訊。
這些除錯和列印語句都在它們各自的提交記錄裡。最後我終於找到了造成這個 bug 的根本原因,解決掉以後覺得沾沾自喜!
最後就差把bugfix
分支裡的工作合併回master
分支了。你可以選擇通過 fast-forward 快速合併到master
分支上,但這樣的話master
分支就會包含我這些除錯語句了。你肯定不想這樣,應該還有更好的方式……
實際我們只要讓 git 複製解決問題的那乙個提交記錄就可以了。跟之前我們在「整理提交記錄」中學到的一樣,我們可以使用
來達到目的。
接下來這種情況也是很常見的:你之前在newimage
分支上進行了一次提交,然後又基於它建立了caption
分支,然後又提交了一次。
此時你想對的某個以前的提交記錄進行一些小小的調整。比如設計師想修改一下newimage
中的解析度,儘管那個提交記錄並不是最新的了。
我們可以通過下面的方法來克服困難:
當然完成這個任務的方法不止上面提到的一種(我知道你在看 cherry-pick 啦),之後我們會多點關注這些技巧啦,但現在暫時只專注上面這種方法。
正如你在上面所見到的,我們可以使用rebase -i
對提交記錄進行重新排序。只要把我們想要的提交記錄挪到最前端,我們就可以很輕鬆的用--amend
修改它,然後把它們重新排成我們想要的順序。
但這樣做就唯一的問題就是要進行兩次排序,而這有可能造成由 rebase 而導致的衝突。下面還是看看git cherry-pick
是怎麼做的吧。
要在心裡牢記 cherry-pick 可以將提交樹上任何地方的提交記錄取過來追加到 head 上(只要不是 head 上游的提交就沒問題)。
來看看這個例子:
執行命令:git cherry-pick c2
相信通過前面課程的學習你已經發現了:分支很容易被人為移動,並且當有新的提交時,它也會移動。分支很容易被改變,大部分分支還只是臨時的,並且還一直在變。
你可能會問了:有沒有什麼可以永遠指向某個提交記錄的標識呢,比如軟體發布新的大版本,或者是修正一些重要的 bug 或是增加了某些新特性,有沒有比分支更好的可以永遠指向這些提交的方法呢?
當然有了!git 的 tag 就是幹這個用的啊,它們可以(在某種程度上 —— 因為標籤可以被刪除後重新在另外乙個位置建立同名的標籤)永久地將某個特定的提交命名為里程碑,然後就可以像分支一樣引用了。
更難得的是,它們並不會隨著新的提交而移動。你也不能檢出到某個標籤上面進行修改提交,它就像是提交樹上的乙個錨點,標識了某個特定的位置。
咱們來看看標籤到底是什麼樣。
咱們先建立乙個標籤,指向提交記錄c1
,表示這是我們 1.0 版本。
執行命令:git tag v1 c1
很容易吧!我們將這個標籤命名為v1
,並且明確地讓它指向提交記錄c1
,如果你不指定提交記錄,git 會用head
所指向的位置。
由於標籤在**庫中起著「錨點」的作用,git 還為此專門設計了乙個命令用來描述離你最近的錨點(也就是標籤),它就是git describe
!
git describe 能幫你在提交歷史中移動了多次以後找到方向;當你用git bisect
(乙個查詢產生 bug 的提交記錄的指令)找到某個提交記錄時,或者是當你坐在你那剛剛度假回來的同事的電腦前時, 可能會用到這個命令。
git describe
的語法是:
git describe
可以是任何能被 git 識別成提交記錄的引用,如果你沒有指定的話,git 會以你目前所檢出的位置(
head
)。
它輸出的結果是這樣的:
__g
tag
表示的是離ref
最近的標籤,numcommits
是表示這個ref
與tag
相差有多少個提交記錄,hash
表示的是你所給定的ref
所表示的提交記錄雜湊值的前幾位。
當ref
提交記錄上有某個標籤時,則只輸出標籤名稱
執行命令:git tag v2 c3
git describe master
會輸出:
v1_2_gc2
git describe side
會輸出:
v2_1_gc4
git命令詳解
git 是乙個很強大的分布式版本控制系統。它不但適用於管理大型開源軟體的源 管理私人的文件和源 也有很多優勢。git常用操作命令 1 遠端倉庫相關命令 檢出倉庫 git clone git 檢視遠端倉庫 git remote v 新增遠端倉庫 git remote add name url 刪除遠端...
GIT命令詳解
2 進行預設安裝在開始選單中找到如下 開啟git bash出現如下圖就是安裝成功 3 git是乙個分布式版本控制系統,需要填寫使用者名稱和郵箱作為標識 4 基本命令 mkdir xx 建立乙個空目錄 xx指目錄名 pwd 顯示當前目錄的路徑。git init 把當前的目錄變成可以管理的 git倉庫,...
git 命令詳解
一.基本快照命令 1.git add 新增檔案到快取 情形是 在工作目錄中新建bb.txt,cc.txt git status s bb.txt cc.txt 2.git status檢視工作目錄和快取區的 檔案的狀態 上次提交之後 當前情形 1 git add 命令把bb.txt檔案加入快取中,2...