12

我们有一系列这样的事件:

  1. 创建分支 A,并向其添加一些提交
  2. 时间流逝,数百个提交添加到 master
  3. Master合并到A
  4. 时间过去了,也许另外 50 个提交添加到 master

是否可以将步骤 3 中的合并转换为变基?如果不出意外,它将使即将进行的合并更简单,因为可以查看的历史更少。

我们还没有启用 rerere。

4

1 回答 1

18

考虑以下 Git 图:

A...C...D...F
^       ^   ^ master
 \       \
  G...H...I...J
              ^ feature

... 表示“大量提交”。

假设我们想从本质上进行变基,即获取特性历史中的提交,而不是主历史中的提交,并将它们修改为 master 中的线性提交序列。这与我们在提交时将 master 合并到 feature 的事实混淆了I。如果我们尝试 rebase,Git 会搞砸,因为它会尝试C在 master 之上应用例如并发现冲突。

feature我们可以通过从中获取实际更改并将它们打包到一个新的提交中来解决这个问题。这是一种仅使用非常基本的 Git 命令的方法:

(1) git checkout feature
(2) git merge master
(3) git reset A
(4) git add -A  # This stages all working copy changes
(5) git commit -m "Every change between A and J"

在步骤 (2) 中,分支在和feature中都有所有变化。在第 (3) 步之后,HEAD 指向,但我们的工作副本具有来自和的所有更改,并且步骤 (4) 和 (5) 暂存并提交这些更改。masterJAmasterJ

此时我们的图表看起来像这样

A...C...D...F
^           ^ master
 \
  J'
  ^ feature

请注意,它J'包含A...F. 现在我们做

git rebase master

Git 很乐意将更改应用J'为新的提交J'',但要添加的唯一更改是那些更改,G...J因为其他更改已经在 master 中。所以现在我们有

  A...F<--J''
master^   ^feature

我们分支中的所有更改都被feature压缩到 commitJ''中。此时,您可以根据需要以更精细的方式(甚至使用)重置F并重新应用更改。J''git add --patch


另一种做本质上相同的事情的方法是read-tree这个其他答案中解释

git checkout master
git read-tree -u -m feature

从这个答案中窃取的另一种做同样事情的方法是

git diff master > feature.patch
git checkout master
patch -p1 < feature.patch
于 2018-02-21T18:37:30.447 回答