是否可以不留痕迹地改写历史?
Is it possible to rewrite history without leaving trace?
我已阅读 this question 关于更改旧提交时间戳的内容。
我想知道的是:这种操作是破坏性的(即不留痕迹)还是有可能发现对版本库进行了某种操作?如果是这样,我该怎么办?
谢谢
除非您有权访问操作所在的存储库(通常是 git filter-branch
) has been done, and where you can access the git reflog
,否则您将无法审核此类更改。
意思是如果你克隆那个 repo,克隆就没有那个 "rewrite" 操作的痕迹。
即使您有权访问本地存储库及其 reflog,该 reflog 也是有时间限制的:90 天后(默认情况下)其记录将被删除。
一旦在本地完成重写,它通常会被强制推送到远程仓库 (git push --force
),同样,没有任何痕迹表明是谁进行了强制推送 (hence the polygraph) .
(除非你有一些 ACL -- 访问控制级别 -- 像 gitolite, which comes with its own audit trail 这样的管理系统)
注意:要了解重写的 "destructive" 性质,您需要了解提交在 Git object model
中的结构
作者和提交者字段实际上由姓名和日期组成。
更改任何内容都会更改提交的 SHA1,以及引用该提交的任何其他对象的 SHA1。没有任何办法知道这个提交在某一点上是不同的(reflog 除外,在本地进行了修改)
来自 this thread, using git cat-file
and git 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
a commit's hash is generated from all of that above content:
(这里省略了GPG签名和提交信息)
$ git cat-file -p ee85b05 | git hash-object --stdin -tcommit
ee85b058df783ffaa9f8d5ae58f9eb6d7586b0ca
You'll notice that this is precisely the hash referenced in the tag.
If we were to change the commit content in the slightest, we'd get a different hash:
$ cat <( git cat-file -p ee85b05 ) <( echo foo ) | git hash-object --stdin -tcommit
696a73618dd5d0d39f030d19ceab08c14115af4e
您可以在自己的存储库中做任何您想做的事情。除非他们允许,否则你不能让任何人 else 的 repo 做任何事情,而且由于 git 的运作方式和 "because math",特别是数学在 cryptographic hash functions 之后,即使您可以伪造,也没有其他存储库会看到它,更不用说查看或接受它了。
为了处理意外的强制推送等问题,Git 在默认 hooks
目录中提供了有关如何配置日志记录和限制以及所有其他工作流程定制方式的文档和示例。
对于配置了最简单预防措施的存储库,可执行文件
#!/bin/sh
cat >>info/receives
在 hooks/post-receive
中,您问题的答案是 "no."
我已阅读 this question 关于更改旧提交时间戳的内容。
我想知道的是:这种操作是破坏性的(即不留痕迹)还是有可能发现对版本库进行了某种操作?如果是这样,我该怎么办?
谢谢
除非您有权访问操作所在的存储库(通常是 git filter-branch
) has been done, and where you can access the git reflog
,否则您将无法审核此类更改。
意思是如果你克隆那个 repo,克隆就没有那个 "rewrite" 操作的痕迹。
即使您有权访问本地存储库及其 reflog,该 reflog 也是有时间限制的:90 天后(默认情况下)其记录将被删除。
一旦在本地完成重写,它通常会被强制推送到远程仓库 (git push --force
),同样,没有任何痕迹表明是谁进行了强制推送 (hence the polygraph) .
(除非你有一些 ACL -- 访问控制级别 -- 像 gitolite, which comes with its own audit trail 这样的管理系统)
注意:要了解重写的 "destructive" 性质,您需要了解提交在 Git object model
中的结构作者和提交者字段实际上由姓名和日期组成。
更改任何内容都会更改提交的 SHA1,以及引用该提交的任何其他对象的 SHA1。没有任何办法知道这个提交在某一点上是不同的(reflog 除外,在本地进行了修改)
来自 this thread, using git cat-file
and git 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
a commit's hash is generated from all of that above content:
(这里省略了GPG签名和提交信息)
$ git cat-file -p ee85b05 | git hash-object --stdin -tcommit
ee85b058df783ffaa9f8d5ae58f9eb6d7586b0ca
You'll notice that this is precisely the hash referenced in the tag.
If we were to change the commit content in the slightest, we'd get a different hash:
$ cat <( git cat-file -p ee85b05 ) <( echo foo ) | git hash-object --stdin -tcommit
696a73618dd5d0d39f030d19ceab08c14115af4e
您可以在自己的存储库中做任何您想做的事情。除非他们允许,否则你不能让任何人 else 的 repo 做任何事情,而且由于 git 的运作方式和 "because math",特别是数学在 cryptographic hash functions 之后,即使您可以伪造,也没有其他存储库会看到它,更不用说查看或接受它了。
为了处理意外的强制推送等问题,Git 在默认 hooks
目录中提供了有关如何配置日志记录和限制以及所有其他工作流程定制方式的文档和示例。
对于配置了最简单预防措施的存储库,可执行文件
#!/bin/sh
cat >>info/receives
在 hooks/post-receive
中,您问题的答案是 "no."