如何放弃旧的Git Master,并将分支用作新的Master?

时间:2019-01-28 14:27:05

标签: git

我们有一个项目,我们不得不一次回顾一下Git的历史,并从旧的提交开始创建一个新的分支(在这里称为“ new_branch”)。现在,所有开发都在new_branch中进行,并且在分支创建之后,旧的Master不再有用。因此,我们现在遇到的情况如下:

C1 = Commit 1, C2 = Commit 2, etc.

            C1                       
             |                       
            C2                       
             |\                      
            C3 \                     
             |  \                    
            ...  \                   
             |    \                  
Master -->  C17    \                         
                    \                
                   C18               
                    |                        
                   ...               
                    |                
                   C37 <-- new_branch

所以我现在想做的是放弃(撤消?)分支点之后,即C3到C17,在Master中所做的所有提交。至少,这就是我想做的?我的意思是,C3至C17现在已无用,如果我可以撤消它们,则可以将new_branch合并回Master,以使Master再次有用。

所以我的问题是,这是实现我再次使用Master的目标的正确方法吗?以及应该使用哪个命令(在Linux的命令行中使用Git)撤消C3到C17的提交?这是一个工作项目,因此正确无误非常重要。

3 个答案:

答案 0 :(得分:4)

最直接的解决方案是简单地将new_branch推到原点的master上:

git checkout new_branch
git push -f master

然后使用以下几种方法之一修复本地master

  1. git reset --hard origin/master分支master上)
  2. git branch -D master不在分支master上,再次拉动以获取更新的分支)

在这种情况下,无需使用master对现有的new_branch进行基础调整。

(显然)这将消除现有的master并将其替换为new_branch的内容和历史记录。 确定您的意图。


正如Romain指出的那样,使用git branch -f消除了本地修复步骤:

git branch -f master new_branch && git push -f origin master

因为它也将分支指针移动到本地。


与许多git问题一样,有很多方法可以解决此问题,其他答案可能同样可行。

答案 1 :(得分:2)

执行此操作有两种通用方法;每个都有缺点,所以这取决于您所处的情况。每种方法也都有差异,但权衡较小...


第一种方法是重写master的历史记录。这只是意味着移动master的方式会从其历史记录中删除当前属于其历史记录的某些提交。

任何历史重写,无论您如何操作都具有一定的成本-因此,通常最好以最简单的方式来满足您的要求。在这种情况下,可能是

git checkout master
git reset --hard new_branch
git push --force-with-lease

这实际上与msanford建议的方法相似,但是有两个优点。首先,它更加简洁(因为它首先更新了本地分支并将其用作更新rmeote的设置)。其次,将-f替换为--force-with-lease可以提供一些额外的安全性,因为它可以确保您没有意识到遥控器没有任何新承诺。 (在您的特定情况下,这可能不是什么大问题;但这是一个很好的习惯。)

对分支的历史记录进行重写的成本已在存储库之间共享(即push ed,然后-至少有可能-fetch ed或pull写入其他存储库)是共享分支的其他存储库将看到分支以“意外”的方式移动,并且必须进行恢复。恢复过程记录在git rebase文档的“从上游资源恢复中”部分中。在进行此操作时,与整个团队进行协调非常重要,就好像任何团队成员在恢复时做错了什么一样,它都可以撤消历史记录的重写。

好处是,您的历史记录非常好,根本不会显示已删除的提交。 (但是要注意,如果这些提交已被共享,则您无能为力,无法确保它们“永远消失”。如果它们包含敏感信息,那将是一个更大的问题,并且该信息基本上必须被视为已泄露-尽管存在您可以采取的步骤至少可以阻止此类信息的进一步传播。)

因此,如果您可以与回购的所有用户进行实际协调,这是一个不错的选择。但是,如果不能,那还有另一种方法。


第二种方法是撤消对主服务器的更改-即将其还原回C2-然后合并new_branch。这符合通常“分支到”分支的方式,因此不承担重写的费用。但是,这意味着被遗弃的提交(及其撤消)在历史上将永远存在。

git checkout master
git revert -n C3..HEAD
git commit
git merge new_branch

这为您提供了类似的历史记录

C1 - C2 - C3 - ... - C17 - R -- M <--(master)
       \                       /
        C18 - ........... - C37 <--(new_branch)

R使master的外观与C2一样,而M是对此的较新更改的简单合并。

如果您从-n命令中省略了revert选项,则可以跳过commit命令,但是您将获得一个单独的提交来撤消{{1} }至C3。如果您真的强烈认为这样做会更好,但也有一些技巧可以将更改的撤销嵌入到合并提交本身中,但是它会创建“恶意合并”,即隐藏更改并可能混淆用户和某些将来操作的合并像C17

缺点是历史比较混乱。 (如果您确实需要历史记录来记录自己的位置,那么可以说它更准确;但是它肯定更复杂,并且可以显示您可能不再需要的信息。如果还原的提交包含敏感信息,则肯定不适合你不想继续传播。)

但是,如上所述,它遵循正常的分支移动模式,因此避免了重写历史记录的费用。

同样,这取决于您所处的情况。

答案 2 :(得分:0)

因此,如果要擦除c3-c17,则可以签出c3,然后使用merge将新分支的更改放在最上面。然后,如果您将其推回主机​​,则c3-c17将消失