gitcherry-pick
什么是 Cherry-pick
Cherry-pick 是 Git 提供的一个非常有用的命令,它允许我们选择一个或多个特定的提交(commit),并将它们应用到当前分支上。通俗地说,就是我们可以从其他分支上选择某些提交,然后把它们“摘”下来并应用到当前分支上。
Cherry-pick 的使用场景
Cherry-pick 在以下几种情况下特别有用:
合并单个提交到当前分支
有时候我们需要从其他分支上选择某个特定的提交合并到当前分支。比如,我们在 bug 分支上修复了一个紧急的 bug,并提交了一个修复提交。现在我们想把这个修复应用到主分支上,而不影响其他的 bug 修复或特性开发。这个时候,我们可以使用 Cherry-pick 命令:
git cherry-pick <commit-hash>
其中 <commit-hash>
是我们想要应用的提交的哈希值。
合并多个连续的提交到当前分支
有时候我们需要把某个分支上的连续多个提交合并到当前分支。比如,我们在某个 feature 分支上进行了多次提交来实现一个新功能,并且所有的提交都是基于同一个父提交。现在我们想把这些提交一起合并到主分支上。这个时候,我们可以使用 Cherry-pick 命令:
git cherry-pick <start-commit-hash>^..<end-commit-hash>
其中 <start-commit-hash>
是我们要合并的第一个提交的哈希值,<end-commit-hash>
是我们要合并的最后一个提交的哈希值。
合并多个离散的提交到当前分支
有时候我们需要把其他分支上的多个离散的提交合并到当前分支。比如,我们在其他分支上修复了多个 bug,这些修复提交的提交者可能是多个人,也可能是同一个人。现在我们想把这些修复提交一起合并到主分支上。这个时候,我们可以使用 Cherry-pick 命令多次调用:
git cherry-pick <commit-hash-1>
git cherry-pick <commit-hash-2>
...
git cherry-pick <commit-hash-n>
其中 <commit-hash-1>
, <commit-hash-2>
, …, <commit-hash-n>
是我们要合并的各个提交的哈希值。
解决冲突
使用 Cherry-pick 合并提交时,有可能会出现冲突(conflict)。当两个提交修改了相同的文件的相同行时,Git 无法自动合并它们,就会发生冲突。这个时候,我们需要手动解决冲突,然后继续 cherry-pick 的过程。
Cherry-pick 的实际应用举例
下面通过一个具体的示例,来演示 Cherry-pick 的实际应用。
- 我们先创建一个新的 Git 仓库,并在 master 分支上初始化文件:
$ git init
$ echo "Hello, Git!" > greeting.txt
$ git add greeting.txt
$ git commit -m "Initial commit"
- 创建一个 feature 分支,并在该分支上进行一些修改和提交:
$ git checkout -b feature
$ echo "How are you?" >> greeting.txt
$ git commit -am "Add a line"
$ echo "Nice weather today!" >> greeting.txt
$ git commit -am "Add another line"
此时,我们的仓库结构如下:
* 1e603b4 (feature) Add another line
* 1145c87 Add a line
| * 7e9a6d9 (HEAD -> master) Initial commit
|/
- 切回到主分支,并在 master 分支上进行一些修改和提交:
$ git checkout master
$ echo "Have a nice day!" >> greeting.txt
$ git commit -am "Add a greeting"
此时,我们的仓库结构如下:
* faf4be2 (HEAD -> master) Add a greeting
| * 1e603b4 (feature) Add another line
| * 1145c87 Add a line
|/
* 7e9a6d9 Initial commit
- 现在,我们想把 feature 分支上的两个提交应用到主分支上。首先,我们使用 Cherry-pick 命令合并第一个提交:
$ git cherry-pick 1145c87
此时,如果没有冲突,则会自动合并提交。我们的仓库结构变为:
* 410acb2 (HEAD -> master) Add a line
* faf4be2 Add a greeting
| * 1e603b4 (feature) Add another line
| * 1145c87 Add a line
|/
* 7e9a6d9 Initial commit
- 接下来,我们使用 Cherry-pick 命令合并第二个提交:
$ git cherry-pick 1e603b4
此时,由于第二个提交的修改和第一个提交修改同一行产生了冲突,Git 会自动停止合并,然后提示我们手动解决冲突。通过 git status
命令,我们可以看到哪些文件出现了冲突。
- 手动解决冲突后,使用
git add
命令标记已解决的文件,并继续 cherry-pick 进行合并:
$ git add greeting.txt
$ git cherry-pick --continue
此时,我们的仓库结构变为:
* e4a1980 (HEAD -> master) Add another line
* 410acb2 Add a line
* faf4be2 Add a greeting
| * 1e603b4 (feature) Add another line
| * 1145c87 Add a line
|/
* 7e9a6d9 Initial commit
至此,我们成功地使用 Cherry-pick 命令将 feature 分支上的两个提交应用到主分支上。
Cherry-pick 的注意事项
在使用 Cherry-pick 命令时,需要注意以下几点:
- Cherry-pick 会在当前分支上产生新的提交,因此在合并提交之前,我们应该确保当前分支是最新的,并且没有未提交的修改。
- Cherry-pick 的合并过程是按照提交的顺序进行的,即使我们指定了多个提交,也会按照它们在仓库中的顺序依次进行合并。
- Cherry-pick 是一个“一次性”的操作,合并后的提交和原始提交之间没有引用关系。如果我们想保留原始提交的引用关系,可以使用
git branch
命令创建一个新的分支。