我使用 Git cherry-pick 命令的 3 個理由
在版本控制系統中摸索前進是一件很棘手的事情。對於一個新手來說,這可能是非常難以應付的,但熟悉版本控制系統(如 Git)的術語和基礎知識是開始為開源貢獻的第一步。
熟悉 Git 也能幫助你在開源之路上走出困境。Git 功能強大,讓你感覺自己在掌控之中 —— 沒有哪一種方法會讓你無法恢復到工作版本。
這裡有一個例子可以幫助你理解「 遴選 」的重要性。假設你已經在一個分支上做了好幾個提交,但你意識到這是個錯誤的分支!你現在該怎麼辦?你現在要做什麼?要麼在正確的分支上重複所有的變更,然後重新提交,要麼把這個分支合併到正確的分支上。等一下,前者太過繁瑣,而你可能不想做後者。那麼,還有沒有辦法呢?有的,Git 已經為你準備好了。這就是「遴選」的作用。顧名思義,你可以用它從一個分支中手工遴選一個提交,然後轉移到另一個分支。
使用遴選的原因有很多。以下是其中的三個原因。
避免重複性工作
如果你可以直接將相同的提交複製到另一個分支,就沒有必要在不同的分支中重做相同的變更。請注意,遴選出來的提交會在另一個分支中創建帶有新哈希的新提交,所以如果你看到不同的提交哈希,請不要感到困惑。
如果您想知道什麼是提交的哈希,以及它是如何生成的,這裡有一個說明可以幫助你。提交哈希是用 SHA-1 演算法生成的字元串。SHA-1 演算法接收一個輸入,然後輸出一個唯一的 40 個字元的哈希值。如果你使用的是 POSIX 系統,請嘗試在您的終端上運行這個命令:
$ echo -n "commit" | openssl sha1
這將輸出一個唯一的 40 個字元的哈希值 4015b57a143aec5156fd1444a017a32137a3fd0f
。這個哈希代表了字元串 commit
。
Git 在提交時生成的 SHA-1 哈希值不僅僅代表一個字元串。它代表的是:
sha1(
meta data
commit message
committer
commit date
author
authoring date
Hash of the entire tree object
)
這就解釋了為什麼你對代碼所做的任何細微改動都會得到一個獨特的提交哈希值。哪怕是一個微小的改動都會被發現。這是因為 Git 具有完整性。
撤銷/恢復丟失的更改
當你想恢復到工作版本時,遴選就很方便。當多個開發人員在同一個代碼庫上工作時,很可能會丟失更改,最新的版本會被轉移到一個陳舊的或非工作版本上。這時,遴選提交到工作版本就可以成為救星。
它是如何工作的?
假設有兩個分支:feature1
和 feature2
,你想把 feature1
中的提交應用到 feature2
。
在 feature1
分支上,運行 git log
命令,複製你想遴選的提交哈希值。你可以看到一系列類似於下面代碼示例的提交。commit
後面的字母數字代碼就是你需要複製的提交哈希。為了方便起見,您可以選擇複製前六個字元(本例中為 966cf3
)。
commit 966cf3d08b09a2da3f2f58c0818baa37184c9778 (HEAD -> master)
Author: manaswinidas <me@example.com>
Date: Mon Mar 8 09:20:21 2021 +1300
add instructions
然後切換到 feature2
分支,在剛剛從日誌中得到的哈希值上運行 git cherry-pick
:
$ git checkout feature2
$ git cherry-pick 966cf3.
如果該分支不存在,使用 git checkout -b feature2
來創建它。
這裡有一個問題。你可能會遇到下面這種情況:
$ git cherry-pick 966cf3
On branch feature2
You are currently cherry-picking commit 966cf3d.
nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git reset'
不要驚慌。只要按照建議運行 git commit --allow-empty
:
$ git commit --allow-empty
[feature2 afb6fcb] add instructions
Date: Mon Mar 8 09:20:21 2021 +1300
這將打開你的默認編輯器,允許你編輯提交信息。如果你沒有什麼要補充的,可以保存現有的信息。
就這樣,你完成了你的第一次遴選。如上所述,如果你在分支 feature2
上運行 git log
,你會看到一個不同的提交哈希。下面是一個例子:
commit afb6fcb87083c8f41089cad58deb97a5380cb2c2 (HEAD -> feature2)
Author: manaswinidas <[me@example.com][4]>
Date: Mon Mar 8 09:20:21 2021 +1300
add instructions
不要對不同的提交哈希感到困惑。這只是區分 feature1
和 feature2
的提交。
遴選多個提交
但如果你想遴選多個提交的內容呢?你可以使用:
git cherry-pick <commit-hash1> <commit-hash2>... <commit-hashn>
請注意,你不必使用整個提交的哈希值,你可以使用前五到六個字元。
同樣,這也是很繁瑣的。如果你想遴選的提交是一系列的連續提交呢?這種方法太費勁了。別擔心,有一個更簡單的方法。
假設你有兩個分支:
feature1
包括你想複製的提交(從更早的commitA
到commitB
)。feature2
是你想把提交從feature1
轉移到的分支。
然後:
- 輸入
git checkout <feature1>
。 - 獲取
commitA
和commitB
的哈希值。 - 輸入
git checkout <branchB>
。 - 輸入
git cherry-pick <commitA>^..<commitB>
(請注意,這包括commitA
和commitB
)。 - 如果遇到合併衝突,像往常一樣解決,然後輸入
git cherry-pick --continue
恢復遴選過程。
重要的遴選選項
以下是 Git 文檔 中的一些有用的選項,你可以在 cherry-pick
命令中使用。
-e
、--edit
:用這個選項,git cherry-pick
可以讓你在提交前編輯提交信息。-s
、--signoff
:在提交信息的結尾添加Signed-off by
行。更多信息請參見git-commit(1)
中的 signoff 選項。-S[<keyid>]
、--pgg-sign[=<keyid>]
:這些是 GPG 簽名的提交。keyid
參數是可選的,默認為提交者身份;如果指定了,則必須嵌在選項中,不加空格。--ff
:如果當前 HEAD 與遴選的提交的父級提交相同,則會對該提交進行快進操作。
下面是除了 --continue
外的一些其他的後繼操作子命令:
--quit
:你可以忘記當前正在進行的操作。這可以用來清除遴選或撤銷失敗後的後繼操作狀態。--abort
:取消操作並返回到操作序列前狀態。
下面是一些關於遴選的例子:
git cherry-pick master
:應用master
分支頂端的提交所引入的變更,並創建一個包含該變更的新提交。git cherry-pick master~4 master~2':應用
master` 指向的第五個和第三個最新提交所帶來的變化,並根據這些變化創建兩個新的提交。
感到不知所措?你不需要記住所有的命令。你可以隨時在你的終端輸入 git cherry-pick --help
查看更多選項或幫助。
via: https://opensource.com/article/21/3/git-cherry-pick
作者:Manaswini Das 選題:lujun9972 譯者:wxy 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive