假设我在仅限本地的分支上有以下提交历史记录:
A -- B -- C
Run Code Online (Sandbox Code Playgroud)
如何在A和之间插入新的提交B?
SLa*_*aks 141
它比OP的答案更容易.
git rebase -i <any earlier commit>.这将在您配置的文本编辑器中显示提交列表.a1b2c3d).在您的编辑器中,对于该行,请更改pick为edit.a1b2c3d),就像它刚刚提交一样.git commit(不要修改,与大多数edits 不同).这会在您选择的提交之后创建新的提交.git rebase --continue.这将重放连续提交,将新提交插入正确的位置.请注意,这将重写历史记录,并打破任何试图拉动的人.
Bar*_*zKP 21
结果很简单,答案在这里找到.假设你在一个分支上branch.执行以下步骤:
在要插入新提交(在本例中为commit A)之后,从提交创建临时分支:
git checkout -b temp A
Run Code Online (Sandbox Code Playgroud)执行更改并提交它们,创建一个提交,让我们调用它N:
git commit -a -m "Message"
Run Code Online (Sandbox Code Playgroud)
(或其git add后git commit)
将新提交(在这种情况下提交B和C)之后要提交的提交重新绑定到新提交上:
git rebase temp branch
Run Code Online (Sandbox Code Playgroud)(可能你需要使用-p保存合并,如果有任何-感谢一个不再存在的意见通过ciekawy)
删除临时分支:
git branch -d temp
Run Code Online (Sandbox Code Playgroud)在此之后,历史看起来如下:
A -- N -- B -- C
Run Code Online (Sandbox Code Playgroud)
当然,在重新定位时可能会出现一些冲突.
如果您的分支不是本地分支,则会引入重写历史记录,因此可能会导致严重问题.
Mat*_*hew 14
更简单的解决方案
最后创建你的新提交,D.现在你有:
A -- B -- C -- D
Run Code Online (Sandbox Code Playgroud)然后运行:
$ git rebase -i hash-of-A
Run Code Online (Sandbox Code Playgroud)Git会打开你的编辑器,它看起来像这样:
pick 8668d21 B
pick 650f1fc C
pick 74096b9 D
Run Code Online (Sandbox Code Playgroud)只需将D移动到顶部,然后保存并退出
pick 74096b9 D
pick 8668d21 B
pick 650f1fc C
Run Code Online (Sandbox Code Playgroud)现在你将拥有:
A -- D -- B -- C
Run Code Online (Sandbox Code Playgroud)Rom*_*eri 13
这里已经有很多好的答案了。我只想通过 4 个简单的步骤添加一个“无变基”解决方案。
概括
git checkout A
# <<< modify your files at this point
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD
Run Code Online (Sandbox Code Playgroud)
解释
(注意:这个解决方案的一个优点是直到最后一步你才接触你的分支,当你 100% 确定你对最终结果没问题时,所以你有一个非常方便的“预确认”步骤允许进行 AB 测试。)
初始状态(我假设master您的分支名称)
A -- B -- C <<< master <<< HEAD
Run Code Online (Sandbox Code Playgroud)
1)首先将 HEAD 指向正确的位置
git checkout A
B -- C <<< master
/
A <<< detached HEAD
Run Code Online (Sandbox Code Playgroud)
(在这里,我们可以选择创建一个临时分支,而不是分离 HEAD,我们git checkout -b temp A需要在过程结束时将其删除。两种变体都可以工作,按照您的喜好进行,因为其他一切都保持不变)
2)创建要插入的新commit D
# at this point, make the changes you wanted to insert between A and B, then
git commit -am "Message for commit D"
B -- C <<< master
/
A -- D <<< detached HEAD (or <<< temp <<< HEAD)
Run Code Online (Sandbox Code Playgroud)
3)然后带上最后丢失的提交 B 和 C 的副本(即使中间有更多提交,命令也是相同的,因为这是选择一系列提交)
git cherry-pick A..C
# (if any, resolve potential conflicts between D and these last commits)
B -- C <<< master
/
A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)
Run Code Online (Sandbox Code Playgroud)
(如果需要,请在此处进行舒适的 AB 测试)
现在是检查你的代码,测试任何需要测试的那一刻,你也可以比较/比较/检查你有什么和你会得到什么样的操作后,只需通过交替检查C或C'。
4)取决于您在C和之间的测试C',它是 OK 还是 KO。
(EITHER) 4-OK) 最后,移动 refmaster
git branch -f master HEAD
B -- C <<< (B and C are candidates for garbage collection)
/
A -- D -- B' -- C' <<< master
Run Code Online (Sandbox Code Playgroud)
(OR) 4-KO)master保持不变
如果你创建了一个临时党支部,只是删除它git branch -d <name>,但如果你去了分离的头路线,没有在所有的在这一点上需要采取行动,新的提交将符合垃圾收集你重新刚过HEAD了git checkout master
在这两种情况下(OK 或 KO),此时只需master再次结帐以重新附加HEAD.
hao*_*lee 12
假设提交历史是preA -- A -- B -- C,如果要在A和之间插入提交B,则步骤如下:
git rebase -i hash-of-preA
Git将打开你的编辑器.内容可能是这样的:
pick 8668d21 A
pick 650f1fc B
pick 74096b9 C
Run Code Online (Sandbox Code Playgroud)
将第一个更改pick为edit:
edit 8668d21 A
pick 650f1fc B
pick 74096b9 C
Run Code Online (Sandbox Code Playgroud)
保存并退出.
然后修改你的代码 git add . && git commit -m "I"
git rebase --continue
现在你的Git提交历史是 preA -- A -- I -- B -- C
如果遇到冲突,Git将停止此提交.您可以使用它git diff来定位冲突标记并解决它们.在解决所有冲突之后,您需要使用git add <filename>告诉Git已解决冲突然后重新运行git rebase --continue.
如果要撤消rebase,请使用git rebase --abort.
这是一种避免在我阅读的其他答案中看到的变基期间进行“编辑hack”的策略。
通过使用git rebase -i您可以获取自该提交以来的提交列表。只需在文件顶部添加一个“ break”,这将导致rebase在那时中断。
break
pick <B's hash> <B's commit message>
pick <C's hash> <C's commit message>
Run Code Online (Sandbox Code Playgroud)
一旦启动,git rebase现在将在“中断”点停止。现在,您可以编辑文件并正常创建提交。然后,您可以使用继续重新设置基准git rebase --continue。这可能会导致您必须解决的冲突。如果您迷路了,别忘了您可以随时使用中止git rebase --abort。
可以普遍采用这种策略,以在任何位置插入提交,只需将“ break”放在要插入提交的位置即可。
重写历史记录后,请不要忘记git push -f。有关其他人提取您的分支的常规警告也适用。
| 归档时间: |
|
| 查看次数: |
28462 次 |
| 最近记录: |