Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to rewrite history without leaving trace?

I have read this question about changing the timestamp of an old commit.

What I'd like to know is: this kind of operations is destructive (i.e. don't leave any traces) or is it possible to find out that a certain operation was done on the repository? If is it so, how could I do it?

Thanks

like image 444
Jubstuff Avatar asked Mar 03 '15 11:03

Jubstuff


1 Answers

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

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

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 <[email protected]> 1407466634 -0400
committer Mike Gerwitz <[email protected]> 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
like image 146
VonC Avatar answered Sep 22 '22 08:09

VonC