Git高级教程- 远程仓库版本回退方法

1 简介

最近在使用git时遇到了远程分支需要版本回滚的情况,于是做了一下研究,写下这篇博客。

2 问题

如果提交了一个错误的版本,怎么回退版本?

如果提交了一个错误的版本到远程分支,怎么回退远程分支版本?

如果提交了一个错误的版本到公共远程分支,又该怎么回退版本?

3 本地分支版本回退的方法

如果你在本地做了错误提交,那么回退版本的方法很简单 
先用下面命令找到要回退的版本的commit id:

git reflog 
 
 
  • 1

接着回退版本:

git reset --hard Obfafd
 
 
  • 1

0bfafd就是你要回退的版本的commit id的前面几位

4 自己的远程分支版本回退的方法

如果你的错误提交已经推送到自己的远程分支了,那么就需要回滚远程分支了。 
首先要回退本地分支:

git reflog
git reset --hard Obfafd
 
 
  • 1
  • 2

紧接着强制推送到远程分支:

git push -f
 
 
  • 1

注意:本地分支回滚后,版本将落后远程分支,必须使用强制推送覆盖远程分支,否则无法推送到远程分支

5 公共远程分支版本回退的问题

看到这里,相信你已经能够回滚远程分支的版本了,那么你也许会问了,回滚公共远程分支和回滚自己的远程分支有区别吗? 
答案是,当然有区别啦。

一个显而易见的问题:如果你回退公共远程分支,把别人的提交给丢掉了怎么办?

下面来分析:

假如你的远程master分支情况是这样的:

A1–A2–B1

其中A、B分别代表两个人,A1、A2、B1代表各自的提交。并且所有人的本地分支都已经更新到最新版本,和远程分支一致。

这个时候你发现A2这次提交有错误,你用reset回滚远程分支master到A1,那么理想状态是你的队友一拉代码git pull,他们的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 directory clean
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

也就是说,你的队友的分支并没有主动回退,而是比远程分支超前了两次提交,因为远程分支回退了嘛。

(1) 这个时候,你大吼一声:兄弟们,老子回退版本了。如果你的队友都是神之队友,比如: Tony(腾讯CTO),那么Tony会冷静的使用下面的命令来找出你回退版本后覆盖掉的他的提交,也就是B1那次提交:

git reflog
 
 
  • 1

然后冷静的把自己的分支回退到那次提交,并且拉个分支:

git checkout tony_branch        //先回到自己的分支  
git reflog                      //接着看看当前的commit id,例如:0bbbbb    
git reset --hard B1             //回到被覆盖的那次提交B1
git checkout -b tony_backup     //拉个分支,用于保存之前因为回退版本被覆盖掉的提交B1
git checkout tony_branch        //拉完分支,迅速回到自己分支
git reset --hard 0bbbbbb        //马上回到自己分支的最前端
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过上面一通敲,Tony暂时舒了一口气,还好,B1那次提交找回来了,这时tony_backup分支最新的一次提交就是B1,接着Tony要把自己的本地master分支和远程master分支保持一致:

git reset --hard origin/master
 
 
  • 1

执行了上面这条命令后,Tony的master分支才真正的回滚了,也就是说你的回滚操作才能对Tony生效,这个时候Tony的本地maser是这样的:

A1

接着Tony要再次合并那个被丢掉的B1提交:

git checkout master             //切换到master
git merge tony_backup           //再合并一次带有B1的分支到master
 
 
  • 1
  • 2

好了,Tony终于长舒一口气,这个时候他的master分支是下面这样的:

A1 – B1

终于把丢掉的B1给找回来了,接着他push一下,你一拉也能同步。

同理对于所有队友也要这样做,但是如果该队友没有提交被你丢掉,那么他拉完代码git pull之后,只需要强制用远程master覆盖掉本地master就可以了

git reset --hard origin/master
 
 
  • 1

(2) 然而很不幸的是,现实中,我们经常遇到的都是猪一样的队友,他们一看到下面提示:

$ 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 directory clean
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

就习惯性的git push一下,或者他们直接用的SourceTree这样的图形界面工具,一看到界面上显示的是推送的提示就直接点了推送按钮,卧&槽,你辛辛苦苦回滚的版本就这样轻松的被你猪一样的队友给还原了,所以,只要有一个队友push之后,远程master又变成了:

A1 – A2 – B1

这就是分布式,每个人都有副本。这个时候你连揍他的心都有了,怎么办呢?你不能指望每个人队友都是git高手,下面我们用另外一种方法来回退版本。

注意:博主是在虚拟机中实验的,用于模拟两个人的操作,如果你在一个机器上,用同一个账号在不同的目录下克隆两份代码来实验的话,回退远程分支后,另外一个人是不会看到落后远程分支两次提交的,所以请务必使用虚拟机来模拟A、B两个人的操作

6 公共远程分支版本回退的方法

使用git reset回退公共远程分支的版本后,需要其他所有人手动用远程master分支覆盖本地master分支,显然,这不是优雅的回退方法,下面我们使用另个一个命令来回退版本:

git revert HEAD                     //撤销最近一次提交
git revert HEAD~1                   //撤销上上次的提交,注意:数字从0开始
git revert 0ffaacc                  //撤销0ffaacc这次提交
 
 
  • 1
  • 2
  • 3

