如何进行 git rebase 并保留提交时间戳?

2024-04-08

我想进行变基以从我的历史记录中删除某个提交。我知道该怎么做。但是,如果我这样做,提交时间戳将设置为我完成变基的那一刻。我希望提交保留时间戳。

我在这里看到了最后一个答案:https://stackoverflow.com/a/19522951/3995351 https://stackoverflow.com/a/19522951/3995351,但是没有用。

最后一个重要命令刚刚显示了一个新行

>

所以我提出一个新问题。


设置

假设这是您要删除的提交的历史记录

... o - o - o - o ...       ... o
        ^   ^   ^               ^
        |   |   +- next         |
        |   +- bad              +-- master (HEAD)
      start

where:

  • bad是您要删除的提交;
  • start是您要删除的提交的父级;
  • next是之后的下一次提交bad;这很好,你想保留它以及它之后的所有时间线;它将取代bad变基后。

先决条件

为了能够安全地移除bad,重要的是当时没有其他分支存在bad创建后合并到主时间线中bad。 IE。通过删除bad及其与历史图中父级和子级提交的连接,您将获得两个断开连接的时间线片段。

或许可以去除bad即使之后合并了另一个现有分支bad。我没有检查这种情况,但我预计由于合并提交会出现一些障碍。

The idea

Each git提交由使用提交属性计算得出的哈希值来标识:内容、消息、作者和提交者日期以及电子邮件。

变基总是会更改提交者日期。它还可以更改提交者电子邮件、提交消息和内容。

为了在变基后恢复原始提交者日期,我们需要将它们与一些可以识别变基后每次提交的信息一起保存。

因为要修改提交,所以提交内容在变基期间会发生变化。添加或删除文件或提交会更改所有未来提交的内容。

这使得我们没有一个唯一标识提交并且在所需的变基期间不会更改的属性。我们可以尝试使用两个或多个在变基期间不会改变的属性。

电子邮件(作者和提交者)几乎没有用。如果只有一个人参与该项目,则他们对于所有提交都是相同的,并且不能使用。保留的属性(在大多数提交上都不同,不受变基影响)是作者日期 and 提交消息(第一行)。

如果这对(作者日期,提交消息)为受变基影响的所有提交提供唯一值,那么我们可以在之后恢复提交日期而不会出现错误。

验证是否可以安全完成

有一种简单的方法可以验证(作者日期,提交消息)对对于受影响的提交是否是唯一的。

运行以下两个命令:

$ git log --format="%aI %s" start...master | uniq | wc -l
$ git log --oneline start...master | wc -l

如果它们显示相同的数字,那么您很幸运:这对(作者日期,提交消息)可用于唯一标识提交。请继续阅读。

如果数字不同(第一个命令生成的数字始终小于或等于第二个命令生成的数字),那么您就不走运了。

提取修复变基后提交日期所需的信息

这个命令

$ git log --format="%H %cI %aI %s" start...master > /tmp/hashlist

提取以以下开头的所有提交的提交哈希、提交者日期(有效负载)、作者日期和提交消息(密钥)start并将它们存储在文件中。

备份当前master

虽然这是一个常见的误解git“重写历史”,实际上它只是生成一条替代历史线并确定它是正确的历史。它不会更改或删除“重写”的提交;它们仍会在数据库中存在一段时间,并且可以在操作失败时恢复。

我们可以主动备份当前历史行,以便在需要时轻松恢复。我们所要做的就是创建一个指向的新分支master。这样,当git rebase moves master对于新的时间线,旧的时间线仍然可以使用新的分支访问。

$ git branch old_master

上面的命令创建一个名为old_master这使得当前的时间线成为焦点,直到我们完成所有的改变并对新的世界秩序感到满意。

进行变基

删除提交bad从历史来看,很简单:

$ git rebase --preserve-merges --onto start bad

修复提交日期

以下命令“重写”历史记录并使用我们之前保存的值更改提交者日期:

$ git filter-branch --env-filter 'export GIT_COMMITTER_DATE=$(fgrep -m 1 "$(git log -1 --format="%aI %s" $GIT_COMMIT)" /tmp/hashlist | cut -d" " -f2)' -f start...master

怎么运行的:

git遍历标记的提交之间的历史记录start and master对于每个提交,它都会运行作为参数提供的命令--env-filter在重写提交之前。它设置环境变量GIT_COMMIT提交的哈希被重写。

