如何在一些特定的提交之后划分一个长的提交分支?

How to divide a long branch of commits after some specific commit?

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

情况:我在分支 "exampleBranch" 中编写了代码,在很多文件中使用 diff 进行了大约 30 次提交(使用推送)(创建新文件、删除冗余等),所以有相当多的很多差异。在这一步(比如提交编号 30)我做了合并请求, 并且由于某些原因继续致力于这个分支(但没有推动,所以我只在本地拥有它)。同时另一个人对push的30次commit做了code review,让我把代码分到MR,以及第30次commit之后写的代码。

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

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

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

预先感谢您的回复。

了解您当前的 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 次提交已经合并,并且要求您拆分剩余的45 在 C30_C74 进入单独的独立合并。

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

变基

创建 anotherBranch,其中本地 exampleBranchrebase 到 "cut off" C30_C74 和 "reattach" 到 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 到 "copy"/"replay" 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 如何帮助您重新组织和简化分支中的提交的指南。

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.