介绍
前面看到的 git merge 保持了 main / feature_1 原始节点的一致性,代价就是多了一个 merge 节点
那是否有方法可以不要有这些 merge 看起来"无用"的节点呢?那就用到了 rebase 方案
操作步骤
bash
$ git checkout feature_1b
Switched to branch 'feature_1b'
Your branch is up to date with 'origin/feature_1b'.
$
$ git log
commit 33063bff55e8d7142a2210a6973455abc98ec431 (HEAD -> feature_1b, origin/feature_1b)
Author: powertest
Date: Tue Feb 3 08:40:22 2026 +0000
Initial commit
$ touch feature_1b.c
$ echo feature_1b > feature_1b.c
$ git status
On branch feature_1b
Your branch is up to date with 'origin/feature_1b'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
feature_1b.c
nothing added to commit but untracked files present (use "git add" to track)
$ git add .
$ git commit -m "Add feature_1b.c"
[feature_1b 8c2dda5] Add feature_1b.c
1 file changed, 1 insertion(+)
create mode 100644 feature_1b.c
$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 298 bytes | 298.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature_1b, visit:
remote: http://gitlab.powertest.com.cn/powertest/test-git-feature-1/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature_1b
remote:
To ssh://gitlab.powertest.com.cn:12022/powertest/test-git-feature-1.git
33063bf..8c2dda5 feature_1b -> feature_1b
$ git log
commit 8c2dda57b712347a8108e5a4278a4bbbff54fb52 (HEAD -> feature_1b, origin/feature_1b)
Author: powertest
Date: Tue Feb 3 18:02:15 2026 +0800
Add feature_1b.c
commit 33063bff55e8d7142a2210a6973455abc98ec431
Author: powertest
Date: Tue Feb 3 08:40:22 2026 +0000
Initial commit
$ git log --oneline --graph
* 8c2dda5 (HEAD -> feature_1b, origin/feature_1b) Add feature_1b.c
* 33063bf Initial commit
$ git rebase main
Successfully rebased and updated refs/heads/feature_1b.
$ git status
On branch feature_1b
Your branch and 'origin/feature_1b' have diverged,
and have 2 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
$ git log
commit 0b8b109c1d9d5df04baddb68b6493c81e5665823 (HEAD -> feature_1b)
Author: powertest
Date: Tue Feb 3 18:02:15 2026 +0800
Add feature_1b.c
commit a079cfa408b94e871796efc799a58b7f6ad011f1 (origin/main, origin/HEAD, main)
Author: powertest
Date: Tue Feb 3 17:09:22 2026 +0800
Add main.c
commit 33063bff55e8d7142a2210a6973455abc98ec431
Author: powertest
Date: Tue Feb 3 08:40:22 2026 +0000
Initial commit
$ git rebase --continue
fatal: No rebase in progress?
$ git log --oneline --graph
* 0b8b109 (HEAD -> feature_1b) Add feature_1b.c
* a079cfa (origin/main, origin/HEAD, main) Add main.c
* 33063bf Initial commit
$ git push
To ssh://gitlab.powertest.com.cn:12022/powertest/test-git-feature-1.git
! [rejected] feature_1b -> feature_1b (non-fast-forward)
error: failed to push some refs to 'ssh://gitlab.powertest.com.cn:12022/powertest/test-git-feature-1.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
$ git push --force-with-lease origin feature_1b
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 333 bytes | 333.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature_1b, visit:
remote: http://gitlab.powertest.com.cn/powertest/test-git-feature-1/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature_1b
remote:
To ssh://gitlab.powertest.com.cn:12022/powertest/test-git-feature-1.git
+ 8c2dda5...0b8b109 feature_1b -> feature_1b (forced update)
$ git log
commit 0b8b109c1d9d5df04baddb68b6493c81e5665823 (HEAD -> feature_1b, origin/feature_1b)
Author: powertest
Date: Tue Feb 3 18:02:15 2026 +0800
Add feature_1b.c
commit a079cfa408b94e871796efc799a58b7f6ad011f1 (origin/main, origin/HEAD, main)
Author: powertest
Date: Tue Feb 3 17:09:22 2026 +0800
Add main.c
commit 33063bff55e8d7142a2210a6973455abc98ec431
Author: powertest
Date: Tue Feb 3 08:40:22 2026 +0000
Initial commit
优缺点比较
通过上面我们可以看出,rebase 方案的 rebase 的含义,将整个记录从树型结构变成了线型结构,代价就是部分节点的值发生了变化。如果分支别人正在并行开发,将会给别人造成很大的问题。
所以个人研发分支不跟别人共用的化可以使用 rebase 方案,共用分支的修改用 merge