Git 不会跟踪提交中的更改。每个提交都包含存储库中文件的完整副本。“更改”是通过区分两个提交来确定的。
所以,简而言之,squashing 绝对没有问题E
,B
并C
提交F
,然后将其合并到 dev 分支上。B
提交仍将存在于 dev 分支上。当 git 与 比较F
时B
,只有 和 引入的更改C
将E
归因于F
.
当然,您可以使用git rebase
. 例如,由于git rebase
更改了您的分支历史记录(将您的提交移动到来自 dev 的最新提交之上),如果存在冲突,您必须在每次 rebase 时重新解决这些冲突。如果您的问题需要一段时间才能解决,这会很快过时,需要多次变基才能与开发人员保持同步。
只是为了证明这一切都是真的并且您无需担心,我设置了一个示例 GitHub 存储库:https ://github.com/cyborgx37/sandbox
首先,我们有dev分支,它有B
提交。
B:patch
|
A
然后我创建了feature1分支,它有提交C
和. (注意,因为 D 是一个合并,因此有两个父级,也显示在提交历史中)D
E
B
E
|
D:merge with dev
|\
C \
| B
A
最后,还有dev-with-feature1分支。
F
|
B:patch
|
A
我从 dev 创建了这个分支,然后使用
git merge --squash feature1
git commit -m "F"
将所有feature1的提交压缩成一个提交,F
.
如果您检查commit的差异F
,您会发现它没有“应用补丁”。由于B
已经包含这些更改,并且F
只是重复它们,git 不会将它们与F
.
从另一个角度来看,这是罪魁祸首:
initial hello!
B:patch patch!
F new feature!!!
Git 不会跟踪提交中的更改。它存储您的完整项目状态。“更改”是通过将提交与其父(或前任)提交进行比较来确定的。因为B
有补丁,git 将这个变化与B
. 因此,预计补丁也会出现F
。它不会出现的唯一方法F
是如果你删除了补丁。