rebase & merge
先说结论,rebase
比较适用于私人分支,可以把主干分支上其他人开发的功能拉到自己的分支上,并且是一条线;merge
则主要适用于主分支,可以将其他人的代码合并上去,因为要保留主分支的完整历史记录。
- Merge
-
rebase
squash
主要用于合并commit,简化分支。
- 交互式重排示例:
# 进行交互式重排,假设重排最近的4个提交
git rebase -i HEAD~4
在编辑器中,将目标提交标记为 squash
或 s
(s 代表将当前提交合并到上一个提交):
pick 1234567 Add feature A
s 89abcdef Fix bug in feature A
s 4567890 Add tests for feature A
s abcdef12 Improve documentation for feature A
- 保存并退出。此时应该弹出合并提交信息的编辑界面,例如:
# This is a combination of 4 commits.
# The first commit's message is:
Add feature A# This is the 2nd commit message:Fix bug in feature A# This is the 3rd commit message:Add tests for feature A# This is the 4th commit message:Improve documentation for feature A# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
编辑合并后的提交信息,例如:
Add feature A with bug fixes, tests, and documentation improvements- Add feature A
- Fix bug in feature A
- Add tests for feature A
- Improve documentation for feature A
保存并退出,这样 Git 就会完成合并提交。
此时的git log
前后对比
git diff Patch
git diff
和 git apply
的用法,特别是如何通过生成和应用补丁文件(patch files)在不同的分支或仓库之间传递更改。现对这段话进行详细解读:
基本用法
- 使用场景
git diff
可以用来创建一个补丁文件,该文件包括不同提交、分支等之间的差异。然后可以使用 git apply
将这些补丁文件应用到另一个分支或仓库中。
- 实际操作步骤
步骤1:创建一个包含HEAD和HEAD~5之间差异的补丁文件:
git diff HEAD~5 HEAD > my-feature.patch
这个命令生成了从 HEAD~5
(当前HEAD的前五个提交) 到 HEAD
之间的差异,并将这些差异输出到名为 my-feature.patch
的文件中。
步骤2:将当前工作目录中的更改写入一个补丁文件:
git diff > my-changes.patch
这个命令将当前工作目录中的未提交更改记录到名为 my-changes.patch
的文件中。
步骤3:在新分支中应用补丁文件:
git apply my-feature.patch
这个命令应用 my-feature.patch
中记录的更改到当前工作目录或暂存区。
主要用途
- 生成补丁文件:使用
git diff
生成补丁文件,可以记录不同提交、分支、工作目录之间的差异。 - 应用补丁文件:使用
git apply
应用补丁文件,可以将其他分支或仓库中的更改引入当前工作目录或暂存区。 - 共享代码更改:补丁文件非常适合在不依赖多次提交或创建分支的情况下共享代码更改。
- 应用实例
例如,在某个迁移项目中,频繁使用 git diff
补丁文件。先将提交导入到另一个存储库(DYEH repo),然后创建补丁文件,最后在第二个存储库(TTEH repo)中应用补丁文件,从而实现代码的迁移。
这个过程可以总结如下:
- 通过
git diff
生成补丁文件,记录两个提交、分支或版本之间的差异。 - 将生成的补丁文件应用到目标分支或仓库中,确保差异能够被正确合并。
通过这种方式,可以高效地在项目之间迁移或共享代码更改,而无需直接操作多次提交或创建额外分支。
git bisect ——二分查找debug
说白了就是使用二分查找定位bug点,先分别标记
good
,bad
两个commit点,然后git会自动把状态恢复到中间的commit状态,我们在这里检查一下,然后可以判断好坏,如果是好,则会跳到下一个二分查找点。
bisect
是 Git 提供的一个功能,用于在大型代码库中快速定位引入错误的提交。通过二分查找算法,它能够在一系列提交中迅速找到导致问题的那一个。这个工具对于调试引入问题的提交非常有用,可以显著减少需要检查的提交数量。
基本用法
-
启动
git bisect
:命令:
git bisect start
-
标记坏的提交:
命令:
git bisect bad
使用
git bisect bad
告诉git bisect
目前的代码状态是有问题的,即指出坏的提交(通常是当前的 HEAD)。 -
标记好的提交:
命令:
git bisect good <commit>
使用
git bisect good <commit>
告诉git bisect
一个已知的良好提交,这样 Git 就可以确定搜索的范围。<commit>
可以是提交哈希、分支、标签等。 -
Git Bisect 开始搜索:
git bisect
会切换到两个提交中间的那个提交点,然后你需要测试该提交中的代码是否有问题:- 如果测试后发现有问题,运行:
git bisect bad
- 如果测试后发现没有问题,运行:
git bisect good
Git 会重复该过程,继续在剩余的提交中间点切换,直到找到引入问题的提交为止。
- 如果测试后发现有问题,运行:
-
找到问题提交并结束
git bisect
:当
git bisect
找到导致问题的提交后,可以使用以下命令结束二分查找过程:git bisect reset
这会将当前工作目录恢复到
git bisect
启动之前的状态。
PS:
在自动化测试环境中,可以使用 git bisect run
命令配合脚本自动化测试。例如:
git bisect start
git bisect bad
git bisect good v1.0
git bisect run ./test_script.sh
其中 ./test_script.sh
是一个返回状态码的脚本,非零状态码表示错误,零表示正常。
通过 git bisect
,你可以更快捷地定位回归问题,大大提高了调试和修复代码的效率。
cherry-pick (cross-repo)
git cherry-pick
是一个非常有用的 Git 命令,它可以让你从一个分支中挑选特定的提交(commit)并将它们应用到当前分支。这个命令在团队协作或处理多个功能分支时特别有用,当你需要从不同的分支中复制已存在的修改时,不必合并整个分支。
使用场景
- 从功能分支中挑选特定提交应用到主分支。
- 在一个修复分支中选择特定的修复提交应用到其他分支。
- 将特定改动引入到当前正在开发的功能分支中。
基本用法
-
切换到目标分支:
首先,切换到你希望应用提交的目标分支。例如,你要将提交应用到
main
分支:git checkout main
-
执行
cherry-pick
操作:使用
git cherry-pick
命令选择特定提交并将其应用到当前分支。你可以通过提交哈希(SHA1)指定提交:git cherry-pick <commit-hash>
例如:
git cherry-pick a1b2c3d4
这将把
a1b2c3d4
提交的更改应用到当前所在的分支。
高级用法
-
挑选多个提交:
你可以一次挑选多个连续的提交,使用提交范围:
git cherry-pick <start-commit>^..<end-commit>
例如:
git cherry-pick a1b2c3d4^..d5e6f7g8
这样会将从
a1b2c3d4
之后(包含)的提交到d5e6f7g8
的所有提交依次应用到当前分支。 -
挑选非连续的多个提交:
你可以使用多次
git cherry-pick
命令,或者一次性应用多个单独的提交:git cherry-pick <commit-hash1> <commit-hash2> <commit-hash3>
例如:
git cherry-pick a1b2c3d4 e5f6g7h8 i9j0k1l2
-
解决冲突:
cherry-pick
操作过程中,如果遇到冲突,Git 会提示你解决冲突。你需要手动解决文件中的冲突,然后继续cherry-pick
操作:git add <resolved-files> git cherry-pick --continue
如果想中止
cherry-pick
操作,可以使用:git cherry-pick --abort
-
自动提交信息:
通常,
cherry-pick
会保留原提交的提交信息。如果你想修改提交信息,可以使用-e
选项:git cherry-pick -e <commit-hash>
-
签名提交:
如果你想签名
cherry-pick
提交,可以使用-s
选项:git cherry-pick -s <commit-hash>