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
|
* Write-once store of files identified by globally-unique names
(e.g. hashes or UUIDs).
Simplest option is to just dump them in a directory.
Optionally do delta-compression between similar/related files; or
build this on top of deltas.
* Tree manifests/inventories which say which files should be assembled at
particular points to build a tree. These too can be stored indexed
by hash.
- Reconstruct a revision by pulling out the manifest and then all
the individual files.
- Manipulate working copy of inventory by add/mv/remove/commands.
* Retrieve deltas
- Calculate diffs between two file versions, just by getting them
from the store.
- Retrieve deltas between any two revisions: requires looking for
changes to the structure of the tree, and then text changes for
anything inside it.
- Deltas may be either stored or calculated on demand. They can be
put in the store just indexed by the from and to manifest id.
- Calculate diff between a previous revision and the working copy.
* Commit and retrieve revisions
- Revisions hold metadata (date, committer, comment, optional
parents, merged patches), and a pointer to the inventory.
- Stored in a write-once store.
* Branch holds a linear history of revisions.
- This is mostly redundant; we could just remember the current base
revision and walk backwards from there. But it still seems
possibly useful to hold; we can check that the two are always
consistent.
(This suggests that we actually *could* do ``switch`` if we
really wanted to, by replacing the revision history and head
revision. But I don't think it's a good idea.)
- Can add a new revision to the end.
- By indexing into this can translate between 0-based revision
numbers and revision ids.
- By walking through and looking at revision dates can find
revisions in a particular date range.
* Calculations on branch histories:
- Find if one branch is a prefix of another.
- Find the latest common ancestor of another.
* Three-way merge between revisions
- Resolve shape of directory
- Then resolve textual conflicts
* Pull/push changes when they perfectly match
- Possible when the destination is a prefix of the source
- Just move all revisions, manifests and texts across, and
* Merge all changes from one branch into another
* Signatures applied to revisions
- There is a separable module for checking a signature: this is
passed the claimed author, changeset, date. This needs to fetch
an appropriate key, decide if it is trusted to correspond to that
author, is not revoked, etc.
- If it is unknown, untrusted, revoked, etc, that is reported.
Depending on a paranoia level it may cause the operation to
abort.
|