Fossil

Check-in [f9f7cf5684]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The autosync setting understands values like "on", "off", "true", and "false" in addition to 0 and 1. Updates to the documentation.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f9f7cf5684d27947eb49283af145f86c214cc119
User & Date: drh 2007-11-24 02:45:39.000
Context
2007-11-24
14:06
Documentation updates. check-in: 6680679c2e user: drh tags: trunk
02:45
The autosync setting understands values like "on", "off", "true", and "false" in addition to 0 and 1. Updates to the documentation. check-in: f9f7cf5684 user: drh tags: trunk
2007-11-23
23:06
Fix a bug in the default header. check-in: 13732d495d user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
948
949
950
951
952
953
954













955
956
957
958
959
960
961
  db_begin_transaction();
  db_multi_exec("REPLACE INTO %sconfig(name,value) VALUES(%Q,%d)",
                globalFlag ? "global_" : "", zName, value);
  if( globalFlag && g.repositoryOpen ){
    db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
  }
  db_end_transaction(0);













}
char *db_lget(const char *zName, char *zDefault){
  return db_text((char*)zDefault,
                 "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset(const char *zName, const char *zValue){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);







>
>
>
>
>
>
>
>
>
>
>
>
>







948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
  db_begin_transaction();
  db_multi_exec("REPLACE INTO %sconfig(name,value) VALUES(%Q,%d)",
                globalFlag ? "global_" : "", zName, value);
  if( globalFlag && g.repositoryOpen ){
    db_multi_exec("DELETE FROM config WHERE name=%Q", zName);
  }
  db_end_transaction(0);
}
int db_get_boolean(const char *zName, int dflt){
  static const char *azOn[] = { "on", "yes", "true", "1" };
  static const char *azOff[] = { "off", "no", "false", "0" };
  int i;
  char *zVal = db_get(zName, dflt ? "on" : "off");
  for(i=0; i<sizeof(azOn)/sizeof(azOn[0]); i++){
    if( strcmp(zVal,azOn[i])==0 ) return 1;
  }
  for(i=0; i<sizeof(azOff)/sizeof(azOff[0]); i++){
    if( strcmp(zVal,azOff[i])==0 ) return 0;
  }
  return dflt;
}
char *db_lget(const char *zName, char *zDefault){
  return db_text((char*)zDefault,
                 "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset(const char *zName, const char *zValue){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%Q)", zName, zValue);
Changes to src/sync.c.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
** If the respository is configured for autosyncing, then do an
** autosync.  This will be a pull if the argument is true or a push
** if the argument is false.  Return true if the autosync is done
** and false if autosync is not requested for the current repository.
*/
int autosync(int pullFlag){
  const char *zUrl;
  if( db_get_int("autosync", 0)==0 ){
    return 0;
  }
  zUrl = db_get("last-sync-url", 0);
  if( zUrl==0 ){
    return 0;  /* No default server */
  }
  url_parse(zUrl);







|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
** If the respository is configured for autosyncing, then do an
** autosync.  This will be a pull if the argument is true or a push
** if the argument is false.  Return true if the autosync is done
** and false if autosync is not requested for the current repository.
*/
int autosync(int pullFlag){
  const char *zUrl;
  if( db_get_boolean("autosync", 0)==0 ){
    return 0;
  }
  zUrl = db_get("last-sync-url", 0);
  if( zUrl==0 ){
    return 0;  /* No default server */
  }
  url_parse(zUrl);
Changes to www/concepts.html.
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
or through a central server.  Changes can "push" from the local
repository into a remote repository.  Or changes can "pull" from a
remote repository into a local repository.  Or one can do a "sync"
which is a shortcut for doing both a push and a pull at the same time.
Fossil also has the concept of "cloning".  A "clone" is like a "pull",
except that instead of beginning with an existing local repository,
a clone begins with nothing and creates a new local repository that
is a replicate of a remote repository.</p>

<p>Communication between repositories is via HTTP.  Remote
repositories are identified by URL.  You can also point a webbrowser
at a repository and get human-readable status, history, and tracking
information about the project.</p>

<h3>2.1 Identification Of Artifacts</h3>







|







73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
or through a central server.  Changes can "push" from the local
repository into a remote repository.  Or changes can "pull" from a
remote repository into a local repository.  Or one can do a "sync"
which is a shortcut for doing both a push and a pull at the same time.
Fossil also has the concept of "cloning".  A "clone" is like a "pull",
except that instead of beginning with an existing local repository,
a clone begins with nothing and creates a new local repository that
is a duplicate of a remote repository.</p>

<p>Communication between repositories is via HTTP.  Remote
repositories are identified by URL.  You can also point a webbrowser
at a repository and get human-readable status, history, and tracking
information about the project.</p>

<h3>2.1 Identification Of Artifacts</h3>
138
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
you look at a "timeline" of changes in fossil, the UUID associated
with each check-in or commit is really just the UUID of the
manifest for that baseline.</p>

<p>Fossil automatically generates a manifest whenever you "commit" 
a new baseline.  So this is not something that you, the developer,
need to worry with.  The format of a manifest is intentionally
designed to be simple to parse, however, so that if
you want to read and interpret a manifest, either by hand or
with a script, that is easy to do.</p>


<p>In addition to identifying all files in the baseline, a
manifest also contains a check-in comment, the date and time
when the baseline was established, who created the baseline,
and links to other baselines from which the current baseline
is derived.  There is also a couple of checksums used to verify
the integrity of the baseline.  And the whole manifest might







|

|
>







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
you look at a "timeline" of changes in fossil, the UUID associated
with each check-in or commit is really just the UUID of the
manifest for that baseline.</p>

<p>Fossil automatically generates a manifest whenever you "commit" 
a new baseline.  So this is not something that you, the developer,
need to worry with.  The format of a manifest is intentionally
designed to be simple to parse, so that if
you want to read and interpret a manifest, either by hand or
with a script, that is easy to do.  But you will probably never
need to do so.</p>

<p>In addition to identifying all files in the baseline, a
manifest also contains a check-in comment, the date and time
when the baseline was established, who created the baseline,
and links to other baselines from which the current baseline
is derived.  There is also a couple of checksums used to verify
the integrity of the baseline.  And the whole manifest might
273
274
275
276
277
278
279
































280
281
282
283
284
285
286
</p></li>

<li><p>
Repeat all of the above until you have generated great software.
</p></li>
</ol>

































<h2>5.0 Setting Up A Fossil Server</h2>

<p>With other configuration management software, setting up a server is
a lot of work and normally takes time, patience, and a lot of system
knowledge.  Fossil is designed to avoid this frustration.  Setting up
a server with fossil is ridiculously easy.  You have three options:</p>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
</p></li>

<li><p>
Repeat all of the above until you have generated great software.
</p></li>
</ol>

<h3>4.1 Variations</h3>

<p>The <b>settings</b> lets you view and modify various operating
properties of fossil.  Among the available settings is "autosync"
mode.  When autosync is enabled, the push and pull of content from
your local server is largely automated.  Whenever you use the <b>update</b>
command, fossil first does a <b>pull</b> to see if other users have
perhaps added new baselines to the central repository.  When you
<b>commit</b>, fossil also does a <b>pull</b> and issues a warning
if your check-in would cause a fork.  After a <b>commit</b>, fossil
automatically does a <b>push</b> to send your changes up to the
central server.</p>

<p>With autosync enabled, fossil works like
<a href="http://www.nongnu.org/cvs/">CVS</a> or 
<a href="http://subversion.tigris.org/">Subversion</a>.
When autosync disabled, fossil works more like
<a href="http://monotone.ca/">Monotone</a>, 
<a href="http://git.or.cz">GIT</a>, or
<a href="http://www.selenic.com/mercurial/wiki/">Mercurial</a>.
The fun thing about fossil is that it will work either
way, depending on your needs of the moment.  You can freely switch
between these operating modes using commands like:</p>

<blockquote>
<b>fossil setting autosync off<br />
fossil setting autosync on</b>
</blockquote>

<p>For additional information about autosync and other settings
using the <b>help</b> command.</p>

<h2>5.0 Setting Up A Fossil Server</h2>

<p>With other configuration management software, setting up a server is
a lot of work and normally takes time, patience, and a lot of system
knowledge.  Fossil is designed to avoid this frustration.  Setting up
a server with fossil is ridiculously easy.  You have three options:</p>

Changes to www/fileformat.html.
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
188
189

































190
191
192

193
194
195
196
197
198
199
200


201

202
203
204
205
206
207

208

209
210

211


212
213


214
215
216
217
218
219

220
221
222







223
224

225
226






227
228
229
<html>
<head>
<title>Fossil File Format</title>
</head>
<body bgcolor="white">
<p>[ <a href="index.html">Index</a> ]</p>
<hr>
<h1 align="center">
Fossil File Formats
</h1>

<p>
The global state of a fossil repository is determined by an unordered
set of files.  Some files are used to represent wiki pages, trouble tickets,
and the special "manifest" file has a specific and well-defined format.


Other files are just data.  Files can be text or binary.
</p>

<p>
Each file in the repository is named by its SHA1 hash.
No prefixes or meta information is added to a file before
its hash is computed.  The name of a file in the repository
is exactly the same SHA1 hash that is computed by sha1sum 
on the file as it exists in your source tree.</p>

<p>
Some files have a particular format which qualifies them
as "manifests".  A manifest assigns filenames to a subset
of the files in the repository, in order to provide a
snapshot of the state of the project at a point in time.
Each manifest file corresponds to a version or baseline
of the project.
</p>

<h2>1.0 The Manifest File</h2>

<p>
Any file in the repository that follows the syntactic rules
of a manifest is a manifest.  Note that a manifest can
be both a real manifest and also a content file, though this
is rare.
</p>

<p>
A manifest is a line-oriented text file.  Newline characters
(ASCII 0x0a) separate lines.  Each line begins with a single

character "line type".  Zero or more arguments may follow
the line type.  All arguments are separated from each other
and from the line-type character by a single space
character.  There is no surplus white space between arguments
and no leading or trailing whitespace except for the newline 
character that acts as the line separator.
</p>

<p>
All lines of the manifest occur in strict sorted lexicographical order.
No line may be duplicated.
The entire manifest file may be PGP clear-signed, but otherwise it
may contain no additional text or data beyond what is described here.
</p>

<p>
Allowed lines in the manifest are as follows:
</p>

<blockquote>
<b>C</b> <i>checkin-comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br>
<b>F</b> <i>filename</i> <i>SHA1-hash</i><br>
<b>P</b> <i>SHA1-hash</i>+<br>
<b>R</b> <i>repository-checksum</i><br>
<b>U</b> <i>user-login</i><br>
<b>Z</b> <i>manifest-checksum</i>
</blockquote>

<p>
A manifest must have exactly one C-line.  The sole argument to
the C-line is a check-in comment that describes the baseline that
the manifest defines.  The check-in comment is text.  The following
escape sequences are applied to the text:
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73).  A
newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E).  A backslash 
(ASCII 0x5C) is represented as two backslashes "\\".  Apart from
space and newline, no other whitespace characters are allowed in
the check-in comment.  Nor are any unprintable characters allowed
in the comment.
</p>

<p>
A manifest must have exactly one D-line.  The sole argument to
the D-line is a date-time stamp in the ISO8601 format.  The
date and time should be in coordinated universal time (UTC).
The format is:
</p>

<blockquote>
<i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i>
</blockquote>

<p>
A manifest has zero or more F-lines.  Each F-line defines a file
(other than the manifest itself) which is part of the baseline that
the manifest defines.  There are two arguments.  The first argment
is the pathname of the file in the baseline relative to the root
of the project file hierarchy.  No ".." or "." directories are allowed
within the filename.  Space characters are escaped as in C-line
comment text.  Backslash characters and newlines are not allowed
within filenames.  The directory separator character is a forward
slash (ASCII 0x2F).  The second argument to the F-line is the
full 40-character hexadecimal SHA1 hash of the file content.  
Upper-case letters ABCDEF are used for the higher digits of the
hexadecimal.
</p>

<p>
A manifest has zero or one P-lines.  Most manifests have one P-line.
The P-line has a varying number of arguments that
defines other manifests from which the current manifest
is derived.  Each argument is an 40-character lowercase 
hexadecimal SHA1 of the predecessor manifest.  All arguments
to the P-line must be unique to that line.
The first predecessor is the manifests direct ancestor.
Other arguments define manifests with which the first was
merged to yield the current manifest.  Most manifests have
a P-line with a single argument.  The first manifest in the
project has no ancestors and thus has no P-line.
</p>

<p>
A manifest may optionally have a single R-line.  The R-line has
a single argument which is the MD5 checksum of all files in 
the baseline except the manifest itself.  The checksum is expressed
as 32-characters of lowercase hexadecimal.   The checksum is
computed as follows:  For each file in the baseline (except for
the manifest itself) in strict sorted lexicographical order, 
take the pathname of the file relative to the root of the
repository, append a single space (ASCII 0x20), the
size of the file in ASCII decimal, a single newline
character (ASCII 0x0A), and the complete text of the file.
Compute the MD5 checksum of the the result.
</p>

<p>
Each manifest has a single U-line.  The argument to the U-line is
the login of the user who created the manifest.  The login name
is encoded using the same character escapes as is used for the
check-in comment argument to the C-line.
</p>

<p>
A manifest has an option Z-line as its last line.  The argument
to the Z-line is a 32-character lowercase hexadecimal MD5 hash
of all prior lines of the manifest up to and including the newline 
character that immediately preceeds the "Z".  The Z-line is just
a sanity check to prove that the manifest is well-formed and
consistent.
</p>

<h2>2.0 Clusters</h2>

<p>
A cluster is a file that states the existance of other files.
Clusters are used during repository synchronization to help 
reduce network traffic.
</p>

<p>
Clusters follow a syntax that is very similar to manifests.
A Cluster is a line-oriented text file.  Newline characters
(ASCII 0x0a) separate lines.  Each line begins with a single
character "line type".  Zero or more arguments may follow
the line type.  All arguments are separated from each other
and from the line-type character by a single space
character.  There is no surplus white space between arguments
and no leading or trailing whitespace except for the newline 
character that acts as the line separator.
All lines of a cluter occur in strict sorted lexicographical order.
No line may be duplicated.
The cluster may not contain additional text or data beyond 
what is described here.

</p>

<p>
Allowed lines in the cluster are as follows:
</p>

<blockquote>
<b>M</b> <i>uuid</i>
<b>Z</b> <i>manifest-checksum</i>

































</blockquote>

<p>

A cluster contains one or more "M" lines followed by a single "Z"
line.  Each M line has a single argument which is the UUID of 
another record in the repository.  The Z line work exactly like
the Z line of a manifest.  The argument to the Z line is the
lower-case hexadecimal representation of the MD5 checksum of all
prior lines in the cluster.
</p>





<h2>3.0 Trouble Tickets</h2>

<p>
Each trouble ticket is a file in the repository and appears in
a manifest for every baseline in which the ticket exists.
Trouble tickets occur in a specific subdirectory of the file

heirarchy.  The name of the subdirectory that contains tickets

is part of the local state of each repository.  The filename
of each trouble ticket has a ".tkt" suffix.  The trouble ticket

has a particular file format defined below.


</p>



<i>To be continued...</i>

<h2>4.0 Wiki Pages</h2>

<p>
Each wiki is a file in the repository and appears in

a manifest for every baseline in which that wiki page exists.
Wiki pages occur in a specific subdirectory of the file
heirarchy.  The name of the subdirectory that contains wiki pages







is part of the local state of each repository.  The filename
of each wiki page has a ".wiki" suffix.  The base name of

the file is the name of the wiki page.  The wiki pages
have a particular file format defined below.






</p>

<i>To be continued...</i>













|
|
>
>
|



|
|
|




|

|

|



|


|







|
>
|
|
|


|



|
|
|




|













|
|











|
|









|




|


|
|
<
|



|
|



|
|


|
|



|













|


|



|
|

|







|







|
|
|
|


|
|
|


>



|




|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



>
|
<
|
<
<
<
|

>
>

>
|
|
<
<
|
|
>
|
>
|
|
>
|
>
>
|

>
>
|



|
|
>
|
|
|
>
>
>
>
>
>
>
|
|
>
|
<
>
>
>
>
>
>
|

<
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

231



232
233
234
235
236
237
238
239


240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283

<html>
<head>
<title>Fossil File Format</title>
</head>
<body bgcolor="white">
<p>[ <a href="index.html">Index</a> ]</p>
<hr>
<h1 align="center">
Fossil File Formats
</h1>

<p>
The global state of a fossil repository is determined by an unordered
set of files.  A file in fossil is called an "artifact".
An artifact might be a source code file, the text of a wiki page,
part of a trouble ticket, or one of several special control artifacts
used to show the relationships between other artifacts within the
project.  Artifacts can be text or binary.
</p>

<p>
Each artifact in the repository is named by its SHA1 hash.
No prefixes or meta information is added to a artifact before
its hash is computed.  The name of a artifact in the repository
is exactly the same SHA1 hash that is computed by sha1sum 
on the file as it exists in your source tree.</p>

<p>
Some artifacts have a particular format which qualifies them
as "manifests".  A manifest assigns filenames to a subset
of the artifacts in the repository, in order to provide a
snapshot of the state of the project at a point in time.
Each manifest corresponds to a version or baseline
of the project.
</p>

<h2>1.0 The Manifest</h2>

<p>
Any artifact in the repository that follows the syntactic rules
of a manifest is a manifest.  Note that a manifest can
be both a real manifest and also a content file, though this
is rare.
</p>

<p>
A manifest is a line-oriented text file.  Newline characters
(ASCII 0x0a) separate lines.  Each line is called a "card".
Each card begins with a single
character "card type".  Zero or more arguments may follow
the card type.  All arguments are separated from each other
and from the card-type character by a single space
character.  There is no surplus white space between arguments
and no leading or trailing whitespace except for the newline 
character that acts as the card separator.
</p>

<p>
All cards of the manifest occur in strict sorted lexicographical order.
No card may be duplicated.
The entire manifest may be PGP clear-signed, but otherwise it
may contain no additional text or data beyond what is described here.
</p>

<p>
Allowed cards in the manifest are as follows:
</p>

<blockquote>
<b>C</b> <i>checkin-comment</i><br>
<b>D</b> <i>time-and-date-stamp</i><br>
<b>F</b> <i>filename</i> <i>SHA1-hash</i><br>
<b>P</b> <i>SHA1-hash</i>+<br>
<b>R</b> <i>repository-checksum</i><br>
<b>U</b> <i>user-login</i><br>
<b>Z</b> <i>manifest-checksum</i>
</blockquote>

<p>
A manifest must have exactly one C-card.  The sole argument to
the C-card is a check-in comment that describes the check-in that
the manifest defines.  The check-in comment is text.  The following
escape sequences are applied to the text:
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73).  A
newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E).  A backslash 
(ASCII 0x5C) is represented as two backslashes "\\".  Apart from
space and newline, no other whitespace characters are allowed in
the check-in comment.  Nor are any unprintable characters allowed
in the comment.
</p>

