2

想象一下,我们有两个存储库,其中正在开发相同的软件。一个是交付给客户的旧版本,错误正在得到修复等等。另一个是对同一个软件的完美重写,A 中出现的所有问题现在都很棒而且很闪亮(对……)。

所以随着时间的流逝,无论出于何种原因,我们都认为重写是成功的。我们决定淘汰旧版软件。然而,我们希望保留它的历史(以防万一,你知道……),同时摆脱对两个存储库的需求。

假设存储库 A 如下所示:

      A---B---C 
     /         \
D---E---F---G---H---I master (A)

巧合的是,存储库 B 看起来像这样:

      S---R---Q
     /         \
K---L---M---N---O---P master (B)

所以,我们最想做的就是打字

[~/repo-a]$ git magic

并得到这个结果:

      A---B---C               S---R---Q
     /         \             /         \
D---E---F---G---H---I---K---L---M---N---O---P master (A)

然而可悲的是没有git-magic命令(完成我们想要的)。

到目前为止我尝试的是

一个]

查看git-rebase合并策略的手册页ours似乎是我们想要的

我们的

这解决了任意数量的头,但合并的结果树始终是当前分支头的树,有效地忽略了所有其他分支的所有更改。它旨在用于取代分支的旧开发历史。请注意,这与递归合并策略的 -Xours 选项不同。

[~/repo-a]$ git remote add shiny-rewrite git@github.com/orga/shiny-rewrite.git
[~/repo-a]$ git fetch shiny-rewrite
[~/repo-a]$ git checkout shiny-rewrite/master
[~/repo-a]$ git checkout -b shiny-master
[~/repo-a]$ git rebase -s ours master
First, rewinding head to replay your work on top of it...
Already applied: 0001 initial commit
Already applied: 0002 blablabla
Already applied: 0003 …
Already applied: 0004 ZOMG IT'S READY
All done.

然而,现在所有来自闪亮重写的提交都消失了。不完全是我们想要的。

乙]

“蛮力”替代方案

[~/repo-a]$ git rm -r *
[~/repo-a]$ git commit -am "DELETE ALL THE THINGS"
[~/repo-a]$ git remote add shiny-rewrite git@github.com/orga/shiny-rewrite.git
[~/repo-a]$ git fetch shiny-rewrite
[~/repo-a]$ git checkout shiny-rewrite/master
[~/repo-a]$ git checkout -b shiny-master
[~/repo-a]$ git rebase master
[~/repo-a]$ git checkout master
[~/repo-a]$ git merge shiny-master

但是,现在我们有了这个删除提交..

      A---B---C                  S---R---Q
     /         \                /         \
D---E---F---G---H---I---X---K---L---M---N---O---P master (A)
                       /\
                       ||
             "DELETE ALL THE THINGS"
4

1 回答 1

0

如果你在插入 K 之后挤压 X 和 K,你会得到你想要的。

我还通过挑选 K 来制作 X,以便 X 在压缩时保留 K 的提交者和日期。

1) git checkout I
2) git cherry-pick K
3) git rm -rf .
4) # only if there are conflicts in (2):
   git commit
   # only if there are no conflicts in (2):
   git commit --amend
5) git cherry-pick K  # yes, again
6) git rebase -i HEAD~2
7) # edit the file, changing the second commit in the list to a squash
8) # remove one of the duplicated commit messages
9) git rebase --onto HEAD --root P

第 3 步是将 X 转换为空提交,保留所有内容。

于 2020-05-04T17:41:48.733 回答