如何在Git中将最后一个提交分成两部分

我有两个工作分支, 主人论坛 ,我刚刚在论坛分支做了一些修改,我想挑选成主人 。 但不幸的是,我想挑选的承诺还包含一些我不想要的修改。

解决scheme可能会以某种方式删除错误的提交,并用两个单独的提交replace它,一个是我想要在master中select的更改,另一个不属于那个。

我试过了

git reset --hard HEAD^ 

其中删除了所有的变化,所以我不得不回去

 git reset ORIG_HEAD 

所以我的问题是, 最后一个提交分成两个独立提交的最好方法什么?

你应该使用索引。 在做一个混合重置(“ git reset HEAD ^”)之后,将第一组更改添加到索引中,然后提交它们。 然后提交其余的。

您可以使用“ git add ”将文件中所做的所有更改放入索引。 如果你不想在文件中进行每一个修改,只有其中的一部分,你可以使用“git add -p”。

我们来看一个例子。 假设我有一个名为myfile的文件,其中包含以下文本:

 something something else something again 

我在上次提交中修改了它,现在看起来像这样:

 1 something something else something again 2 

现在我决定把它分成两部分,我想插入第一行是在第一个提交中,最后一行插入到第二个提交中。

首先我回到HEAD的父级,但是我想保留文件系统中的修改,所以我使用“git reset”而没有参数(这将做一个所谓的“混合”重置):

 $ git reset HEAD^ myfile: locally modified $ cat myfile 1 something something else something again 2 

现在我使用“git add -p”来添加我想要提交到索引(=我阶段他们)的更改。 “git add -p”是一个交互式工具,它会询问你添加到索引的文件有什么变化。

 $ git add -p myfile diff --git a/myfile b/myfile index 93db4cb..2f113ce 100644 --- a/myfile +++ b/myfile @@ -1,3 +1,5 @@ +1 something something else something again +2 Stage this hunk [y,n,a,d,/,s,e,?]? s # split this section into two! Split into 2 hunks. @@ -1,3 +1,4 @@ +1 something something else something again Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y # yes, I want to stage this @@ -1,3 +2,4 @@ something something else something again +2 Stage this hunk [y,n,a,d,/,K,g,e,?]? n # no, I don't want to stage this 

然后我承诺这第一个改变:

 $ git commit -m "Added first line" [master cef3d4e] Added first line 1 files changed, 1 insertions(+), 0 deletions(-) 

现在我可以进行所有其他更改(即放在最后一行的数字“2”):

 $ git commit -am "Added last line" [master 5e284e6] Added last line 1 files changed, 1 insertions(+), 0 deletions(-) 

让我们来检查日志,看看我们有什么提交:

 $ git log -p -n2 | cat Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8 Author: ... Date: ... Added last line Diff --git a/myfile b/myfile Index f9e1a67..2f113ce 100644 --- a/myfile +++ b/myfile @@ -2,3 +2,4 @@ something something else something again +2 Commit cef3d4e0298dd5d279a911440bb72d39410e7898 Author: ... Date: ... Added first line Diff --git a/myfile b/myfile Index 93db4cb..f9e1a67 100644 --- a/myfile +++ b/myfile @@ -1,3 +1,4 @@ +1 something something else something again 

目标:

  • 我想把过去的提交( splitme )分成两部分。
  • 我想维护提交消息

计划:

  1. splitme之前的一个交互。
  2. 编辑splitme
  3. 重置文件以拆分为第二次提交。
  4. 修改提交,保留消息,必要时修改。
  5. 添加从第一次提交中分离出来的文件。
  6. 提交一个新的消息。
  7. 继续rebase。

如果splitme是最近的提交,则可以跳过基础步骤(1和7)。

 git rebase -i splitme^ # mark splitme commit with 'e' git reset HEAD^ -- $files git commit --amend git add $files git commit -m "commit with just some files" git rebase --continue 

如果我想要首先提交分割文件,那么我会再次重新绑定-i并切换顺序

 git rebase -i splitme^ # swap order of splitme and 'just some files' 

要将当前提交更改为两个提交,可以执行以下操作。

或者:

 git reset --soft HEAD^ 

这撤销了最后一次提交,但是一切都已经完成。 您可以取消某些文件:

 git reset -- file.file 

可以select重新设置这些文件的一部分

 git add -p file.file 

做一个新的第一次提交:

 git commit 

阶段并在第二次提交中落实其余的更改:

 git commit -a 

要么:

撤消和取消上次提交的所有更改:

 git reset HEAD^ 

select性地进行第一轮变革:

 git add -p 

承诺:

 git commit 

提交其余的更改:

 git commit -a 

(在任一步骤中,如果你没有提交添加一个全新文件的提交,并且想将其添加到第二个提交中,则必须将其手动添加为commit -a只有阶段才会更改为已经跟踪的文件。

运行git gui ,select“修改最后提交”单选button,然后取消(Commit> Unstage From Commit或CtrlU )更改,您不想进入第一次提交。 我认为这是最简单的方法。

你可以做的另一件事是樱桃select没有提交( git cherry-pick -n ),然后手动或使用git gui在提交之前select所需的更改。

 git reset HEAD^ 

– 硬是什么杀了你的改变。

我很惊讶没有人build议git cherry-pick -n forum 。 这将从最新的forum提交阶段进行更改,但不提交 – 然后,您可以reset不需要的更改,并提交您想要保留的更改。

双重还原 – 挤压法

  1. 进行另一次提交,以删除不需要的更改。 (如果是每个文件,这真的很简单: git checkout HEAD~1 -- files with unwanted changesgit commit文件如果没有,混合改动的文件可以部分地被git reset filegit add -p file作为中间步骤)称这是恢复
  2. git revert HEAD – 进行另一次提交,添加不需要的更改。 这是双重回复
  3. 在你现在提交的两个提交中,第一个压缩提交到分裂( git rebase -i HEAD~3 )。 现在这个提交变成免费的,因为那些是在第二次提交。

优点

  • 保留提交消息
  • 即使提交分裂不是最后一个工程。 它只需要不需要的更改不会与以后的提交冲突