<p>
A manifest must have exactly one D-card.  The sole argument to
the D-card is a date-time stamp in the ISO8601 format.  The
date and time should be in coordinated universal time (UTC).
The format is:
</p>

<blockquote>
<i>YYYY</i><b>-</b><i>MM</i><b>-</b><i>DD</i><b>T</b><i>HH</i><b>:</b><i>MM</i><b>:</b><i>SS</i>
</blockquote>

<p>
A manifest has zero or more F-cards.  Each F-card defines a file
(other than the manifest itself) which is part of the baseline that
the manifest defines.  There are two arguments.  The first argment
is the pathname of the file in the baseline relative to the root
of the project file hierarchy.  No ".." or "." directories are allowed
within the filename.  Space characters are escaped as in C-card
comment text.  Backslash characters and newlines are not allowed
within filenames.  The directory separator character is a forward
slash (ASCII 0x2F).  The second argument to the F-card is the
full 40-character lower-case hexadecimal SHA1 hash of the content

artifact.
</p>

<p>
A manifest has zero or one P-cards.  Most manifests have one P-card.
The P-card has a varying number of arguments that
defines other manifests from which the current manifest
is derived.  Each argument is an 40-character lowercase 
hexadecimal SHA1 of the predecessor manifest.  All arguments
to the P-card must be unique to that line.
The first predecessor is the direct ancestor of the manifest.
Other arguments define manifests with which the first was
merged to yield the current manifest.  Most manifests have
a P-card with a single argument.  The first manifest in the
project has no ancestors and thus has no P-card.
</p>

