TL; DR;我想要一种方法来告诉git“master有一个新版本看起来与功能A的提示完全相同,但没有历史记录”。
有办法做到这一点吗?
[更新:我现在有一个最小化此问题的工作流程,但我仍然想知道如何告诉git执行以下操作: -
将一个更改提交到branchX,使所有文件和文件夹与分支Y的尖端匹配。这可能吗?]
后面的故事
我们通常避免从功能分支分支..但在这种情况下必须。这是我们试图做的: -
master o-----------------o---------------o
\ /[squash] /
feature A o-o-o-o-o-o-o-o / [squash] -- too many conflicts
\ /
feature B o-o-o-o-------------o
由于各种原因,我们总是挤在主人身上。但是由于特征B与特征A有一些共同的变化,第二次挤压有很多合并冲突。
我试过了......
master o-----------------o----------------o
\ /[squash] / [squash] -- same set of conflicts!!
feature A o-o-o-o-o-o-o-o----------------o
\ / (merge) -- easy
feature B o-o-o-o--------------o
(合并)很简单,左边的功能A完全具有我想要拥有的文件集(因为功能A和master在合并到master之后具有相同的文件)。这种合并很容易,因为Git知道只有特征B分支后的冲突需要解决。
那时我想要将现在合并的功能A分支提交到master。但我得到了同样的一系列冲突,我试图避免。
功能A具有我想要的所有更改...因此我可以检查主要功能A并将所有文件复制到主服务器中,然后提交。事实上,这就是我最终做的......但是肯定有一种方法可以用git做到这一点?!?
我尝试从主生成二进制补丁到功能A ,然后应用它。
git diff --binary master featureA > patch
git apply patch
由于“补丁不适用”错误而失败。
我尝试了各种其他尝试合并......所有这些都导致我必须解决我已经解决的所有相同的合并冲突。
合并是从特征B到掌握的痛苦的原因是在特征B分支之前在特征A中改变的文件在提交之前由特征A进一步改变。这意味着Git认为这些文件在功能B中已更改,但它们与功能A中提交的文件不同,因此需要进行合并。
在提交之前重新设置主设备上的功能B意味着您必须再次执行此未合并的文件合并。
答案 0 :(得分:2)
使用Git解决问题的方法不止一种,但最常用的方法之一就是在尝试合并之前简单地将分支B重新绑定到主分支上。 < / p>
假设X是分支A和B之间的共享共同祖先提交。然后
将B重新投入主人
git rebase --onto master X B
这将在X之后进行所有提交并导致B,并在主分支之上重新应用它们。您可能仍需要解决冲突,但是您将在较小的块中解决它们,因为您逐个重新应用提交。
接下来,您可以使用软重置压缩分支B,然后提交(请注意,这不是压缩B的唯一方法):
git reset --soft X
git commit -m "Squashing B"
请注意,您可以撤销步骤#1和#2。唯一的区别是,首先挤压B,你最终必须在重组后再次解决所有冲突。
将B合并为主,
git checkout master
git merge B
除了上面的步骤#2和#3,如果您执行了步骤#1,那么您可以使用git merge --squash
压缩并合并分支B,
git checkout master
git merge --squash B
git commit -m "Squashed and merged B"
答案 1 :(得分:0)
原始海报说明:
(合并)很简单,左边的功能A完全具有我想要主人拥有的文件集(因为功能A和主人在合并到主人后具有相同的文件)。
同样,正如我指出的in the comments,这没什么意义,你没有列出导致你的结果的命令序列。
但是,我会根据你的这个问题回答你的问题,忽略所有其他不清楚的信息(强调我的):
向分支X提交单个更改,以使所有文件和文件夹与分支Y的尖端匹配。这可能吗?
您可以先将X合并为Y,然后使用--strategy ours
或-s ours
选项忽略X中的所有更改,从而使分支X与Y匹配。然后在使用--squash
时将Y合并回X(快进合并):
git checkout Y
git merge --strategy ours X
# Verify that Y is unchanged
git diff Y^
git checkout X
git merge --squash Y
git commit
# Verify that X matches Y
git diff Y
来自official git-merge(1) Manual Page:
合并策略
ours
这解决了任意数量的头,但是合并的结果树始终是当前分支头的树,实际上忽略了来自所有其他分支的所有更改。它旨在用来取代边支的旧发展历史。
以下是documentation for --squash
:
选项
--squash
生成工作树和索引状态,就像发生了真正的合并一样(合并信息除外),但实际上并不提交或移动HEAD,也不记录
$GIT_DIR/MERGE_HEAD
以导致下一个{{1用于创建合并提交的命令。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支相同(或者在章鱼的情况下更多)。