Rebase - 功能分支合并到主分支的操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rebase - 功能分支合并到主分支的操作相关的知识,希望对你有一定的参考价值。

参考技术A

温馨提示先行:
永远不要衍合那些已经推送到公共仓库的更新

如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题。如果衍合那些已经公开的提交对象,并且已经有人基于这些提交对象开展了后续开发工作的话,就会出现叫人沮丧的麻烦。

参考链接: Git 分支 - 分支的衍合

操作步骤:

5.1 rebase
当前分支: dev_1 (粗体表示)
基底分支: develop
操作: 鼠标在 develop 分支上右击, 出现以下弹框, 选中"将当前变更衍合到 develop", 下一步"确认衍合", 若出现冲突则解决冲突. 然后重复上述右击操作, 弹框选择"继续衍合". 衍合完成后, dev_1 分支跑到了 develop 分支的下游, 而且是一根直线哦.

5.2 merge
当前分支: develop (粗体表示)
操作: 鼠标在 dev_1 分支上右击, 出现以下弹框, 选中"合并 dev_1 至 develop", 下一步"确认合并", 进行一次 Fast forward. 合并完成后, develop 分支指向了 dev_1 分支的最新提交.

5.3 删除 dev_1 分支
功能分支合并到主分支后, 就没有存在的意义了, 可以将其删除.

把在 C3 里产生的变化补丁在 C4 的基础上重新打一遍. 在 Git 里, 这种操作较做衍合(rebase).

它的原理是, 回到2个分支最近的共同祖先, 根据当前分支 (也就是要进行衍合的分支 dev_1) 后续的历次提交对象 (这里只有一个 C3), 生成一系列文件补丁, 然后以基底分支 (也就是 develop) 最后一个提交对象 C4 为新的出发点, 逐个应用之前准备好的补丁文件, 最后会生成一个新的合并提交对象 C3’, 从而改写 dev_1的提交历史, 使他成为 develop 分支的直接下游, 如下图.

现在回到 develop 分支, 进行一次 快进合并 (Fast forward). 此时, develop 分支指向了 C3’.

由于当前 develop 分支所在的提交对象是要并入的 dev_1 分支的直接上游, Git 只需把 develop 分支指针直接右移. 换句话说, 如果顺着一个分支走下去可以达到另一个分支的话, 那么 Git 在合并两者时, 只会简单地把指针右移, 因为这种单线的历史分支不存在任何需要解决的分歧, 所以这种合并过程可以称为 快进 (Fast forward).

git rebase 特性分支到主分支

【中文标题】git rebase 特性分支到主分支【英文标题】:git rebase the feature branch into the master branch 【发布时间】:2021-08-20 05:21:56 【问题描述】:

我正在尝试将功能分支重新定位到主分支。我在第 7 步及以后遇到问题。您能帮助确定 git rebase 的问题吗?即使在第 7 步中解决了合并冲突后,我也遇到了问题。

参考: 1. https://dev.to/joemsak/git-rebase-explained-and-eventually-illustrated-5hlb

    创建新分支:new-branch-one
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git checkout -b new-branch-one
Switched to a new branch 'new-branch-one'
    修改文件。在新分支中添加新提交
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git commit -m 'commit D'
[new-branch-one 487ec55] commit D

修改文件。新分支中的其他提交

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git commit -m 'commit E'
[new-branch-one 78b0680] commit E
 1 file changed, 2 insertions(+)
    签出 master 分支
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

从本地 master 分支上的远程 master 拉取

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git pull origin master
Username for 'https://gitlab.com': krishnagk
Password for 'https://krishnagk@gitlab.com': 
From https://gitlab.com/krishnagk/testrebaseone
 * branch            master     -> FETCH_HEAD
Already up to date.
    创建新分支:f-two
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git checkout -b f-two
Switched to a new branch 'f-two'

修改文件。在新分支中添加新提交

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git commit -m 'commit f'
[f-two 99210bc] commit f
 1 file changed, 2 insertions(+)

修改文件。新分支中的其他提交

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git commit -m 'commit g'
[f-two 6ed028f] commit g
 1 file changed, 2 insertions(+)