<p>
A manifest may optionally have a single R-card.  The R-card has
a single argument which is the MD5 checksum of all files in 
the baseline except the manifest itself.  The checksum is expressed
as 32-characters of lowercase hexadecimal.   The checksum is
computed as follows:  For each file in the baseline (except for
the manifest itself) in strict sorted lexicographical order, 
take the pathname of the file relative to the root of the
repository, append a single space (ASCII 0x20), the
size of the file in ASCII decimal, a single newline
character (ASCII 0x0A), and the complete text of the file.
Compute the MD5 checksum of the the result.
</p>

<p>
Each manifest has a single U-card.  The argument to the U-card is
the login of the user who created the manifest.  The login name
is encoded using the same character escapes as is used for the
check-in comment argument to the C-card.
</p>

<p>
A manifest has an option Z-card as its last line.  The argument
to the Z-card is a 32-character lowercase hexadecimal MD5 hash
of all prior lines of the manifest up to and including the newline 
character that immediately preceeds the "Z".  The Z-card is just
a sanity check to prove that the manifest is well-formed and
consistent.
</p>

<h2>2.0 Clusters</h2>

<p>
A cluster is a artifact that declares the existance of other artifacts.
Clusters are used during repository synchronization to help 
reduce network traffic.
</p>

<p>
Clusters follow a syntax that is very similar to manifests.
A Cluster is a line-oriented text file.  Newline characters
(ASCII 0x0a) separate the artifact into cards.  Each card begins with a single
character "card type".  Zero or more arguments may follow
the card type.  All arguments are separated from each other
and from the card-type character by a single space
character.  There is no surplus white space between arguments
and no leading or trailing whitespace except for the newline 
character that acts as the card separator.
All cards of a cluter occur in strict sorted lexicographical order.
No card may be duplicated.
The cluster may not contain additional text or data beyond 
what is described here.
Unlike manifests, clusters are never PGP signed.
</p>

