我有一个功能和一个主分支,例如像这样(将master合并到功能中两次):
* 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
问题:
答案 0 :(得分:2)
为什么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
都是为单个功能开发的。