将新分支推送到远程仓库。

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git push origin f-two
Username for 'https://gitlab.com': krishnagk
Password for 'https://krishnagk@gitlab.com': 
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 505 bytes | 505.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: 
remote: To create a merge request for f-two, visit:
remote:   https://gitlab.com/krishnagk/testrebaseone/-/merge_requests/new?merge_request%5Bsource_branch%5D=f-two
remote: 
To https://gitlab.com/krishnagk/testrebaseone.git
* [new branch]      f-two -> f-two
    创建合并请求,将 f-two 分支合并到 master 分支中

请求将 f-2 合并到 master

17 分钟前由 Krishna Kurtakoti 合并(格林威治标准时间 2021 年 6 月 2 日上午 8:09)17 分钟前 更改与 044f2ae0 合并到 master 中

合并成功后,检出本地master分支并从远程master拉取。

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git checkout master
Already on 'master'
Your branch is up to date with 'origin/master'.
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git pull origin master
Username for 'https://gitlab.com': krishnagk
Password for 'https://krishnagk@gitlab.com': 
From https://gitlab.com/krishnagk/testrebaseone
 * branch            master     -> FETCH_HEAD
Already up to date.
    结帐分支 new-branch-one
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git checkout new-branch-one
Switched to branch 'new-branch-one'
    当我想在分支上做rebase master时,这一步出现了问题 新分行一
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: commit D
Using index info to reconstruct a base tree...
M   todo
Falling back to patching base and 3-way merge...
Auto-merging todo
CONFLICT (content): Merge conflict in todo
error: Failed to merge in the changes.
Patch failed at 0001 commit D
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
    成功解决冲突后,我们执行 git status
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git status
rebase in progress; onto 044f2ae
You are currently rebasing branch 'new-branch-one' on '044f2ae'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   todo
    实验步骤:
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git commit -m 'rebase'
[detached HEAD c83a6ff] rebase
 1 file changed, 2 insertions(+)
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git rebase --continue
Applying: commit D
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.

@torek 谢谢。我尝试了您的建议,结果如下:

krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git status
rebase in progress; onto 044f2ae
You are currently rebasing branch 'new-branch-one' on '044f2ae'.
  (all conflicts fixed: run "git rebase --continue")

nothing to commit, working tree clean
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git rebase --continue
Applying: commit D
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
krishna@krishna-Lenovo-G50-70:~/r/testrebaseone$ git rebase --skip
Applying: commit E
Using index info to reconstruct a base tree...
M   todo
Falling back to patching base and 3-way merge...
Auto-merging todo

【问题讨论】:

步骤太多。请将您的问题减少到更简单的程度。 它告诉你该怎么做:git rebase --continue 【参考方案1】:

伙计,你的问题太详细了。 看起来它归结为您在第 7 步中遇到的合并冲突。

您在两个分支中都修改了todo 文件,而 git 不知道要选择哪个版本,或者它应该从一个分支中选择部分更改并添加来自另一个分支的更改,以及如何处理共同的部分? Git 不知道如何回答这类问题,所以它留给你去理解该怎么做。

因此,您可以在第 7 步之后键入 git status,然后您会看到它正在变基并且有冲突需要解决

您可以解决文件中的冲突(我通常在 IDE 中解决,例如 JetBrains,因为它们提供了良好的 UI),但您可以使用任何其他 ide 或自己解决,

在任何情况下,一旦您解决了冲突并获得了您想要保留的版本,您可以输入git add .(或git add todo,如果您想具体一点),然后输入git rebase --continue(双连字符) GIT 将继续 rebase 并使其达到“干净状态”。

【讨论】:

不过,我会注意到,细节太多总比不够好。 :-) 我用两个连字符替换了你的破折号(以防有人想剪切和粘贴它)但留在你的括号中。

以上是关于Rebase - 功能分支合并到主分支的操作的主要内容,如果未能解决你的问题,请参考以下文章

git rebase使用

Git rebase使用

git rebase 压缩提交

使用基于功能分支的 rebase 提交消息修改,然后合并到 master

Git:如何使用 VS Code 源代码控制将功能分支合并到主分支?

图解 Git 基本命令 merge 和 rebase