`
liuming
  • 浏览: 163852 次
  • 性别: Icon_minigender_1
  • 来自: 蛮夷之地
社区版块
存档分类
最新评论

版本控制的邪术:在特定条件下擦除GIT历史

Git 
阅读更多

代码版本库中的历史记录对于跟踪项目代码的变化来说,是非常重要的。通常的情况是一但代码提交进版本库,就成为了版本库的历史记录,而这些记录可以被追踪,不应该被篡改

 

但在很极端的情况下,你可能需要篡改这个库的历史。比如说你不小心把冠希哥的照片提交进了版本库,而你的老板正好是冠希哥的粉丝。这时你肯定不想用正常的手段把文件中目录中删掉,然后再提交回版本库,因为这样的话历史记录还是会存在的,要是哪天你老板审察这段历史的话,会真相大白的。所以你可能会要想办法把已经提交上去的历史擦除掉。

 

不过当你要做篡改历史这种事的时候,要牢记以下几点:

  • 篡改历史是一个很恶心的行为,被人知道后晚上会来找你的
  • 篡改历史是或多或少要付出代价的
  • 篡改历史可能会失败的,真相说不定哪天就会回归
  • 篡改历史只能寄托于非常特定的条件 ,不像某朝的法律那样说改就改的

 

对于要篡改GIT这种分布式、非线性的版本库的历史来说,情况会很复杂,条件限制会很多。特别是在涉及到多人开发的环境,要想偷偷地篡改历史而不被别人发现,成功率是很低的。

 

下面先说第一种最好的情况,要是符合以下全部条件:

  • 文件刚刚提交进版本库(只涉及到最近的一次或几次提交)
  • 之后再没有继续提交任何的东西
  • 也没有把提交的东西合并到任何其它本地的分支
  • 更没有同步到任何远程的版本库

很好,趁坏事还没出门,立马封杀+和谐:

git reset --hard HEAD~1

这会删除当前分支最近的一次提交的所有东西,包括历史记录和所涉及到的文件改动。要删除最近三次提交的话,就把上面命令中的1换成3,以此类推。要是说提交的东西同步到了本地的其它分支,也是切换到那个分支,按着这个流程走一次就行。这是最成功的一种情况,只要坏事不出门,一切都好办。

 

接着是一种比较坏的情况,就是你把东西同步到远程了。这下你想要篡改成功的话,必须眼明手快,机不可失。条件如下:

  • 文件刚刚提交进版本库(只涉及到最近的一次或几次提交)
  • 之后再没有继续提交任何的东西
  • 刚提交的已经同步到远程的版本库中的一个分支
  • 但是同步过去的东西还没有被其它人下载

这种情况下,先按上面的如法泡制一次,然后覆盖掉远程的历史:

git reset --hard HEAD~1
git push --force origin master

这里的例子假设你是要覆盖名叫origin的远程库上的master分支。

 

但实际上很可能的情况是,你同步到运程之后,有其它人下载了你的改动了。这个时候,基本杯具,除非你知道具体是谁,然后让他们提交自己的改动之前,按上面的做法删除记录,否则是很难办的。因为他们已经有了你之前提交的东西,并且再提交自己的改动,然后在下次同步到远程的时候,会把你删掉的东西重新发到远程上。这叫天网灰灰,疏而不漏。要是改动被很多人下载了的话,还是乖乖地用普通的reset吧

 

本文提及的属于软件工程中的邪术,不到事关重大时不应该随便乱用。

1
1
分享到:
评论
1 楼 zhangthe9 2012-03-29  
我就喜欢邪恶的

相关推荐

Global site tag (gtag.js) - Google Analytics