从历史记录中删除合并并重新调整非顺序提交的基础

2023-12-19

我有以下 git 历史记录,我想在其中压缩提交并删除多个合并

git log --graph --oneline --all
* 80e2fa1     I want to squash this commit
*   7850013   Merge branch 'master'  want to get rid of these branch merges
|\  
| * b645616 
| * 4aee207 
* | 6077ae7   Into this one
* | bc882a2  
|/  
* 7607733  
*   82643ed   Merge branch 'master'  
|\  
| * ead8b48  
* | 5fadbff  
|/  
* 2e0797c  
*   3552f8f   Merge branch 'master'  
|\  
| *  
* |  
|/  
* e1defac  
* 912c802  

但是当我尝试执行 git rebase --interactive 6077ae7 我最终得到

  The previous cherry-pick is now empty, possibly due to conflict resolution.

当我在合并之前进行变基时,我也没有得到合并,这是删除它们的正确方法吗?这对我不起作用git 从历史记录中删除合并提交 https://stackoverflow.com/questions/17577409/git-remove-merge-commit-from-history.


正常变基ignores合并。对于您的情况,这实际上会有帮助!

背景

首先,请记住变基副本提交。无论哪个提交实际上都会被重新定位,都会被复制。 (原始版本保留在您的存储库中,只是“放弃”,这样如果您不喜欢变基的结果,您可以挽救它们。一段时间后,默认情况下为 30 天,放弃变得更加永久,因为垃圾收集器现在允许真正删除它们。)

让我们从重新绘制图表开始git log --oneline以水平格式显示(这很有用并且有很多有用的信息),但会丢弃一些信息。这通常可能不太有用,但它应该更容易“看森林” https://en.wiktionary.org/wiki/see_the_forest_for_the_trees(可以说,忽略了一些树木)。我不确定你实际上在哪个分支,所以我只会使用标签somebranch(您当前的分支很可能是master,这是我的猜测,但我无法从您引用的日志输出中证明这一点)。

     o      o      B--C
    / \    / \    /    \
o--o   o--o   o--A      F--G   <-- somebranch
    \ /    \ /    \    /
     o      o      D--E

All the o提交是您的最早(最低行)的提交git log输出,而标记的提交A通过G是来自前 7 行。犯罪G(这是我们的单字母代码,代表80e2fa1) 是你想要“压缩”到提交中的那个C(真的6077ae7)。犯罪F是你说你想放弃的合并(真的7850013).

现在,最简单的形式git rebase只是git rebase没有任何争论,但这可能不是我们想要的。相反,我们需要复制并因此展平一些以以下任一开头的提交B--C或与D--E,以便看到这个结果:

     o      o
    / \    / \
o--o   o--o   o--A--D--E--B'-C'  <-- somebranch
    \ /    \ /
     o      o

或者这个:

     o      o
    / \    / \
o--o   o--o   o--A--B--C'-D'-E'  <-- somebranch
    \ /    \ /
     o      o

