【问题标题】:Bring Git branch to state of commit in other branch将 Git 分支带入其他分支的提交状态
【发布时间】:2021-10-08 16:47:34
【问题描述】:

假设我有 2 个分支 A(旧的)和 B(新的),最近分开了。在 A2 中我犯了一些错误(破坏了一些我想保留的文件的历史记录),我用 B2 修复了这些错误。

我想将分支 B 的工作目录带到提交 A3 的状态,但不要合并/提交它。相反,我宁愿只进行(暂存/未暂存)本地更改,以便在下一次提交后,B3 将与 A3 相同(但不以任何方式链接到 A2 或 A3):

A1 - [A2 - A3 - A4]  (A will be deleted after the fix)
   \
     B2 - B3=(state of)A3 - A4

在我的情况下这样做的原因是我弄乱了中间状态 A2,我想用 B2 修复它,然后直接用 A3 继续。

我想到的最简单的方法是在另一个文件夹中检出 A3,删除 B 的内容并用 A3 的内容覆盖。

有Git命令可以直接实现吗?

【问题讨论】:

  • 赞成。我在这里是因为我在 git* 服务上的分叉存储库不会让我强制推送到我的主分支,该分支已经(错误地)与上游主分支分道扬镳。

标签: git merge version-control branch


【解决方案1】:

新的(从 Git 2.23 开始)git restore 命令可以作为单个命令执行此操作,使用工作树顶层的 git restore --source <em>commit</em> --worktree -- .。由于这种git restore 不影响Git 的索引,所以这里什么都没有。但这对想要来说是一件很奇怪的事情,所以在你做之前要确定它真的是你想要的。

(将--staged 添加到上面的git restore 也会使所有内容都暂存于提交。请注意,这与git checkout <em>commit</em> -- . 不同,因为git restore 默认以“无覆盖”模式运行,而@ 987654328@ 使用“叠加”模式。)

请注意,这不会将任何 分支 带到任何状态。分支没有这种状态:分支名称仅标识提交哈希 ID。这个git restore 命令只是修改你的工作树 的内容以匹配指定的提交,只留下索引/暂存区域。随后的 git commit 使用 Git 索引中的任何内容,因此您必须运行 git add 才能影响后续提交。

【讨论】:

    【解决方案2】:

    @torek 的回答对我有用,他们显然比我更了解 git。

    如果您只想让分支 B 离开 A3,您可以 git checkout B; git reset --hard A3 给您:

    A1 - A2 - A3 - A4
      \        \
       \        B
    [   B2 - B3        ] These will get removed eventually; are no longer on a branch
    

    如果您想将提交 B2 保留在 B 分支的历史记录中,那么您有两种选择:

    选项 1

    只需创建一个新分支“abandoned-b-branch”,然后执行上述操作。这意味着如果需要,您将始终可以参考废弃的 b 分支。

    选项 2

    git checkout B
    git revert -n B2
    git merge -n A3  # or even use cherry-pick -n
    

    这将您的工作树留在A3,但您的B2 提交原样并且仍然来自A1

    编辑 1 - 解决已澄清的问题

    我设置了相同的场景

    * a3420df        (branch-A) A4
    * e8b5e69        A3
    * 3f9837f        A2
    | * 1465593      (branch-B) B2
    |/
    * 6835b02        A1
    
    • 提交A1只有一个文件A1
    • 提交A2 添加A2
    • 提交A3 添加A3 并删除A2
    • 提交A4 添加A4
    • 提交B2 添加B2

    您更新后的问题表明您想要

    A1 - [A2 - A3 - A4]  (A will be deleted after the fix)
       \
         B2 - B3=(state of)A3 - A4
    

    我这样做了:

    git checkout branch-B
    git revert -n 1465593
    git cherry-pick -n 3f9837f e8b5e69
    

    使工作树处于A3 状态,文件A1A3。然后我可以继续将其作为 B3 提交,然后应用 A4

    git commit -m "B3"
    git cherry-pick -n a3420df
    git commit -m A4
    

    给我留下的分支-B(最后一个)看起来像

    * 262a312        (HEAD -> branch-B) A4
    * 7bca645        B3
    * 1465593        B2
    * 6835b02        A1
    

    在工作树中,我有 A1、A3、A4。提交 A2 已从我的分支历史记录中消失,但我的历史记录中仍有 B2。

    【讨论】:

    • 我想你误解了我的意思。我想保留 B2 但完全删除 A2 - 它从未存在于分支 B 中,但之后继续使用 A3 和 A4。当我对分支 A 进行 Merge/Cherry Pick 时,提交 A2 现在将出现在 B 的历史记录中。
    • 所以和B没关系?在 B 分支中是 A1 - B2 (就像现在一样),你希望 A 分支是 A1 - A3 - A4
    • 最后,我想要一个分支 A1 - B2 - A3 - A4。另一个将被删除。我只是想用 B2 替换 A2,然后继续,就好像 A2 不存在一样。
    猜你喜欢
    • 2015-04-10
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多