git rebase实践

本文介绍了Git rebase的两种常见使用场景:一是用于个人分支,将多个commit合并为一个,以便于更整洁地提交特性;二是保持多人协作时的分支线性,通过git pull --rebase避免分支合并的复杂结构。通过实例详细展示了如何操作,以维护清晰的版本历史。
摘要由CSDN通过智能技术生成

一、本文介绍git rebase两种常用使用场景

  1. 本地分支合并多个commit为1个

  2. 多人合作开发时保持master或develop等公共分支的线性增长(不分叉)

二、准备工作

  1. 启动gitlab

首次启动:

docker run --name gitlab -d -p 5443:443 -p 5080:5080 -p 5022:22 -v /Users/sw/gitlab/config:/etc/gitlab -v /Users/sw/gitlab/logs:/var/log/gitlab -v /Users//sw/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce

非首次:

docker start gitlab
  1. 确保已经上传个人公钥到gitlab

  2. 确保宿主机用户目录下已经添加.ssh/config文件,其中有这么一段:

host mygitlab
    user liuliangbin
    hostname 127.0.0.1
    port 5022
    identityfile ~/.ssh/liuliangbin
  1. 登录gitlab,创建group:test,创建project:test

  2. clone代码

git clone git@mygitlab:test/test.git

  1. 添加文件,创建develop分支
cd test
git checkout -b develop origin/develop
echo "a" > a.txt
git add a.txt
git commit -m "add a.txt"
git push
  1. 目前test项目develop分支只有一个commit:“add a.txt”

三、场景1: 个人分支合并commit

  1. 为了开发某个特性,用户创建个人分支feature1
git checkout -b feature1
  1. 第1天开发结束了,虽然代码不完整,而且还没跑通,但作为一个好的实践,保持每天commit代码
echo "b" >b.txt
git add b.txt
git commit -m "add b.txt"
  1. 第2天开发结束了,虽然代码不完整,而且还没跑通,但作为一个好的实践,保持每天commit代码
echo "c" >c.txt
git add c.txt
git commit -m "add c.txt"
  1. 第3天开发完成,代码完整
echo "d" >d.txt
git add d.txt
git commit -m "add d.txt"
  1. 合入develop之前,分支的commit情况

  2. 合入develop之前,最好把上图中3个commit变成1个,原因是:

    这3个commit是为了开发一个特性所做的工作
    每个commit都不是完整的,每个单独commit没有意义(如果checkout出来可能甚至无法构建)

  3. git rebase合并本地分支最近3个commit

git rebase -i HEAD~3

-i 表示弹出交互式界面,让用户编辑控制合并操作,弹出界面如下:

编辑后:

上图表示在cb0e82e这个commit的基础上合并其它commit,保存并退出编辑器后会弹出另一个编辑器:
p
s
s

在这里可以编辑3个commit合并后的提交信息,只有非注释部分有效,保存退出后:
p
s
s
查看本地commit:

发现已经把3个commit合为1个新的commit,这时候可以往develop上合入:

git checkout develop
git merge feature1
git push

四、场景2:保持分支线性

在多人协作场景中,随着每个人代码合入变多,commit历史将变成复杂的树形结构,为了保持简洁,可以强制团队成员:

git pull --rebase

具体描述如下:

  1. 作为对比先来看下不用git pull --rebase的情况, 用普通的git pull

(1)两个用户基于同一个master的commit开发不同功能

//用户1, 在git_test目录下操作
git clone git@mygitlab:test/test.git test
cd test
git checkout -b user1
echo "u1" > u1.txt
git add u1.txt
git commit -m "add u1.txt"
//用户2,在git_test目录下操作
git clone git@mygitlab:test/test.git test2
cd test2
git checkout -b user2
echo "u2" > u2.txt
git add u2.txt
git commit -m "add u2.txt"

(2)用户1从user1分支把代码合入master分支并推送到远程master

//在git_test/test目录下
git checkout master
git merge user1
git pull
git push

(3)用户2从user2分支把代码合入本地master并推送到远程master

//在git_test/test2目录下
git checkout master
git merge user2
git pull
//git pull执行后,会弹出编辑框产生额外一个合并commit
git push

(4)master的commit历史将呈现分支和合并结构

  1. 用git pull --rebase

(1)两个用户继续分别开发

//用户1: 
git checkout master
git pull
//上面命令确保本地master分支是最新的
git checkout -b f1
echo "f1" > f1.txt
git add f1.txt
git commit -m "f1"
//用户2:
git checkout master
git pull
git checkout -b f2
echo "f2" > f2.txt
git add f2.txt
git commit -m "add f2.txt"

(2)用户1合入代码

git checkout master
git merge f1
git pull --rebase
git push

(3)用户2合入代码

git checkout master
git merge f2
git pull --rebase
git push

(4)master的commit历史将呈现结构:

可以观察到:

master分支的commit没有分支结构,也没有合并commit的情况,非常清爽。其中后合入的f2分支产生的commit就好像是基于f1分支的最新commit开发的,这就是git pull --rebase的效果
当然,如果git pull --rebase时有冲突,还是需要解决冲突,并用git rebase --continue继续rebase操作,或者用git rebase --abort中断rebase操作,回到rebase之前状态
有冲突时,如果冲突还没解决,执行git rebase --continue将不被允许,会报冲突未解决的错误
  1. 如果我们一开始就强制团队成员每次pull都要执行:git pull --rebase,master分支就不会分叉,保持非常清爽的线性结构

五、场景3:保持分支线性:在没有权限合入分支的场景

  1. 用户继续开发
//用户1: 
git checkout master
git pull
//上面命令确保本地master分支是最新的
git checkout -b f1 origin/f1
echo "f1" > test.txt
git add test.txt
git commit -m "f1"
//用户2:
git checkout master
git pull
git checkout -b f2 origin/f2
echo "f2" > test.txt
git add test.txt
git commit -m "f2"
  1. 用户1合入代码
git checkout master
git pull --rebase
git checkout f1
git rebase -i master
git push f1 origin/f1
//申请把origin/f1合入origin/master分支
  1. 用户2合入代码
git checkout master
git pull --rebase
git checkout f2
git rebase -i master
//选择commit,解决冲突
git add test.txt
git rebase --continue
git push f2 origin/f2
//申请把origin/f2合入origin/master
  1. 管理员执行merge操作后,分支结构如下图

六、总结

git的rebase功能有两个常用场景:

合并本地分支(如feature分支)中多个commit为一个: git rebase -i HEAD~3
多人合作开发时保持分支线性无分支状态:

在有权限操作目标分支的情况下,可以在对应分支上(如master或develop上)执行:git pull --rebase
在无权限操作目标分支的情况下,可以在个人分支上(如feature分支)执行: git rebase -i develop

确保你的团队成员已经理解rebase概念,在实际开发中鼓励团队用起来!

内部资料 学习记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值