Is it possible to rewrite history without leaving trace?

给你一囗甜甜゛ 提交于 2019-12-05 17:17:45
VonC

Unless you have acces to the repo where the operation (generally a git filter-branch) has been done, and where you can access the git reflog, you wouldn't be able to audit this kind of change.

Meaning that if you clone that repo, the clone has no trace of that "rewrite" operation.

And even if you have access to the local repo and its reflog, that reflog is time-limited: after 90 days (by default) its records would be expunged.

Once the rewrite is done locally, it is generally forced push to a remote repo (git push --force), and there again, there is no trace of who did that forced push (hence the polygraph).
(Not unless you have some ACL -- Access Control Level -- management system like gitolite, which comes with its own audit trail)


Note: to understand the "destructive" nature of the rewrite, you need to understand how a commit is structured in the Git object model

The author and committer fields are actually composed of a name and a date.

Changing anything change the SHA1 of the commit, and of any other objects referencing that commit. Without any way to know that this commit was different at one point (except for the reflog, locally where the modification was done)

From 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:

(I omitted the GPG signature and commit message here)

$ 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

You can do anything you want in your own repo. You can't get anybody else's repo do to anything at all unless they allow it, and because of how git operates and "because math", specifically the math behind cryptographic hash functions, even if you could construct a forgery no other repo would even so much as see it let alone look at it or accept it.

For dealing with accidental force-pushes and the like, Git comes with documentation and samples for how to configure logging and restrictions and all manner of other workflow tailoring in the default hooks directory.

For a repo configured with even the simplest precaution, an executable

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

in hooks/post-receive, the answer to your question would be "no."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!