如何轻松修复过去的提交?

2024-01-31

我刚刚读过修改 git 中过去提交的单个文件 https://stackoverflow.com/questions/493450/amending-a-single-file-in-a-past-commit-in-git但不幸的是,接受的解决方案“重新排序”了提交,这不是我想要的。所以这是我的问题:

我时不时地在处理(不相关的)功能时注意到代码中存在错误。一个快速git blame然后显示该错误已在几次提交前引入(我提交了很多次,因此通常不是引入该错误的最新提交)。此时,我通常会这样做:

git stash                      # temporarily put my work aside
git rebase -i <bad_commit>~1   # rebase one step before the bad commit
                               # mark broken commit for editing
vim <affected_sources>         # fix the bug
git add <affected_sources>     # stage fixes
git commit -C <bad_commit>     # commit fixes using same log message as before
git rebase --continue          # base all later changes onto this

然而,这种情况经常发生,以至于上述序列变得令人讨厌。尤其是“交互式变基”很无聊。上述序列是否有任何快捷方式,可以让我通过分阶段更改修改过去的任意提交?我完全意识到这改变了历史,但我经常犯错误,所以我真的很想拥有类似的东西

vim <affected_sources>             # fix bug
git add -p <affected_sources>      # Mark my 'fixup' hungs for staging
git fixup <bad_commit>             # amend the specified commit with staged changes,
                                   # rebase any successors of bad commit on rewritten 
                                   # commit.

也许是一个可以使用管道工具等重写提交的智能脚本?


更新的答案

前段时间,新出了一个--fixup参数被添加到git commit它可以用来构造一个带有适合的日志消息的提交git rebase --interactive --autosquash。因此,修复过去提交的最简单方法是:

$ git add ...                           # Stage a fix
$ git commit --fixup=a0b1c2d3           # Perform the commit to fix broken a0b1c2d3
$ git rebase -i --autosquash a0b1c2d3~1 # Now merge fixup commit into broken commit

原答案

这是我不久前写的一个Python小脚本,它实现了这个git fixup我在最初的问题中希望得到的逻辑。该脚本假设您暂存了一些更改,然后将这些更改应用到给定的提交。

NOTE:此脚本是 Windows 特定的;它寻找git.exe并设置GIT_EDITOR环境变量使用set。根据其他操作系统的需要调整此项。

使用此脚本,我可以精确地实现我要求的“修复损坏的源代码、阶段修复、运行 git fixup”工作流程:

#!/usr/bin/env python
from subprocess import call
import sys

