Git错误提交后该如何回滚操作?

git项目的存储主要分为四部分:工作区、暂存区、本地仓库、远程仓库

git项目存储的主要部分以及之间的关系

  • Workspace:工作区(当前用户操作修改的区域)
  • Index / Stage:暂存区 (add后的区域)
  • Repository:仓库区或本地仓库(commit后的区域)
  • Remote:远程仓库(push后的区域)

整个过程如下:

  • 工作区–>add–>暂存区–>commit–>本地仓库区–>push–>远程仓库区
  • 远程仓库区–>fetch–>使用refs\remotes下对应分支文件记录远程分支末端commit_id 和本地仓库区 –>merge–>工作区
  • 远程仓库区–>pull–>使用refs\remotes下对应分支文件记录远程分支末端commit_id 、 本地仓库区 和 工作区

干货来咯!!!
现有如下提交记录:

 

$ git log

commit 119f493775ac878c24c37bebda316aa73a355003 (HEAD -> master)

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:13:37 2020 +0800

第四次提交

commit 8e226045a8c501950522225c9a01337688e03e99

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:13:16 2020 +0800

第三次提交

commit a2dd0e3dd5721a8e0848f98ef5a9d1be6688c0db

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:12:51 2020 +0800

第二次提交

commit 6d77ae0cd6a0e934722a1d97546f9b214bd13198

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:11:38 2020 +0800

第一次提交

说明:

  • commit后为commit_id,是每个commit的唯一标识,一般前六位即可确定一个唯一commit
  • Author后为设置的user和email
  • Date后为commit提交的时间
  • 后面的文字为每个commit的描述信息

提交顺序为:6d77ae --> a2dd0e --> 8e2260 --> 119f49

场景1:错误提交在本地仓库

  1. 获取当前提交的commit id
    命令:git log或者git reflog
    假设提交错误的commit id为commit id: 119f49这一次提交,即最后一次提交;
  2. 将某个commit id前的commit清除,并保留修改的代码
    命令:git reset <commit_id>
    当前场景下就是:commit_id为第三次提交的ID,即commit id: 8e2260
    将指定commit_id后的所有提交都删除,并保留修改的代码在本地的区域,即Workspace
  3. 修改错误内容后将修改好的代码add到暂存区,并提交到本地仓库中
    命令:git add <file_name> and git commit -m <commit_message> 或git commit -am <commit_message> 将最新修改后的代码commit
    提交后的提交记录如下: 可以看到,我们错误提交的第四次commit提交记录消失,取而代之的是我们更新代码后提交的记录第五次提交; 这样就完成了本地的代码修改和更新
 

$ git log

commit 323fc9b5d1d43f0b48a6bfd88b00b4ab53676ad7 (HEAD -> master)

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:39:37 2020 +0800

第五次提交

commit 8e226045a8c501950522225c9a01337688e03e99

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:13:16 2020 +0800

第三次提交

commit a2dd0e3dd5721a8e0848f98ef5a9d1be6688c0db

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:12:51 2020 +0800

第二次提交

commit 6d77ae0cd6a0e934722a1d97546f9b214bd13198

Author: bccoco <bccoco@163.com>

Date: Tue Sep 15 23:11:38 2020 +0800

第一次提交

整个流程:

 
  1. git log

  2. git reset 8e2260

  3. 修改代码

  4. git commit -am '第五次提交'

接下来对git reset进行一下总结:
在进行总结时,先假设有这样一个提交链:
commit_id1 --> commit_id2 --> commit_id3 --> commit_id4
git reset commit_id1:
reset是将HEAD重新定位到commit_id1上,对于commit_id2commit_id3 和 commit_id4 和本地当前的修改,对于不同的参数,会有不同的处理,具体如下:
reset命令有三种处理模式:

  • soft:保留commit修改,将修改存储到index中;也就是说git add后的区域
  • mixed:保留commit修改,将修改存储到本地工作区域中;也就是说git add前的区域
  • hard:删除commit修改,慎用!

git reset --soft

回滚commit_id前的所有提交,不删除修改:git reset --soft commit_id
重设head,不动index,所以效果是commit_id之后的commit修改全部在index中,将id3 和 id4的修改放到index区(暂存区),也就是add后文件存放的区域,本地当前的修改保留

git reset --mixed

回滚commit_id前的所有提交,不删除修改:git reset commit_id 等同于 git reset --mixed commit_id,与 下述的 git reset --hard commit_id效果不同
重设head 和 index,不重设work tree,效果就是commit_id之前的修改,全部在work tree中,为还未add的状态,将id3 和 id4 的所有修改放到本地工作区中,本地当前的修改保留

git reset --hard

回滚commit_id前的所有提交,将修改全部删除:git reset --hard commit_id
重设head、index、work tree,也就是说将当前项目的状态恢复到commit_id的状态,其余的全部删除(包含commit_id后的提交和本地还未提交的修改)慎用!!

场景2:错误提交已经推送到remote

如果想要只操作修改中间的一个commit,不对其他的commit产生影响; 也就是类似于我们只修改commit_id2,而对commit_id3 和 commit_id4无影响,该怎么处理呢? 在项目开发中,突然发现在前几次的提交中,有一次提交中包含一个bug; 当然我们可以进行一个新的修改,然后再提交一次; 但是历史看着不美观,我们可以直接重做有bug的commit。

为什么不直接去再添加一个commit呢? git revert是用于“反做”某一个版本,以达到撤销该版本的修改的目的。

比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西;
在revert命令中常用的就两个:

  • git revert -e <commit_id>:重做指定commit的提交信息
  • git revert -n <commit_id>:重做执行commit的代码修改

git revert -e

重做commit_id的提交信息,生成为一个新的new_commit_id:git revert -e commit_id

git revert -n

重做commit_id的提交:git revert -n commit_id
将commit_id中修改,放到index区,我们可以对他重新做修改并重新提交

场景3:在一次开发中,发现某个文件修改错了,想要将文件恢复到刚pull代码时的状态怎么办呢?

git checkout回滚指定文件的修改
命令:git checkout -- <file_name>

作用:将file_name的本地工作区的修改全部撤销
有两种情况:

  • 如果file_name在commit后没有add过这个文件,则撤销到版本库中的状态
  • 如果file_name在commit后add过这个文件,则撤销到暂存区的状态,也就是add后的状态

总之,就是让指定的文件回滚到最近的一次git add 或者 git commit时的状态!
git checkout的其他作用:

  • git checkout <branch_name>切换分支
  • git checkout -b <branch_bame>创建分支等操作

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值