Git常用命令rebase

这篇具有很好参考价值的文章主要介绍了Git常用命令rebase。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、git常用命令rebase

rebase 会把你当前分支的 commit 放到公共分支的最后面,所以叫变基,就好像你从公共分支又重新拉出来这个

分支一样。

例如如果你从 master 拉了个 feature 分支出来,然后你提交了几个 commit,这个时候刚好有人把他开发的东西

合并到 master 了,这个时候 master 就比你拉分支的时候多了几个 commit,如果这个时候你 rebase master 的

话,就会把你当前的几个 commit,放到那个人 commit 的后面。

rebase 具体操作:

首先 master 也需要拉取到最新版本,然后是切换到 branch 分支,在branch分支执行 git rebase master,表

示 branch 上新提交的 commit 节点会在 master 上的最新提交点后重新设立起点重新执行,若是有冲突则解决冲

突,没有冲突执行 git add,然后执行 git rebase --continue,最后切换到 master 分支,执行 git merge

master

git merge 会将两个分支的最新提交点进行一次合并,形成一个新的提交点,最终形成树状的提交记录,但是有些

人并不是喜欢 merge,觉得 merge 之后出现的分叉会难以管理,那么可以选择 rebase 操作来替代 merge。

git rebase 操作是将要 rebase 的分支最新提交点作为新的基础点,将当前执行 git rebase master 的分支的新

commit 点重新生成 commit hash 值,rebase 完后再次切换到另一条分支进行合并,就可以保证线性的 commit

的记录。

最后只选择 merge 还是 rebase 取决于个人和时机情况,假如你想提交记录呈现线性整洁那么选择 rebase,否则

选择 merge,实际情况也有可能是这样的,每个人本地开发,可能会提交非常的多次,有些提交可能是修一些简

单的 bug,那么最后的提交只想做一次完整、正确的提交,那么也可以使用 rebase。

2、git rebase的两种用法

2.1 合并当前分支的多个commit记录

你可能出现过对同一处代码进行多次处理的场景,会进行多次提交,这会导致如下提交记录:

# 新建文件
touch README.md
touch a.txt
touch b.txt
touch c.txt

# 新建文件和本地提交
git add .
git commit -m "Initial commit"

# 修改和提交
echo a > a.txt
git add a.txt
git commit -m "modify a"

# 修改和提交
echo 1 > b.txt
git add b.txt
git commit -m "modify b"

# 修改和提交
echo 2 > b.txt
git add b.txt
git commit -m "modify b"

# 修改和提交
echo 3 > b.txt
git add b.txt
git commit -m "modify b"

# 修改和提交
echo c > c.txt
git add c.txt
git commit -m "modify c"
$ git log --pretty=format:'%h: %s'
2eeb74a: modify c
5d340c4: modify b
e51aaca: modify b
16aee3f: modify b
58c8fed: modify a
f6f3452: Initial commit

其实,中间的对 b 的 3 次提交完全可以合并成一次 commit,这个时候 rebase 就很有用了。

2.1.1 找到想要合并的commit然后使用rebase -i

这里的合并的 commit 是待合并的多个 commit 之前的那个 commit,这里也就是最下面那个 modify a 的

commit。

$ git rebase -i 58c8fed

注意:git rebase -i startPonit endPoint

前开后闭区间,这里的 startPonit 是指需要合并的 commit 的前一个 commit (即当前示例中的 58c8fed ),因

为三个 commit 肯定要基于上一个 commit 合并成了新的 commit。

谨慎使用 endPoint,该参数省略即默认表示从起始 commit 一直到最后一个,但是一旦你填写了,则表示

endPoint 后面的commit全部不要了。

2.1.2 进入Interact交互界面

终端会进入选择交互界面,让你进行变基选择操作。

git rebase,git,git
最上面三行,就是刚刚选中的三个 commit,按时间顺序依次往下排序。

前面的三个 Pick 其实就是下面 Commands 展示的 7 种命令中的第一个 p,也就是 use commit。

2.1.3 使用s命令合并到上一个commit

按 i 进入操作,将第 2 和 第 3 个 commit 的 pick 改成 s,按 Esc 退出操作,输入 :wq 保存并退出。

git rebase,git,git

2.1.4 修改commit记录

接下来会弹出第二个页面,分别展示 3 个commit的提交信息。

git rebase,git,git

这里三个信息都是一样的,我们选用第一个的提交信息,将其余的全部注释掉,重复上述步骤,保存退出即可。