每个提交都有一个勾号(例如C') 意味着提交是通过复制并更改原始内容进行的。

We 也许不会需要改变B根本不。原本的B has A作为其父提交。如果我们不改变B,不过,我们必须复制D to D'。之间的明显区别D and D'就是它D' has C'作为其父级。这意味着我们还必须复制E to E',这很像E但有D'作为其父级。

或者,我们might能够离开D and E完全单独,通过复制B to B' (with E作为其父级)。

无论如何我们一定要复制C to C',就像C但是(1)可能有不同的父母并且(2)有G被压扁了。

实际结果将是这些更复杂的图表之一,这就像我们想要的结果,但更混乱,因此更难查看:

     o      o      B--C
    / \    / \    /    \
o--o   o--o   o--A      F--G    [abandoned]
    \ /    \ /    \    /
     o      o      D--E--B'--C'  <-- somebranch

(仔细比较第一个“可能的期望结果”),或者:

                     C'-D'-E'  <-- somebranch
                    /
     o      o      B--C
    / \    / \    /    \
o--o   o--o   o--A      F--G   [abandoned]
    \ /    \ /    \    /
     o      o      D--E

(仔细比较第二个)。

我们实际上会得到哪一个取决于我们给出的指示git rebase --interactive.

到达那里

您提供的命令,git rebase --interactive 6077ae7,不太正确,因为6077ae7是我们在这里绘制为“commit”的提交C“。你传递给的参数git rebase是一个应该提交的提交exclude,默认情况下,新提交会去after那一点。我们must已提交C(真的6077ae7)在指令表中,这样我们就可以移动提交G之后并使其成为squash。 (第一个操作永远不可能squash.) 我们希望 rebase 排除的提交,以及之后的副本,实际上是提交A(真的7607733).

因此所需的命令是:

git rebase -i 7607733

它告诉 Git 制作一个指令表,其中包含pick每次提交的命令after A,直到当前提交(G),不包括合并提交(F).

我不太清楚是否B--C将首先出现,或之后出现D--E,在说明书中,但这并不重要:所有B, C, D, E, and G将在那里,按某种顺序,与B绝对之前C, D绝对之前E, and G最后的。所以这将是:

pick bc882a2 yada yada yada
pick 6077ae7 Into this one
pick 4aee207 yede yede yede
pick b645616 yide yide yide
pick 80e2fa1 I want to squash this commit

Or:

pick 4aee207 yede yede yede
pick b645616 yide yide yide
pick bc882a2 yada yada yada
pick 6077ae7 Into this one
pick 80e2fa1 I want to squash this commit

无论他们按什么顺序show在,现在你的工作是改编他们这样80e2fa1紧随其后6077ae7。 (在第二种情况下,它已经这样做了,在第一种情况下,您必须将其向上移动,或重新洗牌其他pick行。)然后您可以更改pick for 80e2fa1 to squash,写出说明表,然后退出编辑器,rebase 将开始其复制(和压缩)操作。

附加信息

请注意,rebase 现在将复制所有B, C, D, and E即使我们要复制B and C after E。这似乎可能与我们上面的图纸相矛盾,我们只得到了副本D' and E'如果他们必须这样做的话,为了追赶C'.

这里的技巧实际上是一个关键的 Git 属性:如果某个提交被复制到其自身的逐位相同版本,则新提交具有same ID作为原始提交。即使副本中只有一个东西不同,尽管新提交有一个不同的ID.

提交的数据包括作者和提交者,以及一些时间戳。 “现在”的时间与“几秒钟前”的时间不同,因此看起来副本总是会被更改 - 事实上,它would总是会被改变,但是git rebase代码检查是否可以通过按原样重新使用原始提交来完好无损地保留原始提交。几乎可以肯定没有什么可以阻止它离开原来的D--E链条完好无损if新的结果是A--D--E.

在某种程度上,这并不重要:出于您的目的,您可能不在乎是否得到A-D'-E'-B'-C' vs A-D-E-B'-C'。如果你去A-B-C'-D'-E'你可能不会关心 Git 是否生成了版本A-B'-C'-D'-E'反正。但变基代码确实会尽可能保留原始代码,因为在某些情况下,哈希 ID 确实很重要。

(如果我们迫切需要保护A-D-EID,以及git rebase坚持通过复制到新的时间戳来更改它们,我们可以通过使用来做我们想做的事git cherry-pick在提交之上构建我们新的提交链E。但实际上我们可以得到git rebase使用其特殊情况的“尝试保留 ID”代码。事实上,如果有的话,有时恰恰相反:有时——尽管很少——我们迫切需要avoid保存 ID,这就是git rebase -i has a --no-ffflag:告诉它avoid快进分支指针,即避免保留 ID。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从历史记录中删除合并并重新调整非顺序提交的基础 的相关文章

随机推荐

  • 在 Visual Studio 中哪里可以观察全局数据结构、变量?

    当我调试并到达断点时 我只能在 Visual Studio 2008 的 局部变量 选项卡中看到局部变量 在 Visual Studio 中哪里可以观察全局数据结构 变量 In the Watch窗户 这Local选项卡用于局部变量 顾名思
  • 使用 ImageMagick 或 Ghostscript(或其他)缩放 PDF 以适合页面?

    我需要缩小一些大型 PDF 以在 8 5x11 英寸 标准信函 页面上打印 ImageMagick Ghostscript 可以处理这类事情吗 还是因为我使用了错误的工具来完成这项工作 所以遇到了很多麻烦 仅仅依靠客户端打印对话框中的 缩小
  • SceneKit:无论您触摸屏幕的何处,unprojectPoint都会返回相同/相似的点

    下面的代码应该将触摸坐标转换为 SceneKit 场景的世界坐标 但是 如下面的输出所示 返回的点unprojectPoint无论您触摸屏幕的哪个位置 iPhone 5s 都会有效地返回同一点 类文档为unprojectPoint建议使用
  • 是否可以仅使用 GPU 来加厚二次贝塞尔曲线?

    我在 OpenGL 程序中绘制了大量二次贝塞尔曲线 现在 曲线只有一像素细 并且是由软件生成的 因为我还处于相当早期的阶段 看看什么有效就足够了 Simply enough given 3 control points P0 to P2 I
  • Django:进行原始 SQL 查询,传递多个/重复参数?

    希望这应该是一个相当简单的问题 我只是对 Python 和 Django 了解不够 无法回答它 我在 Django 中有一个原始 SQL 查询 它采用六个不同的参数 其中前两个 centreLat 和 centerLng 均重复 query
  • C# - 我应该如何将 datagridview 组合框添加到数据表并在 datagridview 中预览它?

    抱歉 如果这是一个愚蠢的问题 我对此很陌生 我应该如何将组合框添加到数据表 然后将其加载到数据网格视图中 这可以做到吗 这是最好的方法吗 非常感谢有关如何执行此操作的提示和教程 先感谢您 string columnNames dataTab
  • Google Colab 上 R-Keras 的工作流程 [重复]

    这个问题在这里已经有答案了 我想用 R 进行机器学习 请接受我的选择 并且想知道我是否可以使用 google colab 上的 IRkernel 来安装和运行 keras 从而以任何方式访问 TensorFlow 库 是否有一个有效 可访问
  • 基于索引列合并数据帧[重复]

    这个问题在这里已经有答案了 我可以看到我想做的事情是可以通过concat 合并索引上的数据帧 https stackoverflow com questions 21923880 merge dataframes on index 为什么我
  • Python 循环遍历文件夹并重命名文件

    我试图浏览一堆文件夹并进入每个文件夹并将特定文件重命名为不同的名称 我只是陷入了文件夹循环部分 我的文件系统如下所示 Root Directory Folder File1 File2 File3 Folder File1 File2 Fi
  • 将 pandas 中的通话数据拆分为 15 分钟间隔

    我是 python 和 pandas 的新手 尽管我研究了很多关于间隔的知识 但我找不到任何解决我的问题的方法 我希望有人可以提供帮助 这是我的 DF 示例 df pd DataFrame data Mel Gibson German 20
  • Laravel 混合版本控制不会删除旧的构建文件

    我正在使用 Laravel 5 4 和 mix 来版本化我的 javascript 和 scss 文件 问题是 它不会清除以前构建的文件 而只是添加一个具有不同文件名的新文件 即app 9d3e179e85922aad6ccf js 在我开
  • Go 中的符号 [:] 是什么意思?

    我在一些代码中发现了这一点 h s Hash tx sig err crypto Sign h prv 什么是 意思是 如果这是数组的完整切片 为什么不传递数组本身呢 这是什么编码风格 我想知道 在Go中 数组和切片略有不同 不能互换使用
  • AJAX 分页后的 WordPress 类别

    我真的很难找到一种方法来使用 ajax 为我的 WordPress 帖子创建分页 我找到的解决方案不起作用 要获得更多信息 这里有一个链接 底部有用于分页的项目符号 单击这些按钮后 我希望网站能够加载新帖子而不触发页面刷新 http max
  • 填充 va_list

    有没有办法创建一个va list从头开始 我正在尝试调用一个需要va list作为参数 func void entry int num args va list args char key 来自不接受可变数量参数的函数 我能想到的唯一方法是
  • 信号无法通过 execv() 正确重新启用

    我正在为我正在开发的 Linux 发行版编写一个系统关键程序 它需要在收到某些信号时自行重新启动 以避免崩溃 问题是 重新启动后 我无法重新启用该信号 也就是说 信号不能被接收两次 execv 自身执行后 当新进程调用 signal 来设置
  • 简单不平衡搜索树的平均渐近深度是多少?

    对于平衡搜索树 所有情况都是 O log N 对于不平衡搜索树 最坏情况是 O N 例如插入 1 2 3 4 最好情况复杂度是平衡时 例如插入 6 4 8 3 5 7 我们如何定义不平衡搜索树的平均情况复杂度 二叉树的平均高度为 Theta
  • docker-compose 使用独特的环境变量进行扩展

    我的 docker compose 文件中有一个示例计算服务 它按预期工作得很好 version 3 services compute service image dummy compute environment INPUT 2 然而 有
  • mongodb:我应该在更新时始终使用“安全”选项吗

    在处理 mongodb 时 我什么时候应该在查询中使用 safe true 现在我使用 安全 选项只是为了检查我的查询是否已成功插入或更新 不过 我觉得这可能有点过头了 我是否应该假设 99 的时间 我的查询 假设它们被正确编写 将被插入
  • Photoshop 的 RGB 级别与 ImageMagick

    我正在尝试将 Photoshop 中创建的一些效果转换为与 php imagemagick 一起使用的代码 现在我对如何重新创建 Photoshop 的 RGB 级别功能特别感兴趣 我不太熟悉 Photoshop 界面 但这是我得到的信息
  • 从历史记录中删除合并并重新调整非顺序提交的基础

    我有以下 git 历史记录 我想在其中压缩提交并删除多个合并 git log graph oneline all 80e2fa1 I want to squash this commit 7850013 Merge branch maste