【问题标题】:Why does git revert complain about a missing -m option?为什么 git revert 抱怨缺少 -m 选项?
【发布时间】:2011-08-23 16:12:22
【问题描述】:

所以我正在和其他人一起做一个项目,并且有多个 github 分叉正在开发中。有人刚刚解决了一个问题,我与他的 fork 合并,但后来我意识到我可以找到更好的解决方案。我想恢复我刚刚所做的提交。我尝试使用git revert HEAD 执行此操作,但它给了我这个错误:

致命:提交  是一个合并,但没有给出 -m 选项。

这是什么意思?当我合并并提交时,我确实使用了 -m 选项来表示“与 合并”。

我在这里做错了什么?

【问题讨论】:

    标签: git github git-revert


    【解决方案1】:

    默认情况下git revert 拒绝还原合并提交,因为这实际上意味着不明确。我认为您的 HEAD 实际上是一个合并提交。

    如果你想恢复合并提交,你必须指定你想考虑的合并的哪个父主干,即你想恢复到什么。

    通常这将是第一个父级,例如,如果您在 master 并做了 git merge unwanted,然后决定恢复 unwanted 的合并。第一个父级将是您合并前的master 分支,第二个父级将是unwanted 的尖端。

    在这种情况下,你可以这样做:

    git revert -m 1 HEAD
    

    git cat-file -p [MERGE_COMMIT_ID] 将按顺序显示父分支。列出的第一个是 -m 1,第二个是 -m 2。

    【讨论】:

    • 好的,谢谢。我发现只更改受合并影响的两个文件然后提交我的其他一些更改更容易。
    • 我在哪里可以找到我必须使用 -m1 还是 -m2, ...的信息?
    • git cat-file -p [MERGE_COMMIT_ID] 将按顺序显示父分支。列出的第一个是-m 1,第二个是-m 2
    • git revert [HASH] -m 2 告诉我在分支 1.x-1.x 上没有可提交的内容,工作目录干净,但我的提交没有恢复。
    • 所以如果我需要恢复过去的 10 次合并(这很可能是因为每次我从另一个开发人员那里拉取更改时 git 都会自动执行合并)我必须为每次合并执行此操作?这就是为什么 git 粉丝如此热衷于 rebase,因为 revert 基本上没用?
    【解决方案2】:

    假设另一个人在 foo 之上创建了 bar,但你同时创建了 baz 然后合并,给出了一个历史

    $ git lola
    * 2582152 (HEAD, master) 合并分支 'otherguy'
    |\
    | * c7256de (otherguy) 酒吧
    * | b7e7176 巴兹
    |/
    * 9968f79 富

    注意:git lola 是一个非标准但有用的别名。

    git revert 没有骰子:

    $ git revert HEAD
    致命:提交 2582152... 是一个合并,但没有给出 -m 选项。

    Charles Bailey 像往常一样给了excellent answer。使用git revert,如

    $ git revert --no-edit -m 1 HEAD
    [master e900aad] 恢复“合并分支 'otherguy'”
     0 个文件更改,0 个插入 (+),0 个删除 (-)
     删除模式100644栏

    有效地删除了bar 并产生了历史

    $ git lola
    * e900aad (HEAD, master) 恢复“合并分支 'otherguy'”
    * 2582152 合并分支'otherguy'
    |\
    | * c7256de (otherguy) 酒吧
    * | b7e7176 巴兹
    |/
    * 9968f79 富

    但我怀疑你想扔掉合并提交:

    $ git reset --hard HEAD^
    HEAD 现在位于 b7e7176 baz
    
    $ 混帐萝拉
    * b7e7176(头,主)baz
    | * c7256de (otherguy) 酒吧
    |/
    * 9968f79 富

    git rev-parse manual 中所述

    <rev>^,例如头^,v1.5.1^0
    修订参数的后缀^ 表示该提交对象的第一个父级。 ^<n> 表示第 n 个父级( <rev>^ 等同于<rev>^1)。作为一个特殊规则,<rev>^0 表示提交本身,并且在 <rev> 是引用提交对象的标记对象的对象名称时使用。

    所以在调用 git reset 之前,HEAD^(或 HEAD^1)是 b7e7176,HEAD^2 是 c7256de,ie,分别是合并提交的第一和第二父级。 p>

    小心git reset --hard,因为它会破坏工作。

    【讨论】:

    • 这是一个混乱、混乱、震撼的世界。除了萝拉。非常感谢这个奇妙的别名。
    • lola 添加到您的git 命令的简单方法:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
    【解决方案3】:

    我遇到了这个问题,解决方案是查看提交图(使用 gitk)并看到我有以下内容:

    *   commit I want to cherry-pick (x)
    |\  
    | * branch I want to cherry-pick to (y)
    * | 
    |/  
    * common parent (x)
    

    我现在明白我想做的事

    git cherry-pick -m 2 mycommitsha
    

    这是因为-m 1 将基于公共父级合并,而-m 2 基于分支 y 合并,这是我想要挑选的那个。

    【讨论】:

    • 可能是因为它与git-revert 无关,这就是这个问题的意义所在。
    • 我认为这个问题是关于-m 选项,而不仅仅是关于git merge。即,使用-m 选项背后的原因似乎与reverts 和cherry-picks 相似。如果这不是真的,请告诉我们。由于我还没有找到任何其他专门解决樱桃挑选使用它的问题,感谢您的回答,这可能导致谷歌帮助我找到了这个问题和有用的相关讨论!
    • 如果我理解正确,git 没有记录哪个分支(y)是在哪个分支上创建的;据它所知,您的图片是对称的:左侧分支上的未命名提交在任何方面都不会比右侧(y)上的提交更好或更差。如果正确,它如何决定哪个是 1,哪个是 2?
    【解决方案4】:

    在最初的问题中,git 错误的“-m 选项”可能被误认为是提交消息。如其他答案中所述,使用“-m n”指定合并的第 n 个父级以选择您认为是主干的父级。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多