git命令詳解( 九 )


 此為git第九篇記錄

    

    整理提交記錄

    Git Cherry-pick

      交互式的 rebase

   Git Tags

    Git Describe

整理提交記錄

之前我們已經學習了 Git 的基礎知識 —— 提交、分支以及在提交樹上移動。 這些概念涵蓋了 Git 90% 的功能,同樣也足夠滿足開發者的日常需求

然而, 剩余的 10% 在處理復雜的工作流時(或者當你陷入困惑時)可能就顯得尤為重要了。接下來要討論的這個話題是“整理提交記錄” —— 開發人員有時會說“我想要把這個提交放到這里, 那個提交放到剛才那個提交的后面”, 而接下來就講的就是它的實現方式,非常清晰、靈活,還很生動。

看起來挺復雜, 其實是個很簡單的概念。

Git Cherry-pick

  • git cherry-pick <提交號>...

如果你想將一些提交復制到當前所在的位置(HEAD)下面的話, Cherry-pick 是最直接的方式了。我個人非常喜歡 cherry-pick,因為它特別簡單。

咱們還是通過例子來看一下!

這里有一個倉庫, 我們想將 side 分支上的工作復制到 master 分支,你立刻想到了之前學過的 rebase 了吧?但是咱們還是看看 cherry-pick 有什么本領吧

執行命令:git cherry-pick C2 C4

這就是了!我們只需要提交記錄 C2 和 C4,所以 Git 就將被它們抓過來放到當前分支下了。 就是這么簡單!

 

交互式的 rebase

當你知道你所需要的提交記錄(並且還知道這些提交記錄的哈希值)時, 用 cherry-pick 再好不過了 —— 沒有比這更簡單的方式了。

但是如果你不清楚你想要的提交記錄的哈希值呢? 幸好 Git 幫你想到了這一點, 我們可以利用交互式的 rebase —— 如果你想從一系列的提交記錄中找到想要的記錄, 這就是最好的方法了

咱們具體來看一下……

交互式 rebase 指的是使用帶參數 --interactive 的 rebase 命令, 簡寫為 -i

如果你在命令后增加了這個選項, Git 會打開一個 UI 界面並列出將要被復制到目標分支的備選提交記錄,它還會顯示每個提交記錄的哈希值和提交說明,提交說明有助於你理解這個提交進行了哪些更改。

在實際使用時,所謂的 UI 窗口一般會在文本編輯器 —— 如 Vim —— 中打開一個文件。 

 

本地棧式提交

來看一個在開發中經常會遇到的情況:我正在解決某個特別棘手的 Bug,為了便於調試而在代碼中添加了一些調試命令並向控制台打印了一些信息。

這些調試和打印語句都在它們各自的提交記錄里。最后我終於找到了造成這個 Bug 的根本原因,解決掉以后覺得沾沾自喜!

最后就差把 bugFix 分支里的工作合並回 master 分支了。你可以選擇通過 fast-forward 快速合並到 master 分支上,但這樣的話 master 分支就會包含我這些調試語句了。你肯定不想這樣,應該還有更好的方式……

實際我們只要讓 Git 復制解決問題的那一個提交記錄就可以了。跟之前我們在“整理提交記錄”中學到的一樣,我們可以使用

  • git rebase -i
  • git cherry-pick

來達到目的。

 

提交的技巧 #1

接下來這種情況也是很常見的:你之前在 newImage 分支上進行了一次提交,然后又基於它創建了 caption 分支,然后又提交了一次。

此時你想對的某個以前的提交記錄進行一些小小的調整。比如設計師想修改一下 newImage 中圖片的分辨率,盡管那個提交記錄並不是最新的了。

 

我們可以通過下面的方法來克服困難:

  • 先用 git rebase -i 將提交重新排序,然后把我們想要修改的提交記錄挪到最前
  • 然后用git commit --amend 來進行一些小修改
  • 接着再用 git rebase -i 來將他們調回原來的順序
  • 最后我們把 master 移到修改的最前端(用你自己喜歡的方法),就大功告成啦!

當然完成這個任務的方法不止上面提到的一種(我知道你在看 cherry-pick 啦),之后我們會多點關注這些技巧啦,但現在暫時只專注上面這種方法。 

 

提交的技巧 #2

正如你在上面所見到的,我們可以使用 rebase -i 對提交記錄進行重新排序。只要把我們想要的提交記錄挪到最前端,我們就可以很輕松的用 --amend 修改它,然后把它們重新排成我們想要的順序。

但這樣做就唯一的問題就是要進行兩次排序,而這有可能造成由 rebase 而導致的沖突。下面還是看看 git cherry-pick 是怎么做的吧。

要在心里牢記 cherry-pick 可以將提交樹上任何地方的提交記錄取過來追加到 HEAD 上(只要不是 HEAD 上游的提交就沒問題)。

來看看這個例子:

執行命令:git cherry-pick C2

 

 

Git Tags

相信通過前面課程的學習你已經發現了:分支很容易被人為移動,並且當有新的提交時,它也會移動。分支很容易被改變,大部分分支還只是臨時的,並且還一直在變。

你可能會問了:有沒有什么可以永遠指向某個提交記錄的標識呢,比如軟件發布新的大版本,或者是修正一些重要的 Bug 或是增加了某些新特性,有沒有比分支更好的可以永遠指向這些提交的方法呢?

當然有了!Git 的 tag 就是干這個用的啊,它們可以(在某種程度上 —— 因為標簽可以被刪除后重新在另外一個位置創建同名的標簽)永久地將某個特定的提交命名為里程碑,然后就可以像分支一樣引用了。

更難得的是,它們並不會隨着新的提交而移動。你也不能檢出到某個標簽上面進行修改提交,它就像是提交樹上的一個錨點,標識了某個特定的位置。

咱們來看看標簽到底是什么樣。

咱們先建立一個標簽,指向提交記錄 C1,表示這是我們 1.0 版本。

執行命令:git tag v1 C1

很容易吧!我們將這個標簽命名為 v1,並且明確地讓它指向提交記錄 C1,如果你不指定提交記錄,Git 會用 HEAD 所指向的位置。

 

 

 

Git Describe

由於標簽在代碼庫中起着“錨點”的作用,Git 還為此專門設計了一個命令用來描述離你最近的錨點(也就是標簽),它就是 git describe

Git Describe 能幫你在提交歷史中移動了多次以后找到方向;當你用 git bisect(一個查找產生 Bug 的提交記錄的指令)找到某個提交記錄時,或者是當你坐在你那剛剛度假回來的同事的電腦前時, 可能會用到這個命令。

git describe 的​​語法是:

git describe <ref>

<ref> 可以是任何能被 Git 識別成提交記錄的引用,如果你沒有指定的話,Git 會以你目前所檢出的位置(HEAD)。

它輸出的結果是這樣的:

<tag>_<numCommits>_g<hash>

tag 表示的是離 ref 最近的標簽, numCommits 是表示這個 ref 與 tag 相差有多少個提交記錄, hash 表示的是你所給定的 ref 所表示的提交記錄哈希值的前幾位。

當 ref 提交記錄上有某個標簽時,則只輸出標簽名稱

執行命令:git tag v2 C3

git describe master 會輸出:

v1_2_gC2

git describe side 會輸出:

v2_1_gC4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM