不留痕迹地改写历史是否可能?

8

我读过关于如何更改旧提交时间戳的这个问题

我想知道的是:这种操作是破坏性的(即不留下任何痕迹),还是可能会发现对存储库进行了某些操作?如果是这样,我该怎么做?

谢谢

2个回答

9
除非您可以访问操作(通常是git filter-branch)已完成的存储库并且可以访问git reflog,否则您将无法审计此类更改。
这意味着,如果您克隆该存储库,则克隆版本中没有那个“重写”操作的痕迹。
即使您可以访问本地存储库及其reflog,该reflog也有时间限制:默认情况下,在90天后它的记录将被清除。

重写完成后,通常会强制推送到远程仓库(git push --force),但是在那里,没有人可以追踪谁做了这个强制推送(因此需要测谎仪)。
(除非你有像gitolite这样的访问控制级别(ACL)管理系统,它自带审计跟踪功能)


注意:要理解重写的“破坏性”本质,您需要了解提交在Git对象模型中的结构。

http://schacon.github.io/gitbook/assets/images/figure/object-commit.png

作者和提交者字段实际上由一个姓名和日期组成。
更改任何内容都会改变提交的SHA1值,以及引用该提交的任何其他对象的SHA1值。除了本地修改时的reflog外,没有任何办法知道这个提交在某个时刻是不同的。
这个线程中,使用git cat-filegit hash-object
$ git cat-file -p ee85b05
tree 32e5d1faecbc24b16e078ba42c1ab3e2c6515ab6
parent cef45cd0977f5f3f2baa5a5d2da857aff63ee50b
parent a5c89565fe6ceb7ebeef9794afb57415bd9bf099
author Mike Gerwitz <mikegerwitz@gnu.org> 1407466634 -0400
committer Mike Gerwitz <mikegerwitz@gnu.org> 1407466634 -0400

一个提交的哈希值是从上述所有内容生成的:
(我在这里省略了GPG签名和提交消息)
$ git cat-file -p ee85b05 | git hash-object --stdin -tcommit
ee85b058df783ffaa9f8d5ae58f9eb6d7586b0ca

你会注意到这正是标签中引用的哈希值。
如果我们稍微改变提交内容,就会得到不同的哈希值
$ cat <( git cat-file -p ee85b05 ) <( echo foo ) | git hash-object --stdin -tcommit
696a73618dd5d0d39f030d19ceab08c14115af4e

感谢您提供详细的答案。所以,除非我在存储库上放置一些跟踪操作的东西,否则我无法仅使用Git跟踪它们,对吗?例如,您认为像Bitbucket这样的组织是否有此类审计日志?我有一个存储库需要检查。 - Jubstuff
BitBucket有自己的审计跟踪机制:https://blog.bitbucket.org/2013/08/15/new-audit-logs-give-you-the-who-what-when-and-where/,但可能不包括git操作。在2013年,我仍然提到了BitBucket的reflog(https://dev59.com/OWUp5IYBdhLWcg3wAjxF#15597710)。 - VonC

0

在你自己的存储库中,你可以做任何想做的事情。除非他们允许,否则你不能让任何其他人的存储库做任何事情。由于Git的操作方式和“因为数学”,特别是加密哈希函数背后的数学,即使你能构造伪造品,也没有其他存储库会看到它,更不用说查看或接受它了。

对于处理意外的强制推送等问题,Git附带了文档和示例,说明如何在默认的hooks目录中配置日志记录、限制和各种其他工作流程定制。

对于配置了最简单预防措施的存储库,一个可执行文件

#!/bin/sh
cat >>info/receives

hooks/post-receive中,对于你的问题,答案是“不”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接