git revert 命令意思是撤销某次提交。它会产生一个新的提交,虽然代码回退了,但是版本依然是向前的,所以,当你用revert回退之后,所有人pull之后,他们的代码也自动的回退了。 
但是,要注意以下几点:

  1. revert 是撤销一次提交,所以后面的commit id是你需要回滚到的版本的前一次提交
  2. 使用revert HEAD是撤销最近的一次提交,如果你最近一次提交是用revert命令产生的,那么你再执行一次,就相当于撤销了上次的撤销操作,换句话说,你连续执行两次revert HEAD命令,就跟没执行是一样的
  3. 使用revert HEAD~1 表示撤销最近2次提交,这个数字是从0开始的,如果你之前撤销过产生了commi id,那么也会计算在内的。
  4. 如果使用 revert 撤销的不是最近一次提交,那么一定会有代码冲突,需要你合并代码,合并代码只需要把当前的代码全部去掉,保留之前版本的代码就可以了.

git revert 命令的好处就是不会丢掉别人的提交,即使你撤销后覆盖了别人的提交,他更新代码后,可以在本地用 reset 向前回滚,找到自己的代码,然后拉一下分支,再回来合并上去就可以找回被你覆盖的提交了。

7 revert 合并代码,解决冲突

使用revert命令,如果不是撤销的最近一次提交,那么一定会有冲突,如下所示:

<<<<<<< HEAD
全部清空
第一次提交
=======
全部清空
>>>>>>> parent of c24cde7... 全部清空
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

解决冲突很简单,因为我们只想回到某次提交,因此需要把当前最新的代码去掉即可,也就是HEAD标记的代码:

<<<<<<< HEAD
全部清空
第一次提交
=======
 
 
  • 1
  • 2
  • 3
  • 4

把上面部分代码去掉就可以了,然后再提交一次代码就可以解决冲突了。

8 继续扩展,简单粗暴的回滚方法

看到这里也许你已经觉得学会了远程仓库版本回滚方法了,但是实践中总是会遇到很多不按套路来的问题,考虑下面一种情况:

如果你们开发中,忽然发现前面很远的地方有一次错误的合并代码,把本来下一次才能发的功能的代码合并到了这一次来了,这个时候全体成员都觉得直接回滚比较快,因为他们都有备份,覆盖了无所谓,这个时候用reset的话对队友的要求比较高,用revert的话呢要大面积的解决冲突,也很麻烦呀,怎么办呢?

这个时候,可以使用简单粗暴的办法,直接从那个错误的提交的前一次拉取一份代码放到其他目录,然后将master代码全部删除,把那份新代码方进去,然后提交,果然简单粗暴啊,虽然这种方法不入流,但是,实践中发现很好使啊,所以,实践是检验真理的唯一标准。遇到问题还是要灵活应对。 

9 总结

远程分支回滚的三种方法:

  1. 自己的分支回滚直接用reset
  2. 公共分支回滚用revert
  3. 错的太远了直接将代码全部删掉,用正确代码替代
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视频详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程内容: 1.版本管理工具概念 2. 版本管理工具介绍 2.1版本管理发展简史(维基百科) 2.1.1 SVN(SubVersion) 2.1.2 Git 3. Git 发展简史 4. Git 的安装 4.1 git 的下载 4.2 安装 5. Git 工作流程 5.1 Git 初始化 5.2 git 流程 5.2.1 流程图 5.2.2概念即详解 6.Git 的基本使用01-TortoiseGit 操作本地仓库 6.1 初始化仓库 6.2 添加文件 6.3 提交文件至本地仓库 6.4 修改文件,与再次提交文件 6.5 文件状态讲解 6.6 修改文件,不提交和上一个版本比较差异(diff) 6.7 查看提交历史记录 6.8 回退至历史版本 6.9 文件删除 6.9.1本地删除与恢复 6.9.2从版本库删除 6.9.3从版本库删除,但是不删除本地 6.10 忽略提交 7. Git 的基本使用02-TortoiseGit 操作本地仓库(分支) 7.1 分支的概念 7.2 为何要使用分支 7.3 创建分支 7.4 分支的查看切换 7.4.1查看分支 7.4.2切换分支 7.5 分支的合并与删除 7.5.1合并 7.5.2删除分支 8.tag 标签 8.1 标签的概念 8.2 标签的创建(tag) 8.3 标签的切换与删除 9. 远程仓库 9.0 局域网仓库 9.0.1本地相对路径,多个文件夹之间共享代码 9.0.2开启局域网共享代码 9.1 常用远程仓库托管服务 9.2 码云账号注册 9.3 创建远程仓库 9.4 把本地代码推送到远端 9.5 从远程仓库克隆代码 9.6 代码的修改与提交,查看历史 9.7 ssh 连接概述 9.8 ssh 密钥的生成 9.9 ssh 密钥配置 9.10 ssh 方式克隆/提交代码: 9.11. 远程仓库的其他操作 9.12 利用 gitee 搭建个人主页 10.命令行-- git基本操作 10.1 介绍 10.2 环境配置 10.3 初始化本地仓库 init 10.4 克隆 clone 10.5 查看状态 status 10.6 add 10.7 commit 10.8 删除 rm 11. 命令行--git 远程仓库操作 11.1 查看远程 11.2 添加/移除远测仓库 11.3 从远程仓库获取代码 12. 命令行-- 分支 13 . 命令行 --tag 14. 案例

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值