【问题标题】:How to divide a long branch of commits after some specific commit?如何在某些特定提交之后划分一长串提交?
【发布时间】:2019-11-18 19:34:10
【问题描述】:

我认为这个问题看起来几乎像其他几个问题,但我已经尝试了大约 7 种方法,例如 Delete last commit in bitbucketHow can I remove a commit on GitHub? ,可惜还是没找到解决办法。

情况:我在分支“exampleBranch”中编写了代码,在很多文件(创建新文件、删除冗余文件等)中进行了大约 30 次提交(带有推送),因此存在很多差异。在这一步(比如在提交编号 30 时)我做了合并请求, 并且由于某些原因继续致力于这个分支(但没有推动,所以我只在本地拥有它)。同时另一个人对推送的 30 次 commit 进行了代码审查,并要求我将 MR 中的代码和第 30 次 commit 之后编写的代码分开。

对我来说非常清楚,我在第 30 次提交后的所有更改都可以通过从当前本地“exampleBranch”创建一个新分支(比如“anotherBranch”)来获得。是真的吗?

但对我来说不清楚的一点是如何在 30 日之后删除(本地和远程)所有提交(还有大约 45 次以上的额外提交)?所以最后在分支中应该只有已经被审阅者检查过的数据。

如果很重要,我们使用 gitlab。

提前感谢您的回复。

【问题讨论】:

    标签: git version-control gitlab git-reset


    【解决方案1】:

    理解您当前的 Git 历史状态有点困难。我将做几个假设(我会详细说明)。如果需要,请自行运行 git log --all --graph --oneline --decorate 来比较和纠正我的假设。

    听起来你有这样的情况:

    * M1 <- origin/master (with exampleBranch merged)
    |\
    | | * C30_C74 <- exampleBranch (additional 45 local-only commits)
    | |/
    | * C0_C29 <- origin/exampleBranch (30 commits, pushed)
    |/
    * M0
    

    您的本地 exampleBranchM0 之上总共有 75 个提交,C0_C29 的前 30 个提交已经被合并,并且您被要求将 C30_C74 的剩余 45 个提交拆分为单独的独立合并。

    有两种功能相同的方法可以做到这一点:

    变基

    创建anotherBranch 本地exampleBranchrebase 以“切断”C30_C74 并将其“重新附加”到M1

    git checkout exampleBranch                              # move HEAD to C30_C74
    git checkout -b anotherBranch                           # create anotherBranch at HEAD (C30_C74)
    git rebase anotherBranch C0_C29 --onto origin/master    # rebase anotherBranch from C0_C29 to M1
    

    樱桃采摘

    M1 上创建anotherBranch,并在cherry-pick 上“复制”/“重播”C30_C74 提交到您的本地exampleBranch

    git checkout origin/master                              # move HEAD to M1
    git checkout -b anotherBranch                           # create anotherBranch at HEAD (M1)
    git cherry-pick C0_C29..C30_C74                         # cherry-pick the range C0_C29..C30_C74 to HEAD
    

    完成后,您将拥有如下内容:

    * D0_D44 <- anotherBranch (identical changes as C30_C74)
    * M1 <- origin/master (with exampleBranch merged)
    |\
    | | * C30_C74 <- exampleBranch (additional 45 local-only commits)
    | |/
    | * C0_C29 <- origin/exampleBranch (30 commits, pushed)
    |/
    * M0
    

    您可以将anotherBranch 视为基于master 的新分支并创建新的合并请求。

    有关此类事情的精彩互动教程,请查看https://learngitbranching.js.org/

    为未来加分

    我猜在所有这些提交中只有少数有意义的逻辑更改。通常很难读取 30 或 45 个提交大小的合并请求。 (想象一下,如果你不得不像那样阅读别人的分支!)

    继续开发您的 Git-fu,并努力为每个有意义的逻辑更改提交一次。在线查找有关 Git interactive rebase 如何帮助您重组和简化分支中的提交的指南。

    【讨论】:

      【解决方案2】:

      Kache 的答案是一个非常完整和充实的答案。但是,我想指出一个被忽略的简单技术(使用git reset):
      1. 使用您要编辑的分支 (exampleBranch) 中的 (git branch) 创建一个新分支 (anotherBranch)。 (您似乎已经这样做了
      2.git checkout exampleBranch
      3.git reset C30 其中C30 实际上是要包含在您的 MR 中的最后一次提交的 SHA
      4.git push --force 用您的本地分支覆盖远程分支。
      5. 不要忘记也推送anotherBranch 与您所做的工作。

      我假设您正在处理具有写入权限的分支。但请注意git push --force,因为如果滥用它可能会造成很大的破坏。始终确保您没有强制推送到其他人的分支甚至master

      【讨论】:

        猜你喜欢
        • 2019-04-22
        • 2015-11-18
        • 2017-11-16
        • 1970-01-01
        • 2014-10-29
        • 1970-01-01
        • 1970-01-01
        • 2017-12-02
        • 1970-01-01
        相关资源
        最近更新 更多