<p>
Allowed cards in the cluster are as follows:
</p>

<blockquote>
<b>M</b> <i>uuid</i>
<b>Z</b> <i>checksum</i>
</blockquote>

<p>
A cluster contains one or more "M" cards followed by a single "Z"
line.  Each M card has a single argument which is the UUID of 
another artifact in the repository.  The Z card work exactly like
the Z card of a manifest.  The argument to the Z card is the
lower-case hexadecimal representation of the MD5 checksum of all
prior cards in the cluster.  Note that the Z card is required
on a cluster.
</p>


<h2>3.0 Control Artifacts</h2>

<p>
Control artifacts are used to assign properties to other artifacts
within the repository.  The basic format of a control artifact is
the same as a manifest or cluster.  A control artifact is a text
files divided into cards by newline characters.  Each card has a
single-character card type followed by arguments.  Spaces separate
the card type and the arguments.  No surplus whitespace is allowed.
All cards must occur in strict lexigraphical order.
</p>

<p>
Allowed cards in a control artifact are as follows:
</p>

<blockquote>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>T</b> <i>tag-name  uuid  ?value?</i><br />
<b>Z</b> <i>checksum</i><br />
</blockquote>

<p>
A control artifact must have one D card and one Z card and
one or more or more T cards.  No other cards or other text is

