1

我在功能分支上工作了几天,现在可以合并到dev. 在开发此功能时,我已合并dev以接收补丁。我的历史是这样的:

* E (feature1)
* D:merge with dev
|  \ 
* C * B:patch (dev)
  \ | 
    * A

我想将整个分支压缩成一个提交,合并dev然后快进dev。问题是,当合并发生在它们之间时,E不能被压扁。C唯一的选择似乎是 squash EB并且C(调用新的 commit F),在这种情况下,被压缩的提交还将包括作为不相关补丁一部分的更改。一旦合并到dev中,将有两个应用补丁的提交:(F应用补丁并添加功能)和B(仅应用补丁)。此外,F现在将进行两个不相关的更改。

有没有办法让我的历史保持干净整洁?我需要改变我的工作流程吗?

4

3 回答 3

1

Git 不会跟踪提交中的更改。每个提交都包含存储库中文件的完整副本。“更改”是通过区分两个提交来确定的。

所以,简而言之,squashing 绝对没有问题EBC提交F,然后将其合并到 dev 分支上。B提交仍将存在于 dev 分支上。当 git 与 比较FB,只有 和 引入的更改CE归因于F.

当然,您可以使用git rebase. 例如,由于git rebase更改了您的分支历史记录(将您的提交移动到来自 dev 的最新提交之上),如果存在冲突,您必须在每次 rebase 时重新解决这些冲突。如果您的问题需要一段时间才能解决,这会很快过时,需要多次变基才能与开发人员保持同步。


只是为了证明这一切都是真的并且您无需担心,我设置了一个示例 GitHub 存储库:https ://github.com/cyborgx37/sandbox

首先,我们有dev分支,它有B提交。

B:patch
|
A

然后我创建了feature1分支,它有提交C和. (注意,因为 D 是一个合并,因此有两个父级,也显示在提交历史中)DEB

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是如果你删除了补丁。

于 2017-10-12T04:41:43.833 回答
0

这就是我所做的:我将E,BC放入一个新的 commitF中,并带有F说它实现了 feature1 的消息(注意到目前为止它还添加了补丁)。然后我重新定位到dev. 现在提交消息和历史是正确F的:包括补丁,但它没有添加它——它是由先前的提交添加的。

最后,我合并了dev(与--no-ff强制合并提交)。

将来,我将避免与合并dev和变基。

于 2017-10-18T00:32:27.870 回答
0

如果我理解正确,您希望将提交的全部内容E作为单个提交应用到B.

如果这是您想要实现的目标,您可以使用git checkout E .(不要忘记"."):

# go to your `dev` branch :
git checkout dev

# get the *content* of E (here comes the ".") :
git checkout E .

# all the content of E should appear as modifications staged for commit :
git status -sb

# you can double check that the content is to your liking :
git diff --cached  # --cached means 'compare with the index'
gitk --cached      #  as opposed to 'compare with what is on the disk'

# commit
git commit
于 2017-10-12T07:36:29.370 回答