从程序员枪杀案谈git push -f

程序员专属-极客T恤

最近看到几个消息:

程序员不老老实实的当键盘侠,搞起自己的同事?

目前,码农持枪杀人的动机仍然是个谜。有人猜测道:“同事不写注释,不遵循驼峰命名,括号换行,最主要还天天git push –f等因素”激怒了这名行凶者。

看到上面的原因,感觉太假了,“天天git push –f”,开什么玩笑,第一天这么干就被打断腿了好不好?

Git 远程仓库简介

Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上。

在这类系统中,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。

Git Push

所以不可避免的远程仓库和本地仓库,git 常用命令流程图如下: git push命令用于将本地分支的更新,推送到远程主机。

$ git push <远程主机名> <本地分支名>:<远程分支名>

如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。

$ git push origin master

上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

Git Push -f

如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这是正常合理的代码提交流程。 这时,如果你一定要推送,可以使用--force选项。

$ git push --force origin 

上面命令使用--force选项,结果导致远程主机上更新的版本被覆盖。同事之前推送的代码会被你抹掉,他可能刚刚提交了一整个功能模块的代码,也许是一周的工作量。如果大家都不小心更新你的版本,OMG,前功尽弃。 除非你很确定要这样做,否则应该尽量避免使用--force选项。

怎么样避免使用 –force 选项?

1,只给自己用,要坑就坑自己。

我自己在工作的时候,通常会开一个分支出去做,但做完发现Commit 太过琐碎,便会想使用Rebase 来整理一下这个分支。虽然Rebase 是修改历史没错,但因为这个历史影响的范围只有我自己这个分支,所以并不会影响其它人正常使用:

$ git push -f origin features/my_branch

这样只会强制更新features/my_branch这个分支的内容,不会影响其它分支。

2,设置保护机制

但总是有人可能不小心使用了-f参数来Push,GitHub网站有提供保护机制,可以避免某个分支被Force Push。请到仓库的「Settings」页签,左边选择「Branches」,添加保护的规则:

同样,码云gitee.com等有也有样的设置(不过要付费企业项目):

如何回滚?

如果不考虑刚才–force提交的代码,救回来其实还满简单的,就是换你或是其它有之前进度的队友,再次进行git push -f指令一次,把正确的内容强迫推上去,盖掉前一次的git push -f所造成的灾难。

参考资料


关注微信公众号

码中人 微信公众号