既然我们已经做了rebase修改了我们无法使用的所有提交的哈希值$GIT_COMMIT直接识别提交的原始提交日期(因为$GIT_COMMIT是由以下生成的提交git rebase并且我们对他们的提交者日期不感兴趣)。

我们提供给的命令--env-filter

export GIT_COMMITTER_DATE=$(fgrep -m 1 "$(git log -1 --format="%aI %s" $GIT_COMMIT)" /tmp/hashlist | cut -d" " -f2)

runs git log -1 --format="%aI %s" $GIT_COMMIT生成上面讨论的密钥对(作者日期、提交消息)。其输出作为参数传递给命令fgrep -m 1 "..." /tmp/hashlist | cut -d" " -f2在先前保存的哈希值列表中找到该对(fgrep)并从保存的行中提取原始提交日期(cut)。最后,将提交日期的值存储在环境变量中GIT_COMMITTER_DATE被使用的是git重写提交。

确认

使用git log再次命令

$ git log --format="%cI %aI %s" start...master

您可以验证重写的历史记录是否与原始历史记录匹配。如果您使用图形git客户可以通过目视检查更轻松地检查结果。分支old_master使旧的历史记录行在客户端中可见,您可以轻松比较每次提交的日期old_master与相应的分支之一master branch.

如果事情进展不顺利或者您需要修改程序,您可以通过以下方式轻松重新开始:

$ git reset --hard old_master

Cleanup

当您对结果感到满意时,您可以删除备份分支和用于存储原始提交日期的文件:

$ git branch -D old_master
$ rm /tmp/hashlist

就这样!

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

