git - git rebase 如何在合并之间工作?
问题描述
我有一个功能和一个主分支,例如像这样(主已合并两次到功能中):
* 27e89b5 (HEAD -> feature) f4
|\
| * 6849a63 (master) 3
* | 3b78807 f3
* | e84e33f f2
|\ \
| |/
| * 90e6f74 2
* | 4e4025b f1
|/
* e4e0759 (tag: initial) 1
您可以使用以下命令重建此 MWE:
git init
f() { echo "$1" > README.md && git add README.md && git commit -m "$1"; }
f 1
git tag initial
git checkout -b feature
f f1
git checkout master
f 2
git checkout feature
git merge master
f f2
f f3
git checkout master
f 3
git checkout feature
git merge master
f f4
当我使用功能时,我想git rebase -i initial
压缩一些功能分支提交。Git 显示了这一点:
pick 4e4025b f1
pick 90e6f74 2
pick 3b78807 f3
pick 6849a63 3
squash
仅使用“f3”生成下图。
* be4387c (HEAD -> feature) 3
* a90d504 2
* 2afe0a4 f1
| * c447c7f (master) 3
| * efec11d 2
|/
* 661d8fc (tag: initial) 1
问题:
- 为什么 git 不提供压缩“f2”?
- 我可以只压缩“f3”而不对整个分支结构进行进一步更改吗?
解决方案
为什么 git 不提供压缩“f2”?
因为f2
是合并提交,您没有要求保留合并。默认情况下,git rebase
线性化历史并消除合并。它只是将提交堆叠在基础之上,就好像它们是新的补丁一样。
您可以保留合并,-p
然后您将获得所有提交。
$ git rebase -i initial
pick bde29dc f1
pick c9a9c74 2
pick e5565c5 f2
pick 7f18c18 f3
pick ffdd62c 3
pick 35d8ae9 f4
# Rebase aa61de7..35d8ae9 onto aa61de7 (6 commands)
我可以只压缩“f3”而不对整个分支结构进行进一步更改吗?
是的,但是在你压缩f3
到之前2
,如果你想保留你必须压缩f3
到的结构,f2
因为那是紧接在前的提交,在拓扑上。
pick bde29dc f1
pick c9a9c74 2
pick e5565c5 f2
squash 7f18c18 f3
pick ffdd62c 3
pick 35d8ae9 f4
你会结束的。
* (HEAD -> feature) f4
|\
| * (master) 3
* | f2
|\ \
| |/
| * 2
* | f1
|/
* (tag: initial) 1
尽管将提交压缩为合并提交没有多大意义。
如果您改为重新排序提交,以便您可以压缩f3
到2
...
pick bde29dc f1
pick c9a9c74 2
squash 7f18c18 f3
pick e5565c5 f2
pick ffdd62c 3
pick 35d8ae9 f4
......你会结束......一些奇怪的东西。
* (HEAD -> feature) f4
|\
| * 3
|/
* f3
* 2
* (tag: initial) 1
尝试在分支之间移动提交git rebase -i -p
会让人感到困惑,因为它会为git rebase -i
您提供非线性历史的线性视图。假装非线性历史是线性的,这是 Git 令人困惑的地方。
但是您可能不应该担心保留所有这些。保持 Git 历史大部分是线性的,这会让一切变得更加简单。这是如何做到的。
您的历史记录可能是使用 更新的feature
结果git merge master
。这是一个更好的方式来看待它。
1 -- 2 ------- 3 [master]
\ \ \
f1 - f2 - f3 - f4 [feature]
f2
并且f4
没有实际价值;它们是来自更新,master
不包含有趣的内容。他们只是让历史变得混乱。仅f1
包含f3
实际内容。您最好消除这些更新合并git rebase master
并获得线性历史记录。
$ git rebase master
1 - 2 - 3 [master]
\
f1 - f3 [feature]
然后一切都清晰而简单。通过使用git rebase master
而不是git merge master
.
# After more updates with `git rebase master`
1 - 2 - 3 - 4 - 5 [master]
\
f1 - f3 - f5 - f6 [feature]
当您准备好合并feature
到master
这里时,就是您想要合并提交的时候。用于git merge --no-ff feature
强制合并提交,然后删除feature
.
$ git merge --no-ff feature
$ git branch -d feature
1 - 2 - 3 - 4 - 5 ------------------ 6 [master]
\ /
f1 - f3 - f5 - f6
这将使分支保留在历史记录中,而不必保留分支头。这让未来的代码考古学家清楚地知道,f1 - f3 - f5 - f6
它们都是为单一功能而开发的。
推荐阅读
- android - 嵌套滚动视图中的 StreetViewPanoramaView 不起作用
- python - 基于python中的最高有效位对二进制矩阵列进行排序
- python - 在 kv 文件中,如何将方法从父级传输到其子级
- scala - Scala:在 if 条件下声明 val
- angular - Angular 非全局单例服务
- javascript - 如何在formik中提交对象数组?
- ionic-framework - phonegap-plugin-push 消息未显示为 android
- ios - 使用您生成的应用专用密码登录。如果您忘记了应用专用密码或需要创建一个新密码 -22938
- c# - 如何在 Microsoft Visual Studio 2017 中安装 XNA 框架?
- node.js - 无法使用 npm-postgres 发布 postgres 客户端