git merge VS git rebase VS git cherry-pick
在Git中,git merge
、git rebase
和git cherry-pick
都是用于整合不同分支中的更改到当前分支的命令。它们各有特点和适用场景。
Git Merge
git merge
是一种将一个分支的更改合并到另一个分支的方法。它创建一个新的提交,该提交包含来自两个分支的更改。
命令格式:
git merge <branch-name>
示例: 假设你有一个master
分支和一个develop
分支,要将develop
分支合并到master
分支,可以执行:
git checkout master
git merge develop
git 会根据master分支和develop分支的共同祖先(即3号提交)以及这两个分支的最新提交(即6号提交和7号提交)三方合并成一个新的提交(即8号提交)
特点:
- 历史保留:
git merge
会保留分支的历史记录(即保留原有分支的结构和时间顺序)。 - 合并冲突: 如果有文件在同一位置被修改,则需要手动解决冲突。
- 快进合并: 当目标分支没有任何提交是源分支所没有时,可以直接进行快进合并。
Git Rebase
git rebase
将一个分支上的提交重新应用到另一个分支上。这通常意味着将一系列提交移动到另一个分支的顶部。
命令格式:
git rebase <branch-name>
示例: 继续上面的例子,如果你想将master
分支的更改重新应用到develop
分支的顶部,可以执行:
git checkout master
git rebase develop
特点:
- 历史重写:
git rebase
会改变提交历史,可能会导致提交ID的变化。 - 交互式 rebase: 可以使用
git rebase -i
进行交互式 rebase,允许你修改、删除或重组提交。 - 避免合并提交: 使用
rebase
可以避免产生额外的合并提交。
Git Cherry-Pick
git cherry-pick
允许你选择性地将单个或多个提交从一个分支应用到另一个分支。这对于修复已发布的版本特别有用。
cherry-pick单个提交命令格式:
git cherry-pick <commit-4>
示例: 如果想将develop
分支中的某个提交(例如 commit hash 为<commit-4>
)应用到master
分支,可以执行:
git checkout master
git cherry-pick <commit-4>
cherry-pick多个提交命令格式:
git cherry-pick <commit-4>空格<commit-8>
git cherry-pick <commit-4>..<commit-8>
git cherry-pick <commit-4>^..<commit-8>
示例: 如果想将develop
分支中的某几个提交(例如 commit hash 为<commit-4>
,<commit-8>
)应用到master
分支,可以执行:
git checkout master
git cherry-pick <commit-4>空格<commit-8>
cherry-pick多个提交命令格式:
git cherry-pick <commit-4>空格<commit-8>
git cherry-pick <commit-4>..<commit-8>(4,8]
git cherry-pick <commit-4>^..<commit-8>[4,8]
示例: 如果想将develop
分支中的某连续几个提交(例如 commit hash 为 (<commit-4>
到<commit-8>
)应用到master
分支,可以执行:
git checkout master
git cherry-pick <commit-4>空格<commit-8>(4,8]
git cherry-pick <commit-4>^..<commit-8>[4,8]
注意事项:
- 冲突处理:如果在
cherry-pick
过程中遇到文件修改冲突,你需要手动解决这些冲突,然后使用git add
添加解决后的文件,并使用git cherry-pick --continue
继续,如果你决定不再继续cherry-pick
过程,可以使用git cherry-pick --abort
来取消。 - 历史重写:虽然
cherry-pick
本身不重写历史,但如果你对一个已经被推送的分支使用cherry-pick
,可能会导致其他人需要重新拉取最新的提交。 - 提交信息:
cherry-pick
会保留原始提交的信息,包括提交者和提交消息。
总结
- Merge: 适用于希望保留分支历史的场景,通常用于最终合并功能分支到主分支。
- Rebase: 适用于希望保持线性历史记录的情况,适合于经常需要同步最新变更的开发人员。
- Cherry-Pick: 适用于需要快速应用特定修复或功能到现有分支的情况。