修改先前合并的分支的过去提交,同时保留分支历史记录

时间:2016-02-17 23:09:40

标签: git branching-and-merging git-rebase

问题

说我在master做了一些工作:

c1 <- c2
       ^
     master

此时,我分道扬and,再做一些工作:

                test                  
                 v
          c3 <- c4
c1 <- c2 /
       ^   
     master

然后执行git merge --no-ff--no-ff以保留分支历史记录):

                test                  
                 v
          c3 <- c4
c1 <- c2 /        \ [c5]
                      ^   
                    master

[c5]是合并提交)

然后我删除了test分支,认为我已经完成了它。但是,我发现,毕竟我在test上所做的工作存在问题。我需要修改c3,但不会损害分支历史记录。

我尝试过的事情


我的尝试

git checkout c3;然后改变我需要改变的内容,然后git commit --amend。然后我checkout master分支和git branch temp c3。然后我git rebase --preserve-merges temp:这会给我一个合并冲突,我会修复,然后是git add <file>git rebase --continue

但是,当我使用git log --oneline --graph查看分支历史记录时,我会看到以下内容:

*  [c5]
|\
| * c4
|/
* c3'
* c2
* c1

看起来应该更像这样:

*  [c5]
|\
| * c4
| * c3'
|/
* c2
* c1

其中c3'是修改后的提交。

如何从git中获取此行为?

<2>蒂姆的建议
git checkout c3
git checkout -b test
git commit --amend
git checkout master
git reset --hard c2
git merge --no-ff test

不幸的是,这似乎不起作用,因为我们失去了c4。 (请纠正我,蒂姆,如果我误解了你的答案。)git log --oneline --graph得到的分支历史记录如下:

*  [c5]
|\  
| * c3'
|/  
* c2
* c1

其中[c5']是新的合并提交。 (顺便说一下,我不介意它是新的。)

3 个答案:

答案 0 :(得分:1)

您可以使用交互式rebase:

git checkout master
git rebase -i c2

这应该打开一个编辑器,每次提交一行。将pick行中的c3更改为edit。保存并关闭。现在git将你回到c3并停在那里让你进行编辑。通过

更改要更改的内容并进行修改
git commit --amend
git rebase --continue

答案 1 :(得分:1)

我似乎找到了答案! Tim,感谢你尝试import matplotlib.pyplot as plt import numpy as np import pandas as pn import seaborn as sns iris = sns.load_dataset("iris") with sns.axes_style("white"): sns.set_palette("BuGn_r") g2 = sns.jointplot("sepal_width", "petal_length", data=iris, kind="kde", space=0) with sns.axes_style("white"): sns.set_palette("Greens") g3 = sns.jointplot("sepal_width", "petal_length", data=iris, kind="kde", space=0) rebase的灵感。

基本上,答案在于做--interactive;我在分支历史分叉git rebase -p -i <root>之前调用提交。在问题的假设情况下,<root><root>

c2-p的简写,它将阻止--preserve-merges删除合并提交。

编辑器会弹出如下内容:

git rebase

pick c3 <message> pick c4 <message> pick [c5] <message> 之前的pick更改为c3,以便您拥有:

edit

保存并退出。进行您要进行的更改,添加更改以及edit c3 <message> pick c4 <message> pick [c5] <message> 。在此之后,您需要git commit --amend继续变基。

在此期间您可能会遇到合并冲突。只需修复冲突,git rebase --continue已更改的文件将冲突标记为已修复,然后git add。重复此操作,直到git rebase --continue告诉您rebase已成功。

答案 2 :(得分:0)

如你的问题所示,当你在测试分支中进行c4提交并将其合并到master分支时,快进模式只会将主引用移动到c4,为什么你认为你将丢失分支历史并使用 - 有目的的no-ff选项?

关于您尝试过的内容,您似乎修改了主分支时间轴的时间轴,因此提交图是一个明显的结果。