更新 - 重读你的帖子,我意识到我完全错过了merge --squash
问题......事实上,rebase
的方法,我形容是基本相同,做一个merge --squash
,与它更容易重复的差异。 (那么,我不知道--squash
,因为我是n00b。)
无论如何,您对做merge --squash
的关注是该分支“基本上是分歧的”。这是真的;如果你这样做的话(或者按照下面略述的重新定义),在D
和d
提交之间没有git血统链接。但只要你跟踪有多少wip
已被压扁到dev
,它不会使任一分支无用 - 它们的内容没有发散,只有拓扑。 (所以这就是为什么移动一个标签来表示你最后的--squash
或rebase
可以让你摆脱困境。)
但是如果你想保持拓扑关系,那么--no-ff
合并就是要走的路。问题似乎是,你喜欢一些关于有D
知道它来自d
的东西,以及一些关于它不知道的事情;所以你必须决定你宁愿选择哪一个。
如果它知道,那么例如默认log
将显示更细粒度的历史记录(但具有正确的选项可以覆盖该历史记录)。如果它不知道,那么未来在简单merge
上的尝试将会使git交叉,并且您必须自己跟踪“真正”上游(内容方面),例如下面示例中的rebaseUpstream
标记。
那么,你的文字和你的照片并没有说完全一样的东西。
图片是您通过简单合并--no-ff
选项而获得的。所以,当dev
为A
和wip
为d
,你融入dev
创建D
- 单个提交其以dev
,代表你b
,c
,并d
做了wip
一切。
现在你可能认为我是错误的,因为如果你从dev
做git log
你仍然可以看到b
,c
,并d
作为单独提交。这是因为git试图帮助您完全了解D
的历史记录,并且为了防止它会给git log
--first-parent
选项(使其仅在dev
分支中“向上”)。在这种情况下,您需要确保您的合并提交具有良好的提交消息。
但是你写的你想要的是不同的 - 也可以做,但有点毛。如果你做了一个压缩和重组,D
不会是d
的孩子 - 这就是为什么我说你的照片显示合并。
诀窍使之与rebase
工作是了解rebase
不破坏承诺,即使在正常使用中它看起来好像没有。你可以看到它不是通过让两个分支指向同一个提交,并将其中一个分支重新绑定。事实上,这就是你如何做你想问的问题。
但被警告:这种方式的疯狂谎言。
所以我们回到你的图表。在开始时,您在A处有dev
和wip
。在此处放置标签,因为我们总是想知道wip
已有多少dev
。
git tag rebaseUpstream
现在做一些工作,根据您所需的工作流程,直到你在d
有wip
。然后
git checkout -b rebaseTip
git rebase --interactive --onto master rebaseUpstream
现在你在待办事项列表编辑器,因此从pick
改变c
和d
说明squash
,然后让“呃裂口。那么当然你可以编辑压扁的提交信息。
现在你有发展的两条线,指了指dev
- 一个只有D
和一个与b
,c
和d
。接下来我们需要更新dev
。
git checkout dev
git merge rebaseTip
git branch --delete rebaseTip
现在有了这个麻烦的是Git并不知道D
和d
有任何关系。另一方面,这意味着git log
或类似的,当完成dev
时,将显示你所希望的 - 无需额外的选择。但坏消息是,如果你不小心,你会失去多少在dev
。为了降低这种风险
git checkout wip
git tag -f rebaseUpstream
现在你可以恢复你对wip
分支流程,并重复整个事情往往你喜欢。
_I不能只南瓜rebase_的提交。从技术上讲,只要_you可以肯定,没有其他人使用** wip **分支。 – pathfinderelite
是的,我想过,因为这个想法确实是** wip **分支只应该是我的。我对事故有点担心,认为可能有更好的方法可以避免这个潜在的问题。也许我不应该关注它自己,只是指定分支来反映它本身就是我的。 – cgbrown