Git将feature_branch中的单个提交移动到master

svo*_*l13 6 git rebase git-rebase cherry-pick

实现这一目标的最简单方法是什么?

从:

--A--B         
      \
       1--2--3 
Run Code Online (Sandbox Code Playgroud)

至:

--A--B--2
         \
          1--3
Run Code Online (Sandbox Code Playgroud)

我无法想出任何简单的方法来实现这一点(少于5步).

tor*_*rek 8

你遗漏了标签; 让我们把它们放回去.这里是"之前":

--A--B          <-- master
      \
       1--2--3  <-- feature
Run Code Online (Sandbox Code Playgroud)

这里是"之后".我将使用刻度标记(或"素数"或任何您喜欢称之为的标记)来标记这些标记,因为它们将是原始提交的副本,具有新的和不同的提交ID.

--A--B--2'      <-- master
         \
          1'-3' <-- feature
Run Code Online (Sandbox Code Playgroud)

这不能一步完成:至少需要两次.

首先,我们必须重新排序1--2--3序列,以便2首先进行.最简单的方法可能是交互式rebase(在分支上feature,使用git命令git rebase -i master):只需更改pick顺序,rebase将选择2,然后是1,然后是3并移动feature标签:

--A--B          <-- master
      \
       2'-1'-3' <-- feature
Run Code Online (Sandbox Code Playgroud)

现在我们只需要移动master标签指向提交2'.许多命令都会执行此操作,但最简单的git merge命令是执行快进合并(以避免错误):

git checkout master; git merge --ff-only feature~2
Run Code Online (Sandbox Code Playgroud)

为了避免检查出master我们可以使用git branch -f作为VonC的答案(而我是编辑这一从而出现),例如:

git branch -f master feature~2
Run Code Online (Sandbox Code Playgroud)

(在这两种情况下,我们需要命名承诺2';用git branch我们必须命名移动的分公司,同时用git merge我们必须分支进行移动).


为了完整起见,这是一个不同但等效的方法(使用四个git命令).首先让我们来分支master:

git checkout master
Run Code Online (Sandbox Code Playgroud)

现在我们可以挑选提交2,创建副本,2':

git cherry-pick feature^     # or feature~1
Run Code Online (Sandbox Code Playgroud)

生成此图表:

--A--B--2'      <-- master
      \
       1--2--3  <-- feature
Run Code Online (Sandbox Code Playgroud)

现在我们可以feature交互式地重新定义新的master,丢弃的提交2:

git checkout feature
git rebase -i master
Run Code Online (Sandbox Code Playgroud)

pick行更改为复制1和3并省略2,因为提交2'已经存在master.