-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathREADME.changesets
156 lines (117 loc) · 6.39 KB
/
README.changesets
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
Information about the changeset branch integration
==================================================
Between versions 0.14 and 0.15 monotone underwent a major
reorganization of its fundamental data structures. This means pre-0.14
and post-0.15 versions of monotone are strictly incompatible:
- databases are incompatible
- network service is incompatible
Unfortunately we were simply not able to make transparent
interoperation possible. Too much changed. However, it is possible to
*migrate* from the pre-0.14 representation to the post-0.15
representation. The migration is slightly lossy, but it is the best we
are able to provide.
What changed
============
The change added two new objects to the vocabulary of monotone:
- changesets
- revisions
They are both text objects, like manifests, which monotone reads and
writes for its own benefit. Revisions are, like manifests, also hashed
with SHA1 to produce revision IDs. Changesets are not hashed, because
they generally do not appear outside of revisions.
These two new objects replace three previous objects: patch sets,
rename certs, and ancestry certs. Now information about renaming and
patch application is stored in changesets, and information about
ancestry is stored in revisions. Obviously these objects store the
information slightly differently than their predecessors. See the next
section for motivation.
The observable affect for the end user is moderate: most monotone
commands work "the way they used to", except that now they take
revision IDs where they used to take manifest IDs. Don't worry about
this too much: every revision has a reference to a specific manifest
as well, revision IDs still always refer to a specific "tree state",
they just happen to refer to a bit *more* than that as well, as we'll
see.
Why it changed
==============
The old objects were buggy. There were a bunch of subtle and
difficult-to-fix problems with the way we were representing ancestry
and renames before:
- renames of directories had to be inferred, and this could fail.
- nontrivial forms of rename chaining didn't work, and it wasn't clear
that they could be made to work treating renames as we did:
a->b and b->a
a->b and c->a
a/b->a/c and a->d (depending on order)
- you could have multiple *irreconcilable* rename certs attached
to the same manifest edge, and this would cause monotone to crash.
- ancestry could form cycles, if you ever returned to a previous
manifest state.
- ancestry could accidentally jump from one "historical thread" to
another if you happened to pass through the same manifest state;
two branches acquiring the same state would always look like a
merge even when it was a coincidence.
- it wasn't clear what monotone should do if you assigned different
trust to existant branch, ancestry, and rename certs.
These problems were with us for quite a while, even if you didn't
encounter them. The changes at 0.15 fix the whole family of bugs by
removing the troubling abstractions and replacing them with more
robust ones. In particular:
- Unlike ancestry certs, revisions are chained. Each revision
contains *as part of its content* the revision IDs of its
predecessor revisions, so there can never be a loop in the
graph. Each new point in the graph gets a new, previously-unseen
ID.
- Revisions are not subject to trust evaluation, they are
*statements of fact*. They happen to be stating a fact which
describes an entire historical chain of events, but there is only
one trust evaluation: branch membership. The evaluation of branch
membership covers the entire history of events described by a
revision.
- Changesets have much stronger reasoning facilities about
overlapping renames, directory renames, etc. They actually break
down into a "simultaneous rearrangement of inodes" abstraction, in
memory, including directories as first class objects. This
abstraction has a clear algebra for concatenation, inversion and
parallel merger.
How do I migrate?
=================
Before you start any of this, make a backup of the database. All the
world's warnings about making backups seem to go un-heeded, but
seriously, it's just a single "cp" command. How lazy can you get?
$ cp mydatabase.db mydatabase.db.pre-changesets
Please be sure to do so. After backing up, there are three required
steps (and one optional step) to the migration. The first step is to
dump and reload your database, to get something that the new version
of SQLite can read. Note that you need to keep your old version of
monotone around at least long enough to perform this step:
$ old-monotone --db=mydatabase.db db dump > mydatabase.dump
$ monotone --db=new-mydatabase.db db load < mydatabase.dump
The next step is the usual "thing you do when the SQL schema changes":
$ monotone --db=new-mydatabase.db db migrate
Then there is the new step: telling monotone to convert its old
representation of manifests to changesets. It will synthesize a lot of
new changesets based on what it can find in your database. The newly
synthesized information is a *slightly lossy* version of the
information already found in your database. It is lossy in the
following respects:
- All existing rename/edit events will be degraded to delete/add
events
- All existing manifest certs will be reissued as revision certs,
but signed *with your public key*. All previous RSA-key-identity
information is thereby lost.
Assuming you're prepared to live with this loss, the next step is to run
a special, otherwise undocumented "changesetification" command:
$ monotone --db=new-mydatabase.db db changesetify
This should build the new changeset and revision structure and issue
all the necessary certs. It will therefore take a while on a large
database. It will not, however, delete the old manifest certs: the new
version of monotone will simply ignore them, but they continue to
exist in your database, should you wish to recover some of their
information for forensic purposes in the future. If you truly wish to
remove all manifest certs as well (they are all subsumed by revision
certs now, anyways) you can issue one further command:
$ monotone --db=new-mydatabase.db db execute "delete from manifest_certs"
This will purge the manifest_certs table of all its entries, but as we
said this step is purely optional. No harm will come from old manifest
certs remaining in your database.