【问题标题】:How to checkout an old commit and make it a new commit如何签出旧提交并使其成为新提交
【发布时间】:2013-07-03 13:50:00
【问题描述】:

我想“跟进”关于此事的另一个问题: Checkout old commit and make it a new commit

但他们说“不要那样做!”所以看来我必须问一个新问题。 (尽管我认为最适合我的答案没有按预期工作......

如果我有提交 A-B-C-D-E-F(想象一下这些都是 SHA)。 我想让整个存储库与C 完全相同,然后提交它以创建'G',它与C 完全相同。这样当我完成时,即使 C 和 G 相同,日志也是 A-B-C-D-E-F-G。

一个答案表明是cherry-pick,这看起来很完美,除了它让我解决了CF 之间的所有冲突。我查看了文档并尝试了--force,然后推荐了--patch--patch 是最接近的,但不是绝对的。那么有没有办法让cherry-pick只选择C版本的冲突呢?

另一个最接近的答案是结帐C,但我找不到将它保持在同一个分支上的神奇词。我最近完成的培训说在最后使用“魔术破折号”告诉git您希望在当前分支上使用它,但无论我做什么,它都会创建一个“(无分支)”分支。

我相信你会说,我对 git(和一般的命令行)很陌生,但我试图自己弄清楚。如果您可以使用您推荐的详细版本,那么它会更好地留在我的脑海中,将不胜感激。 (-a = --all-a = --annotate-a = --albuquerque?

它看起来很简单,正是你可能想要用 git 做的——返回之前的提交,而不会丢失中间提交,以防你改变主意。

【问题讨论】:

  • 您所说的“D、E 和 F 在哪里”是什么意思?
  • “就在那里”意味着我完成后的完整日志是 A-B-C-D-E-F-G,即使 C 和 G 相同

标签: git


【解决方案1】:

您介意生成:A-B-C-D-E-F-F'-E'-D',其中D' 的代码状态与C 完全相同(所以G == D')?在这种情况下,只需还原 FED。如果你不想要中间步骤,revert 但不要申请,然后提交。那就是:

$ git revert -n HEAD
$ git revert -n HEAD~
$ git revert -n HEAD~2
$ git commit -m 'Revert D,E,and F'

在这之后,当前的 HEAD 是 G,两个提交 G 和 C 应该包含相同的代码树。您可以通过检查git cat-file -p HEAD | grep ^treegit cat-file -p C | grep ^tree 的输出来验证。这两个命令应该给出相同的输出。

但不清楚为什么要保留中间提交。如果您希望它们为子孙后代使用,请执行以下操作:git branch old-stuffgit reset C 这会将您当前的分支设置回C,但DEF 仍然可以在分支名为old-stuff

【讨论】:

  • 再次,也许答案是“不,没有一个简单的一步命令可以将整个存储库放回之前的提交状态作为一个新的提交” .我知道我可以通过分支或连续还原来做到这一点,但这些对于我的用例来说太过分了。谢谢!
【解决方案2】:

【讨论】:

  • 是的。我会喜欢使用cherry-pick。目标是找到我可以添加到git cherry-pick C 的参数序列,这样它就不会要求我解决一路上的所有冲突。谢谢!
【解决方案3】:
git cherry-pick --strategy=recursive -X ours C

git-merge(1):

递归策略可以采用以下选项:

我们的

此选项强制通过支持我们的版本来干净地自动解决冲突的帅哥。 [...]

“我们的”和“他们的”是指被合并的两个提交。但是,我不确定 git cherry-pick 处理提交的方式,因此您可能需要 -X theirs 代替。你可以新建一个分支,试试看。

【讨论】:

    【解决方案4】:

    如果你想最终得到: -G-D-E-F (不确定,我对“D、E 和 F 就在那里”感到困惑。) 那么到达那里的最佳方式是rebase -i,然后将A-B-C 挤在一起。

    【讨论】:

    • 抱歉,那句话不准确。我最终想要的是 A-B-C-D-E-F-G 的完整提交历史,即使 C 和 G 恰好是相同的。我很高兴找到一个很好的 rebase 用例,我听说它有多棒,但从你写的内容来看,我认为它不适合这里。谢谢!
    • 我有点搞不懂你为什么要这么做?这不是你想要推动的东西,因为它是 D-E-F 的变相还原。您实际上可以使用 git revert D E F 去那里。但是为什么呢?如果您想保留 D E F 以供参考,则将它们推送到单独的分支,然后硬重置为 C 似乎是一个更好的解决方案。
    【解决方案5】:

    您能否将您想要的描述为:“使您的工作树与 C 相同,然后提交”?如果是这样,这是一种方法:

    git checkout C     # working tree same as C. But also moves HEAD to C...
    git reset F        # ...so move HEAD back to F, leaving working tree alone
    git commit -a      # commit working tree
    

    编辑这可能会产生一堆合并冲突,因此它不能解决您问题的那一部分。

    EDIT3同样,selected answer 解决了这个问题:首先删除所有内容,没有冲突。


    顺便说一句:在不更改 HEAD 的情况下使工作树等于提交 C 会很好,但我认为没有(瓷器)可以做到这一点。如果您想要整个提交,git checkoutgit reset 都会更改当前分支。 git checkout 可以在不移动当前分支的情况下将单个文件提取到工作树中,但是您必须单独提取每个文件,而不是整个提交...

    EDIT2 哦,我从selected answer 看到您之前的问题,您可以 这样做。我试过git checkout C -- "*",但你需要git checkout C -- . 所以它只是:

    git checkout C -- .    # working tree same as C, without moving branch (NB ".")
    git commit -a
    

    【讨论】:

      【解决方案6】:

      从您对我的其他答案的评论来看(我没有删除,因为该解决方案比这更正确,但这似乎是您想要的),您可以使用管道命令commit-tree,如下所示:

      git reset $( git commit-tree $tree -p F -m 'Revert D,E, and F' )
      

      其中 $tree 是提交 C 底层树对象的哈希值。(git cat-file -p C | grep ^tree 的输出)。这将创建一个新提交,其中底层树与提交 C 相同,但新提交的父级是提交 F。它还将当前分支设置为指向该新提交,使其成为新的 HEAD。

      【讨论】:

        【解决方案7】:

        看起来您希望 C 成为您的 git 存储库的最终状态。

        以“A-B-C-D-E-F-G”为例,

        您可以按使用顺序还原 G、F、E、D

        git revert [commitID]

        然后使用 git commit

        G、F、E、D全部还原后,您的仓库将保持与C相同的状态。

        仅本地分支的另一种方法是:

        git resert --hard HEAD~4

        这将重置您的本地分支以提交 C 并删除 D、E、F、G。

        【讨论】:

          【解决方案8】:

          实际上,在我找到您的之前,我已经提交了my own question,但无论如何 - 您可以使用树哈希来做到这一点。

          这个想法是每个提交都有一个与之关联的“树对象”,它描述了整个工作树,所以你需要做的就是创建一个与旧提交具有相同树对象的新提交,然后添加它到 HEAD。

          这是一个执行此操作的脚本:

          #/bin/bash
          COMMITID=$1
          git reset --hard $(git commit-tree -m "Revert to commit $COMMITID" -p $(git rev-parse HEAD) $(git rev-parse $COMMITID^{tree}))
          

          【讨论】:

            猜你喜欢
            • 2011-03-23
            • 2020-12-18
            • 2018-10-31
            • 2015-07-14
            • 2016-07-30
            • 1970-01-01
            • 2011-06-25
            • 2014-08-01
            • 2013-09-29
            相关资源
            最近更新 更多