git rebase,git,git

# 执行结果
$ git rebase -i 58c8fed
[detached HEAD 792e41c] modify b
 Date: Tue Mar 14 12:28:51 2023 +0800
 1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
2.1.5 查看最新合并情况

会发现原三个一样的提交现在合并成了一个新的 commit 。

$ git log --pretty=format:'%h: %s'
e6c4bbd: modify c
792e41c: modify b
58c8fed: modify a
f6f3452: Initial commit
2.1.6 rebase的其他用法
命令 缩写 含义
pick p 保留该commit
reword r 保留该commit,但需要修改该commit的注释
edit e 保留该commit,但我要停下来修改该提交(不仅仅修改注释)
squash s 将该commit合并到前一个commit
fixup f 将该commit合并到前一个commit,但不要保留该提交的注释信息
exec x 执行shell命令
drop d 丢弃该commit

2.2 避免出现分叉合并

接下来,我将用实际示例和场景,来分析 rebase 是如何解决分叉合并的。

2.2.1 先初始化信息
# 新建文件本地提交
touch README.md
git add README.md
git commit -m "Initial commit"

# 新建文件本地提交
touch first.txt
git add first.txt
git commit -m "first commit"

# 新建文件本地提交
touch second.txt
git add second.txt
git commit -m "second commit"

# 修改当前分支名master为develop
$ git branch -m master develop

$ git branch
* develop

# 新建分支
$ git branch feature

$ git branch
* develop
  feature
  
# 查看log信息
$ git log --pretty=format:"%h: %cd %s" --graph
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit
$ git checkout feature
Switched to branch 'feature'

$ git log --pretty=format:"%h: %cd %s" --graph
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit
2.2.2 develop新增文件
# develop分支下操作
$ touch a.txt

$ git add a.txt

$ git commit -m "add a.txt"
[develop 0434671] add a.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a.txt
 
$ git log --pretty=format:"%h: %cd %s" --graph
* 0434671: Thu May 18 13:49:41 2023 +0800 add a.txt
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit
2.2.3 feature新增文件
# feature操作
$ touch b.txt

$ git add b.txt

$ git commit -m "add b.txt"
[feature 21d641d] add b.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt

$ git log --pretty=format:"%h: %cd %s" --graph
* 21d641d: Thu May 18 13:51:04 2023 +0800 add b.txt
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit
2.2.4 develop直接merge feature
$ git checkout develop
Switched to branch 'develop'

$ git merge feature
Merge made by the 'recursive' strategy.
 b.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
 
$ git log --pretty=format:"%h: %cd %s" --graph
*   4e78e41: Thu May 18 13:52:04 2023 +0800 Merge branch 'feature' into develop
|\
| * 21d641d: Thu May 18 13:51:04 2023 +0800 add b.txt
* | 0434671: Thu May 18 13:49:41 2023 +0800 add a.txt
|/
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit

会出现以下结果:

1、会保留所有的commit

2、按提交顺序排序

3、产生新的commit点 (Merge branch ‘feature’ into develop)

2.2.5 develop rebase feature
$ git checkout develop
Switched to branch 'develop'

$ git rebase feature
First, rewinding head to replay your work on top of it...
Applying: add a.txt

$ git log --pretty=format:"%h: %cd %s" --graph
* 77cda09: Thu May 18 13:54:43 2023 +0800 add a.txt
* 21d641d: Thu May 18 13:51:04 2023 +0800 add b.txt
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit

会出现以下结果:

develop 分支的 a 会被排在合进来的 feature 分支 b 的上面(尽管 a 是先完成的)

develop 的原 commit a 被移除产生了新的 commit a’

从 feature 合进来的 b 不变 (不会对合进来的 commit 进行变基)

2.2.6 rebase两步走完整版

step1:feature 先 rebase develop

# feature分支
$ git checkout feature
Already on 'feature'

# 从分支上拉取
# 拉取的是两个分支都没有提交过的
$ git fetch origin

$ git rebase develop
First, rewinding head to replay your work on top of it...
Applying: add b.txt

$ git log --pretty=format:"%h: %cd %s" --graph
* 73699c0: Thu May 18 20:04:41 2023 +0800 add b.txt
* 0434671: Thu May 18 13:49:41 2023 +0800 add a.txt
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit
# 上面的命令比较繁琐,也可以直接执行下面的命令
# feature分支
$ git checkout feature
Switched to branch 'feature'

