如何在一些特定的提交之后划分一个长的提交分支?
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
您的本地 exampleBranch
在 M0
之上总共有 75 次提交,C0_C29
的前 30 次提交已经合并,并且要求您拆分剩余的45 在 C30_C74
进入单独的独立合并。
有两种功能相同的方法可以做到这一点:
变基
创建 anotherBranch
,其中本地 exampleBranch
和 rebase
到 "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
.
我认为这个问题看起来和其他几个问题差不多,但我已经尝试了大约 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
您的本地 exampleBranch
在 M0
之上总共有 75 次提交,C0_C29
的前 30 次提交已经合并,并且要求您拆分剩余的45 在 C30_C74
进入单独的独立合并。
有两种功能相同的方法可以做到这一点:
变基
创建 anotherBranch
,其中本地 exampleBranch
和 rebase
到 "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
.