如何进行 git rebase 并保留提交时间戳? 的相关文章

  • 克隆存储库时出现 Git 冲突复制错误

    我使用 dropbox 作为 git 存储库 现在由于同步中的一些问题 git 中存在一些冲突的副本 我该如何消除这种冲突 由于这种冲突 我无法克隆该存储库的内容 我在克隆存储库时遇到的错误是 Git 致命 参考格式无效 refs head
  • 使用子模块克隆存储库:覆盖凭据

    我必须automate克隆存储库并获取它的所有子模块 存储库子模块的 url 指定于 gitmodules 如果我要使用默认值 我就会这样做 git clone recursive https username email protecte
  • Git 中的提交是越多越好还是越少越好? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我最近与一位同事进行了一场辩论 他坚持认为 由于合并冲突 提交越少越好 我认为通过使用尽可能多的提交获得的细节越多越好 提交更多还是更少更好 为
  • 如何从“git log”中查看 Git 中的特定版本?

    My git log显示为 enter code here git trial git log commit 4c5bc66ae50780cf8dcaf032da98422aea6e2cf7 Author king lt email pro
  • Visual Studio 2013删除已删除的git分支

    我遇到这个问题 在 VS2013 中 当我从源创建一个新分支时 源分支的下拉列表列出了曾经创建的所有分支 这包括长期从本地存储库和远程 源存储库中删除的分支 如何删除已删除的分支 Visual Studio 将它们保存在本地缓存中 您可以从
  • 忽略提交之间 git-diff 的*所有*空白更改

    我正在检查代码库并修复空白奇怪之处并通常纠正缩进等事情 并且我想确保我没有无意中进行任何其他更改 所以我正在做git diff w显示所有已更改文件中的差异 同时忽略空白差异 问题是这实际上并没有忽略all空白差异 至少是什么I认为仅仅是空
  • 从 git 签出后 nuget dll 丢失

    I have a C solution containing different projects On those projects I have some normal nuget packages like Newtonsoft Js
  • 将更改恢复到特定提交

    我为自己创建了一个新分支 现在我需要一次将多个提交从主分支恢复到特定提交 我知道有一个安全的命令可以使用git revert no commit COMMIT TO REVERT FROM COMMIT TO REVERT TO 这给了我e
  • 如何为新的 eclipse (neon) java 项目初始化 git

    我安装了 eclipse Neon 的新副本 并在一个新的闪亮工作区中创建了一个新的 gradle java 项目 将 git 添加到聚会中的最佳实践是什么 我读到在项目目录中初始化 git 是真是个坏主意 https stackoverf
  • 合并git中2个不同分支中具有相同名称的2个文件

    我目前有一个名为test1在一个名为branch1创建自master另一个文件也命名为test1在一个名为branch2也创建自master 如果我合并 master 中的两个分支 这两个文件中编写的代码会发生什么 As 阿米尔回答了 ht
  • 如何创建毫秒粒度的 Python 时间戳?

    我需要一个自纪元以来的毫秒 ms 时间戳 这应该不难 我确信我只是缺少一些方法datetime或类似的东西 实际上微秒 s 粒度也很好 我只需要亚 1 10 秒的计时 例子 我有一个每 750 毫秒发生一次的事件 假设它检查灯是否打开或关闭
  • 克隆包含所有子模块的 git 存储库

    我有一个工作 git 存储库 其中包含几个子模块 通过克隆不同的存储库获得 现在 我想要复制整个存储库 包含所有子模块 通过使用推送或克隆到另一台机器上的裸 git 存储库 我很高兴失去子模块的历史记录 我只是对保留它们的内容感兴趣 这可能
  • Git 子模块在 Windows 上更新缓慢

    Git 子模块在 Windows 上似乎非常慢 为了测试性能 我创建了 3 个裸存储库并向它们提交了 3 条独立消息 未存储文件 然后 我将每个裸存储库作为子模块添加到新的 git 存储库中 并执行子模块更新 花费了 5 秒多的时间 当使用
  • Hudson 结帐卡在“git fetch”处

    我正在使用 git 版本 1 6 2 2 1669 g7eaf8 在 Hudson 1 314 上使用 Hudson Git 插件 0 7 3 当我触发构建时 Hudson 执行 git fetch 但它永远不会返回 我把一只卡在那里14天
  • 如何在 Android Studio 中比较两个 Git 分支?

    我不确定是否可以将主分支 或任何其他分支 与当前功能分支进行比较 例如GIT does 我想要两个分支 主分支和功能分支 之间的差异 以便我可以在合并之前比较差异 我发现 Git UI 对用户不太友好 就像在 AS 中一样 我可以遍历代码并
  • Git 拉回 master 中的提交?

    一位同事 我们称之为亚伦 被指派翻新网站的一部分作为长期项目 他创建了一个新的 Git 分支 名为aaron 他所有的改变都是在这个分支上进行的 当他工作时 我继续维护整个网站 将我的更改提交给master 最终 Aaron 将他的分支合并
  • 命令来确定当前 HEAD 的上游引用?

    我正在寻找我所希望的简单的一行命令确定当前签出分支的正确上游引用 本质上就像是 git branch remote HEAD 如果有效 会将符号模式 HEAD 转换为当前分支名称 然后选项 remote然后将其更改为远程跟踪分支的引用 但它
  • 如何像对待普通目录一样对待嵌套存储库(子模块)?

    我的 WordPress 网站是使用 Git 进行版本控制的 包括wp content plugins 文件夹 现在有一个插件 wp editormd 带有自己的 Git 存储库 wp content plugins wp editormd
  • 使用 Git 的 Spring Cloud 配置服务器 - 无法克隆或签出存储库连接超时

    我正在使用 GIT 在 Spring Cloud Config Server 上进行 POC Spring Boot 1 5 3 RELEASE 爪哇1 8 弹簧工具套件https github com kishornpatil https
  • 从 git 中删除历史记录 - git 命令失败

    我正在尝试从 Git 历史记录中清除项目 bin 目录 我已经将 bin 添加到 gitignore 并运行 git rm cached r bin成功地 现在我尝试使用 GitHub 帮助页面中推荐的命令来清除历史记录 git filte