$ git pull develop --rebase

会出现以下结果:

feature 的 commit b 会在重新排在第一个变成 b’

这一步可以理解为,当前的 feature 相当于先把需求 b 拎出来,同步完最新的 develop,再把需求 b 放在了最后

面。

所以,接下来 merge 的时候就很舒服了。

step2:develop 再 merge develop

# develop分支
$ git checkout develop
Already on 'develop'

$ git merge feature
Updating 0434671..73699c0
Fast-forward
 b.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b.txt
 
$ git log --pretty=format:"%h: %cd %s" --graph
* 73699c0: Thu May 18 20:04:41 2023 +0800 add b.txt
* 0434671: Thu May 18 13:49:41 2023 +0800 add a.txt
* b825e57: Thu May 18 12:59:45 2023 +0800 second commit
* 40cf065: Thu May 18 12:59:09 2023 +0800 first commit
* 1e86259: Thu May 18 12:59:03 2023 +0800 Initial commit

而这,也是 rebase 为什么不会产生多余的 commit 记录的原因了。

不要基于 rebase 的分支切新分支:如果 feature 在写完新需求 b 后,切了新分支 feature_1,然后又 rebase 了

develop,那么新分支 feature_1 无论是合进 develop 还是合进 feature 都会有冲突,出现重复的 b (其实是b和

b’)。

除非你能百分百确保你的分支已经完成新需求,rebase 操作结束之后,再切新分支,这时他们才是同步的。

3、rebase的其它问题

3.1 rebase时如何解决冲突

1、先解决冲突再保存

2、git add .

3、git rebase --continue

注意不是commit。

如果 rebase 过程中,你想中途退出,恢复 rebase 前的代码则可以用命令 git rebase --abort

3.2 使用rebase的注意点

如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。

因为变基最强大也是最危险之处就在于它能改变原commit的hashId,而一旦你对历史提交做出改变, 那么从变基

那个节点开始往后的所有节点的 commit id 都会发生变化。这对线上环境来说,是不可控的。

3.3 不要对已经合并到主分支的本地修改进行变基

首先,自己的分支,如果想对已经推送的 commit 进行修改,可以在修改完后,使用 git push -f 强行 push 并覆

盖远程对应分支。

但是如果这些修改已经被合到了其他分支(比如主分支),那又会出现冲突,因为其他分支保存的是你 rebase 之前

合进去的 commit。

3.4 不要在预发布/正式分支上使用rebase -i

从变基那个节点开始往后的所有节点的 commit id 都会发生变化。

4、rebase的另一个用法

它的另一个用法是删除任意提交,但是注意不到万不得已的时候不要这么做,因为会使后面的 commit id都会变

化。文章来源地址https://www.toymoban.com/news/detail-564946.html

$ git log --oneline
d735ee3 (HEAD -> master, origin/master, origin/branch_d, origin/HEAD) branch_d | update a.txt | update b.txt | update e.txt
8cb57f6 (origin/branch_c) branch_c | update a.txt | delete e.txt
5b05cb6 (origin/branch_b) branch_b | update a.txt | add new.txt
ddbfc0b (origin/branch_a) branch_a | update a.txt | add new.txt
87d5c63 add f.txt
47e8b59 add e.txt
c0547da add d.txt
9c173bb add c.txt
8c4a625 add b.txt
8e58180 add a.txt
# git rebase --onto commit^ commit
# 例子,假设不要47e8b59这个提交了
$ git rebase --onto 47e8b59^ 47e8b59
First, rewinding head to replay your work on top of it...
Applying: add f.txt
Applying: branch_a | update a.txt | add new.txt
Applying: branch_b | update a.txt | add new.txt
Applying: branch_c | update a.txt | delete e.txt
Using index info to reconstruct a base tree...
A       e.txt
Falling back to patching base and 3-way merge...
Applying: branch_d | update a.txt | update b.txt | update e.txt
$ git log --oneline
2e1e177 (HEAD -> master) branch_d | update a.txt | update b.txt | update e.txt
b6f1c57 branch_c | update a.txt | delete e.txt
1868ec3 branch_b | update a.txt | add new.txt
1eccbb4 branch_a | update a.txt | add new.txt
4e89b48 add f.txt
c0547da add d.txt
9c173bb add c.txt
8c4a625 add b.txt
8e58180 add a.txt

