0

我已经在 SO 和其他文档上对此进行了研究。我尝试过变基、合并、挑选和分离头。

在尝试了 6 个小时之后,是时候提出这个问题了!

这是我开始的内容:

A-B-C-D-E-F-G master

这是我想将其更改为:

A-B      F-G  master
   \    / 
    C-D-E dev

我最接近的是:

A-B      C-D-E-F-G-H Main
   \    / 
    C-D-E dev
        \
         F-G master

我必须添加另一个分支名称和一个虚拟提交才能使分支完全正常工作。

但这比没有变化更糟糕。

请帮忙!

回复后更新

感谢您的回复。

是的,我的“我想要什么”不是很清楚。希望这可以澄清它:

A-B   -  F-G  master
   \    / 
    C-D-E dev

换句话说,F 处的“master”是 B 加上分支“dev”合并到其中的结果。

还是行不通

感谢@frasertweedale 的尝试回答。

我已仔细按照您的指示进行操作,结果如下:

A-B   -  "merge branch 'dev'"-G  master
   \    / 
    C-D-E dev
        \ 
         F-G-"merge branch 'dev'"-F-G

我很高兴这很难:现在花了 7 个小时在这上面,我感觉没有那么糟糕!

最终结果 正如@frasertweedale 所说,这正是我想要的,除了悬空提交。

所以,我只需要摆脱悬垂。

为了清楚起见,我在下面重新绘制了:

A-B   -  "merge branch 'dev'"-G2  master
   \    / 
    C-D-E dev
        \ 
         F1-G1-"merge branch 'dev'"-F2-G2

这个命令进行清理:

git rebase -p --onto F1^ F1

结果:

A-B   -  "merge branch 'dev'"-G2  master
   \    / 
    C-D-E dev

“merge branch 'dev'” 包含原始的 F 提交,当然,可以这样重新注释。

4

1 回答 1

0

假设您将A,B等扩展为相应的提交哈希,即masterat G,第一步是在 处分devE

git branch dev E

然后重置masterB

git reset --hard B

接下来,merge devinto master,明确要求合并提交(否则它将执行快进,因为 dev没有偏离master):

git merge --no-ff dev

master现在包含最多E. 现在您可以挑选原始文件FG提交。

git cherry-pick F
git cherry-pick G

现在你有了非常接近你想要的东西;唯一的区别是添加了合并提交(B+E)

A-B   -  (B+E)-F-G  master
   \    / 
    C-D-E dev

如果您现在想F在合并提交中包含 的内容(B+E),您可以执行交互式 rebase并将两个提交压缩在一起。( --preserve-mergesalias -p) 选项是必不可少的。

git rebase --interactive --preserve-merges B

这将调用内容类似于以下内容的编辑器(提交哈希和摘要会有所不同):

pick d4057bd c
pick 9419ef8 d
pick ad9e208 e
pick 120a90a Merge branch 'dev'
pick 61552ad f     
pick c947153 g

将提交行pick开头的指令替换为指令(在上面的示例中:),然后保存并退出。系统将提示您从合并提交的提交消息中形成新的提交消息,然后 rebase 操作将完成,无需进一步交互。在 rebase 之后,您将拥有所要求的存储库历史记录(在您更新的问题中)。Fsquashsquash 61552ad fF

缩写脚本

以下脚本创建具有线性历史记录的新存储库,然后使用(大部分)与上述相同的步骤自动编辑历史记录。避免了交互式变基,因此不需要用户干预。

mkdir foo ; cd foo
git init
for C in A B C D E F G; do
    echo $C > $C
    git add $C
    git commit -m $C
    git tag $C
done
git branch dev E
git reset --hard B --
git merge --no-ff dev
git cherry-pick F
git reset --soft HEAD~
git commit --amend -m F
git cherry-pick G
for C in A B C D E F G; do
    git tag -d $C
done
于 2015-03-26T04:08:11.423 回答