# Taken from http://stackoverflow.com/questions/377017/test-if-executable-exists-in python
def which(program):
    import os
    def is_exe(fpath):
        return os.path.exists(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file

    return None

if len(sys.argv) != 2:
    print "Usage: git fixup <commit>"
    sys.exit(1)

git = which("git.exe")
if not git:
    print "git-fixup: failed to locate git executable"
    sys.exit(2)

broken_commit = sys.argv[1]
if call([git, "rev-parse", "--verify", "--quiet", broken_commit]) != 0:
    print "git-fixup: %s is not a valid commit" % broken_commit
    sys.exit(3)

if call([git, "diff", "--staged", "--quiet"]) == 0:
    print "git-fixup: cannot fixup past commit; no fix staged."
    sys.exit(4)

if call([git, "diff", "--quiet"]) != 0:
    print "git-fixup: cannot fixup past commit; working directory must be clean."
    sys.exit(5)

call([git, "commit", "--fixup=" + broken_commit])
call(["set", "GIT_EDITOR=true", "&&", git, "rebase", "-i", "--autosquash", broken_commit + "~1"], shell=True)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何轻松修复过去的提交? 的相关文章

随机推荐

  • 每 x 秒调用一次函数(Python)[重复]

    这个问题在这里已经有答案了 我想每 10 秒调用一个函数 实际上 它是一个 Web API 但该函数可能需要随机 t 秒才能返回 假设 t 为 0 1 至 1 0 秒 我们能想到的最简单的代码是 while True func take t
  • Docker BuildKit --mount=type=cache 不起作用,为什么?

    我正在尝试实施Buildkit 的缓存挂载功能 https github com moby buildkit blob master frontend dockerfile docs experimental md run mounttyp
  • 多个源代码存储库

    我使用 Mercurial 对源代码进行版本控制 但有些人更喜欢其他版本控制系统 如 git Bazaar SVN CVS 我想知道 是否可以同时将一个存储库存储在多个系统下 以便人们可以使用他们想要的任何存储库 GitHub 开发了hg
  • Nginx 无法加载 CSS 和 JS 文件(MIME 类型错误)?

    我的网站上出现以下错误 Error There are multiple templates named velvet Each template needs a unique name 1b1a247fc034d5089f331ec954
  • 如何在 Angularjs 中使用 $event 更新事件点击时的 ng-model

    http plnkr co ywhmyO http plnkr co ywhmyO 我尝试过编译和指令 但一无所获 示例中的编译代码是直接从 Angular 网站上撕下来的 但我不知道如何使用它 非常感谢任何指导 你被这样的事实绊倒了ng
  • 如何在类图中显示单例关系

    如果一个类包含指向单例类的指针 它可以是aggregation 据我了解 这不可能是has a关系 因为该类不会创建单例类的实例 它只是像这样使用它association关系 标题并不像所写的那样100 完全有意义 有单例类 但没有真正的单
  • 以编程方式设置 GoogleMapOptions

    我像这样膨胀我的片段 GoogleMap map MapFragment getFragmentManager findFragmentById R id MapFragment map Fragment getMap 在这里我有我的选择
  • Lambda 日志和 CloudWatch PutLogEvents 限制

    I know Lambda 调用PutLogEvents在内部记录消息 CloudWatch 有限制PutLogEvents PutLogEvents 每个日志流每秒 5 个请求 我想知道 Lambda 日志流也可以被限制吗PutLogEv
  • Javascript 将 unicode 字符串转换为“标题大小写”

    我有一个 javascript 大小写转换问题 由于非英文字母 我无法解决该问题 我主要关心的是土耳其字母 我需要做的是这样的 你好世界 gt 你好世界 你好世界 gt 你好世界 你好世界 gt 你好世界 这是我到目前为止所取得的成就 St
  • Rails + Rspec + 机架 + 会话测试

    Gemfile 文件 机架 gt 1 6 0 我在将会话变量从 rspec 测试传递到 Rack 中间件时遇到了一些问题 我在互联网上浏览了很多文章 但没有任何解决方案可以帮助我理解 所以基本上我希望能够在我的中间件类中做到这一点 req
  • Grizzly / Glassfish - 无法建立 websockets 握手

    我正在尝试让 WebSockets 在 Grizzly Glassfish 之上工作 我已经克隆了示例 WebSockets 聊天应用程序 http java net projects grizzly sources git show sa
  • realloc() 旧大小无效

    我正在做 K R C 编程书中的一个练习 该程序用于从用户输入的一组行中找到最长的行 然后打印它 这是我写的 部分内容直接摘自书中 include
  • 将值插值作为属性组件

    我有一个关于 Angular2 中的插值是如何完成的问题 例如 我有组件 X 其值为 Input 在父组件中我有这样的代码
  • 如何在保持纵横比的同时将 div 包含在视口内

    存在一个正方形 div 其宽度为任意百分比 并且高度相同 需要随窗口缩放 它必须保持在视口的范围内 即 不剪裁到外部 并保持其正方形形状 本质上是复制background size contain CSS 的特性 我需要支持iOS Safa
  • 什么是 Java EE? [复制]

    这个问题在这里已经有答案了 我意识到它的字面意思是 Java 企业版 但我要问的是 这到底意味着什么 当公司需要 Java EE 经验时 他们真正需要的是什么 有使用 EJB 的经验吗 有 Java Web 应用程序经验吗 我怀疑这对不同的
  • 无法解码 JSON 对象:期望值:第 1 行第 1 列(字符 0)

    这个问题有点重复 但我找不到解决方案 当我调用 Flask 应用程序并传递 JSON 数据时 出现错误 Failed to decode JSON object Expecting value line 1 column 1 char 0
  • 以特定方式将 String 转换为 NSAttributedString

    所以我有一个看起来像这样的字符串 Swift VisualBasic Ruby i wanna convert this string to something like this 基本上我想在单个单词后面创建一个背景 是的 我可以使用 N
  • Angular 2 库配置

    目前我正在尝试创建我的第一个 Angular 2 库 即翻译管道 现在我正在尝试让开发人员能够将带有翻译的对象插入到模块中 以便管道可以使用它 如何将某种配置 对象插入到我的库中 以便我的所有组件 管道和服务都可以使用它 我的图书馆看起来像
  • 如何设置文件上传的样式?

    在 Firefox 中 它看起来像一个您单击的文本字段 我只需要一个像 Safari 渲染这样的按钮 有没有办法不显示在 Firefox 中查找文件上传的文本字段 之前问过很多次 如何在 Firefox 中设置文件输入字段的样式 https
  • 如何轻松修复过去的提交?

    我刚刚读过修改 git 中过去提交的单个文件 https stackoverflow com questions 493450 amending a single file in a past commit in git但不幸的是 接受的解