到了这里,关于Git常用命令rebase的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Git 怎么使用?管理项目?冲突?命令汇总(git rebase、git reverse、git reset、git tag)——保姆及教程(持续更新)

    写在前面: 整理:CS_GUIDER,作者:阮一峰,原文链接:https://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html 文章一般会优先在个人博客中更新,欢迎少爷们围观我的个人博客: https://wl2o2o.github.io/(点击即可访问) 推荐一个快速练习 Git 的宝藏网站——动图演示 Git 的命令逻辑。

    2024年02月03日
    浏览(33)
  • git合并代码命令 分支合并代码 cherry-pick merge rebase区别

    1.cherry-pick 需要注意 暂存未提交的更改 暂存更改: 使用git stash或git stash push命令暂存当前工作目录和暂存区的更改。你可以提供一个消息作为参数,以便更容易地识别stash项: 执行cherry-pick: 现在,你的工作目录是干净的,可以安全地执行cherry-pick操作了。找到你想要cherry

    2024年04月12日
    浏览(40)
  • 【Git】Git 操作命令可视化(五):git clone、git fetch、git pull、git push、git pull --rebase、解决远程仓库与本地仓库的代码冲突

    1. git clone main是本地的main分支,o(origin)/main是表示本地拉去下来的远程的main分支 o/main分支记录了远程仓库拉取时的分支状态 远程分支有一个特别的属性,在你切换到远程分支时,git会自动进入分离 HEAD 状态(这样做是因为git不想让你在本地就能直接进行修改远程仓库代码的

    2024年02月08日
    浏览(51)
  • git实用命令 git常用分支命令

    要在Git中创建一个新的分支,按照以下步骤进行操作: 确保你当前在要创建分支的代码状态下。你可以使用 git status 命令查看当前的代码状态,并使用 git add 和 git commit 命令将修改的文件提交到当前分支。 1.使用 git branch 命令创建一个新的分支。 这将在本地仓库中创建一个

    2024年02月10日
    浏览(29)
  • Git下载和Git常用命令

    要下载和安装 Git,请按照以下步骤进行操作: 1.访问官方网站:打开 Git 官方网站 https://git-scm.com/。 2.下载 Git 安装程序: 3.选择适用于你的操作系统的下载链接。Git 支持多个操作系统,包括 Windows、macOS 和 Linux。 4.点击下载链接,开始下载 Git 安装程序。 5.运行安装程序:

    2024年02月08日
    浏览(32)
  • Git(3):Git环境常用命令

    1 获取本地仓库 要使用Git对我们的代码进行版本控制,首先需要获得本地仓库 (1)在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库 (2)进入这个目录中,点击右键打开Git bash窗口 (3)执行命令git init (4)如果创建成功后可在文件夹下看到隐藏的.git目

    2024年02月03日
    浏览(32)
  • git快速入门!!! git的常用命令!!!

    Git 是一个开源的分布式版本控制系统,有很多实用的命令可以帮助我们更高效地管理项目和代码。以下是一些常用的 Git 命令及其使用方法和示例: 1. 初始化一个新的 Git 仓库 这个命令会在当前目录下创建一个新的 Git 仓库。 2. 添加文件到暂存区 这个命令会把指定的文件添

    2024年02月05日
    浏览(42)
  • git 常用命令之 git checkout

    大家好,我是 17。 git checkout 是 git 中最重要最常用的命令之一,本文为大家详细解说一下。 checkout 的用途之一是恢复工作区。 checkout . 表示恢复工作区的所有更改,未跟踪的文件不会有变化。 恢复工作区的所有文件风险比较大,会丢失所有工作区的修改,一定要慎用 中间加

    2023年04月13日
    浏览(70)
  • 【Git】git常用命令集合

      Git是现代软件开发不可或缺的版本控制工具,它可以追踪文件的变化、协同开发以及管理代码版本。掌握Git的常用命令对于开发人员来说至关重要。本文将为你介绍一些Git常用命令,帮助你轻松驾驭版本控制。   详细介绍了Git的常用命令,涵盖了版本管理、分支操作、

    2023年04月08日
    浏览(48)
  • git常用命令(git github ssh)

    被” “和\\\"[ ]“包含起来的内容表示用户自己选定的参数。但” “是要求用户必须输入的,而”[ ]\\\"表示用户可以根据自己的需要选择输入。 比如git reset的语法是这样的: 其中commitid指的是commit id,可以理解为每一提交到本地仓库之后该仓库状态的ID,利用这个ID我们可以快速

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包