Git add/commit/push的撤销

引入

使用Git过程中,任何时候,你都有可能需要撤消刚才所做的某些操作,为此该章节,汇总了一些基本的撤消操作相关的命令。专门解决这些困惑。

声明

本文只阐述如何解决问题,不会对git的各种概念多做介绍,如果有兴趣可以点击下面的链接,进行详细的学习: 
Pro Git

另外请注意,有些撤销操作是不可逆的,所以请务必谨慎小心,一旦失误,就有可能丢失部分工作成果。

1. 取消对本地文件的修改

问题:如果觉得对某些local files的修改完全没有必要,该如何取消修改,回到之前的状态(也就是修改之前的版本)呢?

方法:其实git status 提示了具体的撤消方法,可以直接git status查看,如下

git checkout -- <bad filename>

原理git checkout 会把工作目录里的文件修改到 Git 之前记录的某个状态。你可以提供一个你想返回的分支名或特定 SHA ,或者在缺省情况下,Git 会认为你希望 checkout 的是HEAD,当前 checkout 分支的最后一次 commit。

记住:你用这种方法“撤销”的任何修改真的会完全消失。因为它们从来没有被提交过,所以之后 Git 也无法帮助我们恢复它们。你要确保自己了解你在这个操作里扔掉的东西是什么!(也许可以先利用git diff来确认一下)

2. git add 添加错文件,撤销

git status 先看一下add 中的文件 状态(养成这个习惯,保证万无一失)
git reset HEAD 撤销本地所有add操作 
git reset HEAD <file/folder name> 撤销add操作的某个文件或目录

3. git 取消本地 commit (未push)

方法:git reset --soft HEAD^  

原理:这样就成功的撤销了你的commit。注意,仅仅是撤回commit操作,您写的代码仍然保留。

延伸,以下command参数也是可以使用的,只是略有差别,可以根据具体场景选择:

参数1选择--soft:不删除工作空间改动代码,撤销commit,不撤销git add . 

--mixed:不删除工作空间改动代码,撤销commit,并且撤销git add . 操作。这个为默认参数,git reset –mixed HEAD^ 和 git reset HEAD^ 效果是一样的

--hard :删除工作空间改动代码,撤销commit,撤销git add .。完成这个操作后,就恢复到了上一次的commit状态。

参数2选择HEAD^ 等同于HEAD~1 ,相当与回退到上几个版本;所以,如果是回退两个版本,也可以是HEAD~2 or HEAD^^

补充:如果commit注释写错了,只是想改一下注释,可使用:

git commit --amend or git commit --amend -m “new commit info”

前者会进入默认vim编辑器,修改注释完毕后保存就好了,后者则是新的info会直接替换掉旧的info。

原理:git commit --amend 会用一个新的 commit 更新并替换最近的 commit ,这个新的 commit 会把任何修改内容和上一个 commit 的内容结合起来。如果当前没有提出任何修改,这个操作就只会把上次的 commit 消息重写一遍。

但是万一万一,你用git reset --hard撤销了commit修改只够,有后悔了后悔了。。。怎么办?

方法: git reflog

原理: git reflog 对于恢复项目历史是一个超棒的资源。你可以恢复几乎任何你 commit过的东西,只要通过reflog。你可能已经熟悉了git log命令,它会显示commit的列表。git reflog也是类似的,不过它显示的是一个HEAD发生改变的时间列表.

一些注意事项:

  1. 它涉及的只是 HEAD 的改变。在你切换分支、用git commit 进行提交、以及用git reset 撤销 commit 时,HEAD会改变,但当你用git checkout -- <bad filename> 撤销时(正如我们在前面讲到的情况),HEAD并不会改变 — 如前所述,这些修改从来没有被提交过,因此 reflog也无法帮助我们恢复它们。
  2. git reflog不会永远保持。Git会定期清理那些“用不到的”对象。不要指望几个月前的提交还一直躺在那里。
  3. 你的reflog就是你的,只是你的。你不能用git reflog来恢复另一个开发者没有 push 过的 commit。

那么…你怎么利用 reflog 来“恢复”之前“撤销”的 commit 呢?它取决于你想做到的到底是什么:

  1. 如果你希望准确地恢复项目的历史到某个时间点,用git reset --hard <SHA>
  2. 如果你希望重建工作目录里的一个或多个文件,让它们恢复到某个时间点的状态,用git checkout <SHA> -- <filename>
  3. 如果你希望把这些 commit 里的某一个重新提交到你的代码库里,用git cherry-pick <SHA>

4. git push提交成功后如何撤销回退

问题:同样,git push后发现提交的内容不是想要的,这时候我们怎么做呢,提交上去的内容是没有删除按钮的(比如github,或码云)。所以我们需要一些手段将提交上去内容撤销下来。

方法1:git revert <SHA>

原理: git revert 会产生一个新的 commit,它和指定 SHA 对应的 commit 是相反的(或者说是反转的)。如果原先的 commit 是“物质”,新的 commit 就是“反物质” — 任何从原先的 commit 里删除的内容会在新的 commit 里被加回去,任何在原先的 commit 里加入的内容会在新的 commit  里被删除。

这是 Git 最安全、最基本的撤销场景,因为它并不会改变历史,所以你现在可以git push新的“反转”commit 来抵消你错误提交的commit。

方法2先回退版本 用git reset --hard/soft,直接修改代码,然后git commit,最后git push origin 分支 --force

注意:提交失败,因为当前分支的版本低于远程分支的版本,所以要想覆盖掉它,必须使用force

 

 

以上只是一些使用经验总结,如有不妥之处,请提出,多多讨论,感谢

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值