随机推荐

  • C++ boost::graph 从有向图中获取父顶点

    我有一个有向图 通过 boost graph 库中的 adjacency graph 实现 我试图找到某个顶点的父顶点 过去 通过 pygraph 我只是简单地反转了有向图 然后进行了邻居搜索 但似乎使用 boost reverse gra
  • Pandas 忽略 NaN 删除重复项

    在 Pandas df 中 我尝试删除多个列中的重复项 每行有很多数据NaN 这只是一个例子 数据是一个混合包 因此存在许多不同的组合 df drop duplicates IDnum name formNumber 1 NaN AP GR
  • 使用 URL 启动应用程序

    我读过有关 android 中的意图的内容 但这是我的问题 我想通过点击网络浏览器中的链接来启动我的 Android 手机上的应用程序 例子 如果链接是 mycam http camcorder com http camcorder com
  • 如何在JQuery中选择除单击元素之外的所有类?

    我有一个在 Drupal 上开发的网站 我使用一个名为 collapsiblock 的模块 它基本上是一个 JQuery 插件 来实现类似手风琴的效果 它对我来说工作得很好 尽管它还处于测试阶段 但我想修改它 以便当用户单击手风琴的一项时
  • 点击列表视图项目上的手势

    我试图在点击列表视图中的项目后打开另一个视图 我尝试过添加一个TapGestureRegonizer甚至添加ViewCell与网格等 这些似乎都不起作用 我在标签中添加了点击手势 这似乎有效 但对于列表视图项目却不起作用 对于列表视图之类的
  • Rails:按两列之和排序

    所以 我有一个Photo模型可以在以下网址下载full size and presentation size 当用户下载照片时 我会在照片的full downloads and presentation downloads属性 这一切都很好
  • Android:如何从资源文件创建文件对象?

    我的资产文件夹中有一个文本文件 我需要将其转换为文件对象 而不是输入流 当我尝试这个时 我得到 没有这样的文件 异常 String path file android asset datafile txt URL url new URL p
  • Application Insights 遥测筛选不起作用

    我已经按照指南操作了here https learn microsoft com en us azure application insights app insights api filtering sampling filtering
  • Signtool 无法使用时间戳对 SHA2 和 SHA1 进行双重签名

    我们需要使用signtool exe使用SHA1和SHA2对我们的二进制文件进行双重签名 我们的证书支持256位SHA2 使用Windows 8 SDK的signtool e g Signtool exe 签名 as fd sha256 t
  • 如何在 R 中对交集/组索引的结果重新编号?

    我在 R 中对交集 组索引的重新编号结果苦苦挣扎了几天 示例数据框如下所示 t lt data frame mid c 102 102 102 102 102 102 102 103 103 103 103 103 103 103 aid
  • __init__() 内部和外部变量之间的差异(类和实例属性)

    除了名称之外 这些类之间还有什么区别吗 class WithClass def init self self value Bob def my func self print self value class WithoutClass va
  • Delphi 属性真实世界示例在哪里?

    我知道通过TMS奥勒留 http www tmssoftware com site aurelius asp例如 我们可以使用 新 2010 属性功能在运行时将数据库表字段序列化为对象属性 而我不是这种深层面向对象模式的专家 因此我研究了
  • 只要有待处理的取消屏蔽任务留下但不再存在,我如何运行 asyncio 循环?

    我正在尝试向现有的 asyncio 循环添加一些代码 以提供 Ctrl C 上的干净关闭 下面是它正在做的事情的抽象 import asyncio signal async def task1 print Starting simulate
  • 如何获得没有周末的 DateTime.DaysInMonth ?

    如何在 C 中获取一个月中没有星期五和星期六的天数 强制 LINQ 解决方案 int days Enumerable Range 1 DateTime DaysInMonth year month Select day gt new Dat
  • 如何不在uinavigationcontroller中调用viewdidload?

    我正在寻找针对我的情况的解决方案 我的应用程序如下 VC1 上有一个文本字段和按钮 用户键入名称 然后单击一个按钮 该按钮打开VC2 用户在 VC2 中提供附加信息 然后按 保存 我使用 segue 返回 VC1 并将这些附加信息作为字符串
  • 如何将 Istanbul Code Coverage 与转译的 Typescript 结合使用?

    我整个早上都在阅读有关此问题的文章 试图正确设置我的环境 但由于某种原因我不明白 我的设置 app source mixed js and ts scripts copied source js typescripts js transpi
  • 为什么我的 Azure Function 功能密钥不断重新生成?

    我有六种不同的 Azure 函数 每天会被调用数百次 不过 其中一个与其他任何一个实际上没有什么不同 开发了一项新的 功能 每隔几天 它就会更改功能键 该功能密钥用于对功能进行身份验证 因此每当它发生变化时就会中断我们的流程 原始密钥 以及
  • 如何使用 C# 从 FTP 服务器获取一系列文件

    我陷入了这样一个境地 我将通配符参数与 FtpWebRequest 对象一起使用 很糟糕 FtpWebRequest reqFTP FtpWebRequest FtpWebRequest Create new Uri ftp ftpServ
  • 方程解析库 C++ [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何进行 git rebase 并保留提交时间戳?

    我想进行变基以从我的历史记录中删除某个提交 我知道该怎么做 但是 如果我这样做 提交时间戳将设置为我完成变基的那一刻 我希望提交保留时间戳 我在这里看到了最后一个答案 https stackoverflow com a 19522951 3