Git 我可以将推送提交从一个分支移动到另一个现有分支吗?

Git 我可以将推送提交从一个分支移动到另一个现有分支吗?,git,git-branch,Git,Git Branch,我有三个分支:develope、feature-1和feature-2。我正在处理feature-1,然后切换到feature-2。然后我完成了feature-2,提交并推送到repo,然后为该功能创建了一个合并请求。然后我看到feature-2包含了一些应该在feature-1中的提交。我可以将它们从feature-2本地移动到feature-1,然后在回购协议中反映相同的移动吗?

我有三个分支:
develope
feature-1
feature-2
。我正在处理
feature-1
,然后切换到
feature-2
。然后我完成了
feature-2
,提交并推送到repo,然后为该功能创建了一个合并请求。然后我看到
feature-2
包含了一些应该在
feature-1
中的提交。我可以将它们从
feature-2
本地移动到
feature-1
,然后在回购协议中反映相同的移动吗?

是你的好朋友

  • 继续功能2分支
  • 复制
    commit id
    您想从
    feature-2
    移动到
    feature-1
  • 切换到功能1分支
  • 现在,选择上面步骤2中复制的所有提交

    git cherry pick

    如果要将多个提交移动到
    feature-1
    ,请按提交日期/时间顺序放置所有提交ID

    例如:

    git cherry pick


  • 您的问题表示所讨论的提交属于
    feature-1
    ,而不属于
    feature-2
    分支。公认的答案并不能做到这一点

    cherry pick
    是在一个分支上创建一个新提交的好方法,它复制了提交在另一个分支上所做的更改;但它不会改变另一个分支

    比如说,如果你从

    x <--(master)
    |\
    | A1 -- A2 <--(feature_1)
     \
      B1 -- A3 -- B2 <--(feature_2)
    
    因此,
    feature_1
    看起来像是您现在想要的,但是
    feature_2
    仍然有一些可能不应该有的更改。当您将两个功能合并到
    master
    中时,这可能会导致一些问题。(我的意思是,可能存在没有多大意义的合并冲突。
    git
    确实试图在这里提供帮助,但它不可能是完美的。)

    在您的问题中,您注意到提交已经被推送,并且在回答
    cherry pick
    答案时,您询问更改是否会
    干净地推送
    ;因此,我假设您遇到了(至少部分)在您推动的分支上重写历史的问题

    虽然
    cherry pick
    的结果确实会
    干净地推送
    ,但这是因为
    cherry pick
    没有进行您要求的所有更改(如上所述)。是对
    功能-2
    的修复导致了
    推送的问题

    一种解决方案是使用
    cherry pick
    修复
    feature-1
    ,然后使用
    revert
    修复
    feature-2
    。在我们的示例中,使用
    feature-2~1
    作为标识要“移动”的提交的表达式(您通常可以使用提交ID或适合您实际情况的表达式):

    给你

    x <--(master)
    |\
    | A1 -- A2 -- A3' <--(feature_1)
     \
      B1 -- A3 -- B2 -- !A3 <--(feature_2)
    
    此时将打开一个编辑器,显示
    重设基础的“待办事项”列表。列表中的每个条目都是如何处理提交的指令。删除要“留下”的提交的行。(您还可以对提交在
    feature-1
    上的表示方式进行其他调整;但这是一个很长的兔子洞,因为到目前为止,您所要做的就是如何“移动”提交,所以这些步骤将使提交保持“原样”。)

    当您保存并退出编辑器时,
    重新基址
    将开始,重写所有选定的提交。通过以下步骤完成对
    功能-1的更新

    git checkout feature-1
    git merge temp
    git branch -d temp
    
    您仍然需要转到
    feature-2
    ,以还原不应该存在的提交;您可能希望在带有
    -n
    标志的单个命令中执行此操作,以便只创建一个revert commit。(这将产生副作用,降低我上面提到的风险,即在您执行
    恢复
    后,某些
    重新设置基址
    操作的风险;但是,鉴于此问题隐含的约束,我希望您无论如何都不会执行这些类型的
    重新设置基址

    现在,有些人不喜欢使用
    revert
    进行此类操作,因为历史记录显示了发生的情况,包括进行更改和随后删除更改,这可能看起来很烦人,因为根本不应该进行更改


    避免这种情况的唯一方法是“重写”功能-2的历史记录,不管你怎么做,它都不会干净地推送。您可以将其推送至
    push
    ,但这样做会为拥有
    feature-2
    副本的所有其他开发人员创建工作,如果他们做了错误的事情,将撤消您的工作。因此,如果你想改写历史,你必须与其他使用回购协议的人协调。有关详细信息,请参阅“从上游重新基恢复”下的
    git-rebase
    文档。

    从技术上讲,您不移动提交,而是创建一个具有相同内容的新提交,git在合并时会记住此副本。@curiousManish谢谢。当我移动提交时,
    gitpush
    会在repo中显示相同的更改吗?yep@GluePear。可能重复的可能重复的
    x <--(master)
    |\
    | A1 -- A2 -- A3' <--(feature_1)
     \
      B1 -- A3 -- B2 -- !A3 <--(feature_2)
    
    git checkout feature-2
    git branch temp
    git rebase -i feature-1 temp
    
    git checkout feature-1
    git merge temp
    git branch -d temp