在git中,如何在不合并的情况下承诺掌握?

时间:2014-06-23 04:34:42

标签: git squash

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意味着您必须再次执行此未合并的文件合并。

2 个答案:

答案 0 :(得分:2)

使用Git解决问题的方法不止一种,但最常用的方法之一就是在尝试合并之前简单地将分支B重新绑定到主分支上。 < / p>

假设X是分支A和B之间的共享共同祖先提交。然后

  1. 将B重新投入主人

    git rebase --onto master X B
    

    这将在X之后进行所有提交并导致B,并在主分支之上重新应用它们。您可能仍需要解决冲突,但是您将在较小的块中解决它们,因为您逐个重新应用提交。

  2. 接下来,您可以使用软重置压缩分支B,然后提交(请注意,这不是压缩B的唯一方法):

    git reset --soft X
    git commit -m "Squashing B"
    

    请注意,您可以撤销步骤#1和#2。唯一的区别是,首先挤压B,你最终必须在重组后再次解决所有冲突。

  3. 将B合并为主,

    git checkout master
    git merge B
    
  4. 除了上面的步骤#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用于创建合并提交的命令。这允许您在当前分支之上创建单个提交,其效果与合并另一个分支相同(或者在章鱼的情况下更多)。