使用 git rebase 来消除提交历史分叉

发布于 2024-01-10 13:05:34 字数 7674 浏览 24 评论 0

在很多时候,随着开发团队的扩容,大家提交代码一段时间过后,就产生很多的 合并(merge) 节点,对于有代码洁癖的人来说,这个总会觉得很不爽。

master 分支混乱的提交历史

那么,merge 是如何产生的呢?下面我挑一个常见的冲突的场景,示例一下:

用 merge 来解决冲突

我们来在 master 分支 模拟一次 merge 的情况,针对 README.md ,首先 A 用户编写了首行代码 ,并提交到了 git 服务器上内容如下:

# A 用户编写首行代码

同时, B 用户在本地编写了首行代码 ,内容如下:

# B 用户编写首行代码

B 用户只是在本地电脑上进行了 git commit ,如下:

$ git commit -am "B 用户编写首行代码"
[master c8bfe4f] B 用户编写首行代码
 1 file changed, 1 insertion(+), 1 deletion(-)

接下来,B 用户使用 git pull 命令将 git 服务器代码下载并合并到本地,可以看到产生了冲突:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git pull
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From gitee.com:yyxz/test
   45bc85e..fc2c29a  master     -> origin/master
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

接下来,B 用户,修改有冲突的 README.md 文件,解决冲突,如下:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|MERGING)
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|MERGING)
$ git add README.md

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|MERGING)
$ git commit -m "合并 A 和 B 用户编写的首行代码"
[master 5aa451d] 合并 A 和 B 用户编写的首行代码

修改后的 README.md 文件内容如下:

# 合并 A 和 B 用户编写的首行代码

现在 B 将代码提交到 git 服务器上,可以看到有两个 commit(一个是 B 对首行代码的提交: c8bfe4f ,一个是 B 刚才的 merge 动作),如下:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
nothing to commit, working tree clean

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git push
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 695 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To gitee.com:yyxz/test.git
   fc2c29a..5aa451d  master -> master

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git log --oneline --graph
*   5aa451d (HEAD -> master, origin/master, origin/HEAD) 合并 A 和 B 用户编写的首行代码
|\
| * fc2c29a A 用户编写首行代码
* | c8bfe4f B 用户编写首行代码
|/
* 45bc85e 初始状态

可以看到,提交历史产生了分叉,接下来我们看看如何使用 git rebase 消除分叉:

git rebase 消除分叉

A 再次修改首行代码,并提交至 git 服务器, README.md 内容如下:

A 再次修改首行代码

B 再次在本地修改首行代码,并提交至本地, README.md 内容如下:

B 再次修改首行代码

commit 如下:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git commit -am "B 再次修改首行代码"
[master 21a6c2a] B 再次修改首行代码
 1 file changed, 1 insertion(+), 1 deletion(-)

接下来,使用 git pull --rabase ,可以看到冲突,并且进入了 rebase 状态:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git pull --rebase
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From gitee.com:yyxz/test
   5aa451d..ccbb4ff  master     -> origin/master
First, rewinding head to replay your work on top of it...
Applying: B 再次修改首行代码
error: Failed to merge in the changes.
Using index info to reconstruct a base tree...
M       README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Patch failed at 0001 B 再次修改首行代码
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".


bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|REBASE 1/1)
$

此时,B 在本地打开 README.md 文件,可以看到冲突内容如下:

<<<<<<< HEAD
A 再次修改首行代码
=======
B 再次修改首行代码
>>>>>>> B 再次修改首行代码

解决冲突:修改 README.md 文件,内容如下:

再次合并 A 和 B 修改的首行代码

使用 git add README.md 标注冲突已解决:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|REBASE 1/1)
$ git add README.md

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master|REBASE 1/1)
$ git rebase --continue
Applying: B 再次修改首行代码

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git log --oneline --graph
* 1e4c421 (HEAD -> master) B 再次修改首行代码
* ccbb4ff (origin/master, origin/HEAD) A 再次修改首行代码
*   5aa451d 合并 A 和 B 用户编写的首行代码
|\
| * fc2c29a A 用户编写首行代码
* | c8bfe4f B 用户编写首行代码
|/
* 45bc85e 初始状态

可以看到 B 用户第二次修改是在 A 修改之后,但是 B 的提交 commit 编号 21a6c2a 被新的编号 1e4c421 所取代,commit 的内容不变。

这时我们看到 HEAD -> master,origin/master, origin/HEAD 不一致。是因为 B 用户在本地的修改还未提交至 git 服务器,通过 git status 也可以看出来,有 1 commit 未提交至 git 服务器:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working tree clean

提交后,就 OK 了。如下:

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 355 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To gitee.com:yyxz/test.git
   ccbb4ff..1e4c421  master -> master

bianxh@DESKTOP-BIANXH MINGW64 /d/Workspaces/gitee/test (master)
$ git log --oneline --graph
* 1e4c421 (HEAD -> master, origin/master, origin/HEAD) B 再次修改首行代码
* ccbb4ff A 再次修改首行代码
*   5aa451d 合并 A 和 B 用户编写的首行代码
|\
| * fc2c29a A 用户编写首行代码
* | c8bfe4f B 用户编写首行代码
|/
* 45bc85e 初始状态

现在我们登录到服务器看下最新的内容,如下:

使用 rebase 解决冲突后的 README.md 文件内容

可以通过项目网络图直观地看到,如下:

项目网络图

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

二手情话

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文