首先,抛弃本地的修改应当用:
$ git reset --hard HEAD
使用 git 自身功能来回滚代码,取消上一次的修改应该用:
$ git revert sha1_of_commit
但要注意,虽然代码是实现了回滚,同时也会自动产生一条“回滚代码”的 log 。
有些时候,由于工作人员粗心,错误提交的内容完全无意义且占用空间颇大,就想真正 undo 掉错误的 commit,连历史记录都不想留。以下是我尝试的做法:
准备一份干净的客户端仓库
在客户端,下载服务器上的每个分支,并更新到最新状态。git branch -a
查服务器上有哪些分支,挨个 checkout 过去再 pull。
然后回到有错误 commit 的分支,reset 掉错误的 commit:
$ git reset --hard 671475b1ce
这样在客户端就形成了一个已剔除掉错误 commit 的完整状态了。
从客户端仓库生成服务端仓库
这就是 git 分布式源代码管理的优势,客户端也是完整仓库,只是表现形式与服务端的不同罢了,两者之间可以转换。在本地仓库( repo.client )的上级目录中执行:
$ git clone --bare repo.client repo.git
然后把现在服务端仓库中的 hooks, info 目录和 config, description 两个文件拷贝到新生成的服务端仓库当中。
然后备份旧的服务端仓库,删掉用新生成服务端仓库替代,并调整相关文件权限。
基本上就可以了,小结
在客户端 pull:
$ git pull
From ssh://domain.tld/repo
+ 368b15f...671475b master -> origin/master (forced update)
Already up-to-date.
客户端仓库的 HEAD 自动被重置到了错误 commit 之前的。
我这种做法,只适用于用户比较小,可以停掉服务慢慢弄的情况,并且会丢失所有错误 commit 之后的改动,所以要慎用。最好的方法还是搞好用户培训,避免产生离谱的错误提交,一些小的错误还是直接用revert好了。
这种方法不如删除远端master(备份后),然后直接把本地reset后的master push
push origin master
不过需要权限