[Git]真正回滚已上传的更新

首先,抛弃本地的修改应当用:

$ 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好了。

4 thoughts on “[Git]真正回滚已上传的更新”

  1. 这种方法不如删除远端master(备份后),然后直接把本地reset后的master push

    push origin master

    不过需要权限

Leave a Reply

Your email address will not be published. Required fields are marked *