obliterate functionality?

Martin Geisler mg at daimi.au.dk
Tue Mar 18 14:58:33 CDT 2008


cowwoc <cowwoc at bbs.darktech.org> writes:

> Jens Alfke wrote:
>> 
>> For that reason, hg (and similar systems like Monotone and Bazaar)
>> use digital signatures to identify commits. There is deliberately no
>> way to obliterate or alter a prior commit, because it would
>> invalidate the signatures of anything that came after it. Basically,
>> obliteration is a form of tampering, that has to be prevented.
>
> Okay, I am beginning to understand. So you're saying that all data
> associated with a commit is signed with a public key and that removing
> a file from within that commit would require one to re-sign the data
> somehow and that isn't possible. Correct?

Not quite -- Mercurial does not sign anything by default. Instead it
computes a hash value of the data in each changeset, and this includes
the hash(es) of the parent changesets.

So every repository starts out with a hash of all zeros: rev0 = 00...00.
When you add some files and make your first commit the hash of those
files including the 00...0 hash become the first changeset hash:

  rev1 = Hash(data in commit 1 + rev0)

The second commit includes the hash of the first commit:

  rev2 = Hash(data in commit 2 + rev1)
       = Hash(data in commit 2 + Hash(data in commit 1 + rev0)
       = Hash(data in commit 2 + Hash(data in commit 1 + 00...0)

and so on. The result is a chain of hashes.

If someone gives you a repository out of the blue (by mail or whatever),
you can compute the hashes for this repository, and if the hash for tip
is one you know you can trust, then you can trust the entire history in
that repository.

This is what is meant when people say that you cannot change the history
without people noticing: if I edit some changeset and give the whole
repository to you, then your hash calculation (by 'hg verify') would end
up different from what it was before my edit.

Finally, if you want to give people reason to trust a particular
revision hash, then you can sign it with your public key and post the
signature somewhere public. The GPG extension automates this:

  http://www.selenic.com/mercurial/wiki/index.cgi/GpgExtension

> What happens if I pull updates from a rogue repository that corrupted
> or removed some of my files? Sure I can check out versions prior to
> this "bad commit" but ideally I'd like to undo pulling those changes.
> What would one do in such a case? I assume that Hg lets you obliterate
> entire commits as opposed to individual files...?

Pulling in changeset cannot modify the changesets you have already
stored in your repository, only add new ones. To undo a pull you will
simply want to remove the newly added changesets. The 'hg strip' (from
the MQ extension) will let you remove a changeset (including any
children) from your repository.

-- 
Martin Geisler

VIFF (Virtual Ideal Functionality Framework) brings easy and efficient
SMPC (Secure Multi-Party Computation) to Python. See: http://viff.dk/.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 188 bytes
Desc: not available
Url : http://selenic.com/pipermail/mercurial/attachments/20080318/e41b49ca/attachment.pgp 


More information about the Mercurial mailing list