allowed in a control artifact.  Control artifacts might be PGP



clearsigned.</p>

<p>The D card and the Z card of a control artifact are the same
as in a manifest.</p>

<p>The T card represents a "tag" or property that is applied to
some other artifact.  The T card has two or three values.  The
second argument is the 40 character lowercase UUID of the artifact


to which the tag is to be applied. The
first value is the tag name.  The first character of the tag
is either "+", "-", or "*".  A "+" means the tag should be added
to the artifact.  The "-" means the tag should be removed.
The "*" character means the tag should be added to the artifact
and all direct decendents (but not branches) of the artifact.
The optional third argument is the value of the tag.  A tag
without a value is considered to be a boolean.</p>

<p>When two or more tags with the same name are applied to the
same artifact, the tag with the latest (most recent) date is
used.</p>

<p>Some tags have special meaning.  The "comment" tag when applied
to a baseline will override the check-in comment of that baseline
for display purposes.</p>

<h2>4.0 Wiki Pages</h2>

<p>A wiki page is an artifact in a format similar to manifests,
clusters, and control artifacts.  The artifact is divided into
cards by newline characters.  The format of each card is as in
manifests, clusters, and control artifacts.  Wiki artifacts accept
the following card types:</p>

<blockquote>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>L</b> <i>wiki-title</i><br />
<b>U</b> <i>user-name</i><br />
<b>W</b> <i>size</i> \n <i>text</i> \n<br />
<b>Z</b> <i>checksum</i>
</blockquote>


<h2>5.0 Ticket Changes</h2>


<blockquote>
<b>D</b> <i>time-and-date-stamp</i><br />
<b>J</b> ?<b>+</b>?<i>name value</i><br />
<b>K</b> <i>ticket-uuid</i><br />
<b>U</b> <i>user-name</i><br />
<b>Z</b> <i>checksum</i>
</blockquote>