Fossil SCM

Improved file format documentation. Added information on the attachment artifact. Redefine the A-card (which has not previously been used). Update the Manifest object to store attachment artifacts.

drh 2010-03-16 15:38 trunk
Commit d5a4e41c81280c86e9922785713294ef78083065
2 files changed +57 -92 +237 -85
+57 -92
--- src/manifest.c
+++ src/manifest.c
@@ -37,67 +37,56 @@
3737
#define CFTYPE_MANIFEST 1
3838
#define CFTYPE_CLUSTER 2
3939
#define CFTYPE_CONTROL 3
4040
#define CFTYPE_WIKI 4
4141
#define CFTYPE_TICKET 5
42
-
43
-/*
44
-** Mode parameter values
45
-*/
46
-#define CFMODE_READ 1
47
-#define CFMODE_APPEND 2
48
-#define CFMODE_WRITE 3
42
+#define CFTYPE_ATTACHMENT 6
4943
5044
/*
5145
** A parsed manifest or cluster.
5246
*/
5347
struct Manifest {
5448
Blob content; /* The original content blob */
55
- int type; /* Type of file */
56
- int mode; /* Access mode */
57
- char *zComment; /* Decoded comment */
58
- double rDate; /* Time in the "D" line */
59
- char *zUser; /* Name of the user */
60
- char *zRepoCksum; /* MD5 checksum of the baseline content */
61
- char *zWiki; /* Text of the wiki page */
62
- char *zWikiTitle; /* Name of the wiki page */
63
- char *zTicketUuid; /* UUID for a ticket */
64
- int nFile; /* Number of F lines */
49
+ int type; /* Type of artifact. One of CFTYPE_xxxxx */
50
+ char *zComment; /* Decoded comment. The C card. */
51
+ double rDate; /* Date and time from D card. 0.0 if no D card. */
52
+ char *zUser; /* Name of the user from the U card. */
53
+ char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
54
+ char *zWiki; /* Text of the wiki page. W card. */
55
+ char *zWikiTitle; /* Name of the wiki page. L card. */
56
+ char *zTicketUuid; /* UUID for a ticket. K card. */
57
+ char *zAttachName; /* Filename of an attachment. A card. */
58
+ char *zAttachSrc; /* UUID of document being attached. A card. */
59
+ char *zAttachTarget; /* Ticket or wiki that attachment applies to. A card */
60
+ int nFile; /* Number of F cards */
6561
int nFileAlloc; /* Slots allocated in aFile[] */
6662
struct {
6763
char *zName; /* Name of a file */
6864
char *zUuid; /* UUID of the file */
6965
char *zPerm; /* File permissions */
7066
char *zPrior; /* Prior name if the name was changed */
7167
int iRename; /* index of renamed name in prior/next manifest */
72
- } *aFile;
73
- int nParent; /* Number of parents */
68
+ } *aFile; /* One entry for each F card */
69
+ int nParent; /* Number of parents. */
7470
int nParentAlloc; /* Slots allocated in azParent[] */
75
- char **azParent; /* UUIDs of parents */
71
+ char **azParent; /* UUIDs of parents. One for each P card argument */
7672
int nCChild; /* Number of cluster children */
7773
int nCChildAlloc; /* Number of closts allocated in azCChild[] */
78
- char **azCChild; /* UUIDs of referenced objects in a cluster */
79
- int nTag; /* Number of T lines */
74
+ char **azCChild; /* UUIDs of referenced objects in a cluster. M cards */
75
+ int nTag; /* Number of T Cards */
8076
int nTagAlloc; /* Slots allocated in aTag[] */
8177
struct {
8278
char *zName; /* Name of the tag */
8379
char *zUuid; /* UUID that the tag is applied to */
8480
char *zValue; /* Value if the tag is really a property */
85
- } *aTag;
86
- int nField; /* Number of J lines */
81
+ } *aTag; /* One for each T card */
82
+ int nField; /* Number of J cards */
8783
int nFieldAlloc; /* Slots allocated in aField[] */
8884
struct {
8985
char *zName; /* Key or field name */
9086
char *zValue; /* Value of the field */
91
- } *aField;
92
- int nAttach; /* Number of A lines */
93
- int nAttachAlloc; /* Slots allocated in aAttach[] */
94
- struct {
95
- char *zUuid; /* UUID of the attachment */
96
- char *zName; /* Name of the attachment */
97
- char *zDesc; /* Description of the attachment */
98
- } *aAttach;
87
+ } *aField; /* One for each J card */
9988
};
10089
#endif
10190
10291
10392
/*
@@ -108,11 +97,10 @@
10897
free(p->aFile);
10998
free(p->azParent);
11099
free(p->azCChild);
111100
free(p->aTag);
112101
free(p->aField);
113
- free(p->aAttach);
114102
memset(p, 0, sizeof(*p));
115103
}
116104
117105
/*
118106
** Parse a blob into a Manifest object. The Manifest object
@@ -178,44 +166,42 @@
178166
cPrevType = z[0];
179167
seenHeader = 1;
180168
if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
181169
switch( z[0] ){
182170
/*
183
- ** A <uuid> <filename> <description>
171
+ ** A (+|-)<filename> target source
184172
**
185173
** Identifies an attachment to either a wiki page or a ticket.
186174
** <uuid> is the artifact that is the attachment.
187175
*/
188176
case 'A': {
189
- char *zName, *zUuid, *zDesc;
177
+ char *zName, *zTarget, *zSrc;
190178
md5sum_step_text(blob_buffer(&line), blob_size(&line));
191179
if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
192180
if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
193181
if( blob_token(&line, &a3)==0 ) goto manifest_syntax_error;
194
- zUuid = blob_terminate(&a1);
195
- zName = blob_terminate(&a2);
196
- zDesc = blob_terminate(&a3);
197
- if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
198
- if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
182
+ if( p->zAttachName!=0 ) goto manifest_syntax_error;
183
+ zName = blob_terminate(&a1);
184
+ zTarget = blob_terminate(&a2);
185
+ zSrc = blob_terminate(&a3);
199186
defossilize(zName);
200
- if( !file_is_simple_pathname(zName) ){
201
- goto manifest_syntax_error;
202
- }
203
- defossilize(zDesc);
204
- if( p->nAttach>=p->nAttachAlloc ){
205
- p->nAttachAlloc = p->nAttachAlloc*2 + 10;
206
- p->aAttach = realloc(p->aAttach,
207
- p->nAttachAlloc*sizeof(p->aAttach[0]) );
208
- if( p->aAttach==0 ) fossil_panic("out of memory");
209
- }
210
- i = p->nAttach++;
211
- p->aAttach[i].zUuid = zUuid;
212
- p->aAttach[i].zName = zName;
213
- p->aAttach[i].zDesc = zDesc;
214
- if( i>0 && strcmp(p->aAttach[i-1].zUuid, zUuid)>=0 ){
215
- goto manifest_syntax_error;
216
- }
187
+ if( zName[0]!='+' && zName[0]!='-' ){
188
+ goto manifest_syntax_error;
189
+ }
190
+ if( !file_is_simple_pathname(&zName[1]) ){
191
+ goto manifest_syntax_error;
192
+ }
193
+ defossilize(zTarget);
194
+ if( (blob_size(&a2)!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
195
+ && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
196
+ goto manifest_syntax_error;
197
+ }
198
+ if( blob_size(&a3)!=UUID_SIZE ) goto manifest_syntax_error;
199
+ if( !validate16(zSrc, UUID_SIZE) ) goto manifest_syntax_error;
200
+ p->zAttachName = zName;
201
+ p->zAttachSrc = zSrc;
202
+ p->zAttachTarget = zTarget;
217203
break;
218204
}
219205
220206
/*
221207
** C <comment>
@@ -247,33 +233,10 @@
247233
if( p->rDate!=0.0 ) goto manifest_syntax_error;
248234
if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
249235
if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
250236
zDate = blob_terminate(&a1);
251237
p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate);
252
- break;
253
- }
254
-
255
- /*
256
- ** E <mode>
257
- **
258
- ** Access mode. <mode> can be one of "read", "append",
259
- ** or "write".
260
- */
261
- case 'E': {
262
- md5sum_step_text(blob_buffer(&line), blob_size(&line));
263
- if( p->mode!=0 ) goto manifest_syntax_error;
264
- if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
265
- if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
266
- if( blob_eq(&a1, "write") ){
267
- p->mode = CFMODE_WRITE;
268
- }else if( blob_eq(&a1, "append") ){
269
- p->mode = CFMODE_APPEND;
270
- }else if( blob_eq(&a1, "read") ){
271
- p->mode = CFMODE_READ;
272
- }else{
273
- goto manifest_syntax_error;
274
- }
275238
break;
276239
}
277240
278241
/*
279242
** F <filename> <uuid> ?<permissions>? ?<old-name>?
@@ -608,72 +571,74 @@
608571
if( p->nFile>0 || p->zRepoCksum!=0 ){
609572
if( p->nCChild>0 ) goto manifest_syntax_error;
610573
if( p->rDate==0.0 ) goto manifest_syntax_error;
611574
if( p->nField>0 ) goto manifest_syntax_error;
612575
if( p->zTicketUuid ) goto manifest_syntax_error;
613
- if( p->nAttach>0 ) goto manifest_syntax_error;
614576
if( p->zWiki ) goto manifest_syntax_error;
615577
if( p->zWikiTitle ) goto manifest_syntax_error;
616578
if( p->zTicketUuid ) goto manifest_syntax_error;
579
+ if( p->zAttachName ) goto manifest_syntax_error;
617580
p->type = CFTYPE_MANIFEST;
618581
}else if( p->nCChild>0 ){
619582
if( p->rDate>0.0 ) goto manifest_syntax_error;
620583
if( p->zComment!=0 ) goto manifest_syntax_error;
621584
if( p->zUser!=0 ) goto manifest_syntax_error;
622585
if( p->nTag>0 ) goto manifest_syntax_error;
623586
if( p->nParent>0 ) goto manifest_syntax_error;
624
- if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
625587
if( p->nField>0 ) goto manifest_syntax_error;
626588
if( p->zTicketUuid ) goto manifest_syntax_error;
627
- if( p->nAttach>0 ) goto manifest_syntax_error;
628589
if( p->zWiki ) goto manifest_syntax_error;
629590
if( p->zWikiTitle ) goto manifest_syntax_error;
591
+ if( p->zAttachName ) goto manifest_syntax_error;
630592
if( !seenZ ) goto manifest_syntax_error;
631593
p->type = CFTYPE_CLUSTER;
632594
}else if( p->nField>0 ){
633595
if( p->rDate==0.0 ) goto manifest_syntax_error;
634
- if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
635596
if( p->zWiki ) goto manifest_syntax_error;
636597
if( p->zWikiTitle ) goto manifest_syntax_error;
637598
if( p->nCChild>0 ) goto manifest_syntax_error;
638599
if( p->nTag>0 ) goto manifest_syntax_error;
639600
if( p->zTicketUuid==0 ) goto manifest_syntax_error;
640601
if( p->zUser==0 ) goto manifest_syntax_error;
602
+ if( p->zAttachName ) goto manifest_syntax_error;
641603
if( !seenZ ) goto manifest_syntax_error;
642604
p->type = CFTYPE_TICKET;
643605
}else if( p->zWiki!=0 ){
644606
if( p->rDate==0.0 ) goto manifest_syntax_error;
645
- if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
646607
if( p->nCChild>0 ) goto manifest_syntax_error;
647608
if( p->nTag>0 ) goto manifest_syntax_error;
648609
if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
649610
if( p->zWikiTitle==0 ) goto manifest_syntax_error;
611
+ if( p->zAttachName ) goto manifest_syntax_error;
650612
if( !seenZ ) goto manifest_syntax_error;
651613
p->type = CFTYPE_WIKI;
652614
}else if( p->nTag>0 ){
653615
if( p->rDate<=0.0 ) goto manifest_syntax_error;
654
- if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
655616
if( p->nParent>0 ) goto manifest_syntax_error;
656
- if( p->nAttach>0 ) goto manifest_syntax_error;
657
- if( p->nField>0 ) goto manifest_syntax_error;
658
- if( p->zWiki ) goto manifest_syntax_error;
659617
if( p->zWikiTitle ) goto manifest_syntax_error;
660618
if( p->zTicketUuid ) goto manifest_syntax_error;
619
+ if( p->zAttachName ) goto manifest_syntax_error;
661620
if( !seenZ ) goto manifest_syntax_error;
662621
p->type = CFTYPE_CONTROL;
663
- }else{
622
+ }else if( p->zAttachName ){
664623
if( p->nCChild>0 ) goto manifest_syntax_error;
665624
if( p->rDate==0.0 ) goto manifest_syntax_error;
625
+ if( p->zTicketUuid ) goto manifest_syntax_error;
626
+ if( p->zWikiTitle ) goto manifest_syntax_error;
627
+ p->type = CFTYPE_ATTACHMENT;
628
+ }else{
629
+ if( p->nCChild>0 ) goto manifest_syntax_error;
630
+ if( p->rDate<=0.0 ) goto manifest_syntax_error;
631
+ if( p->nParent>0 ) goto manifest_syntax_error;
666632
if( p->nField>0 ) goto manifest_syntax_error;
667633
if( p->zTicketUuid ) goto manifest_syntax_error;
668
- if( p->nAttach>0 ) goto manifest_syntax_error;
669634
if( p->zWiki ) goto manifest_syntax_error;
670635
if( p->zWikiTitle ) goto manifest_syntax_error;
671636
if( p->zTicketUuid ) goto manifest_syntax_error;
637
+ if( p->zAttachName ) goto manifest_syntax_error;
672638
p->type = CFTYPE_MANIFEST;
673639
}
674
-
675640
md5sum_init();
676641
return 1;
677642
678643
manifest_syntax_error:
679644
/*fprintf(stderr, "Manifest error on line %i\n", lineNo);fflush(stderr);*/
680645
--- src/manifest.c
+++ src/manifest.c
@@ -37,67 +37,56 @@
37 #define CFTYPE_MANIFEST 1
38 #define CFTYPE_CLUSTER 2
39 #define CFTYPE_CONTROL 3
40 #define CFTYPE_WIKI 4
41 #define CFTYPE_TICKET 5
42
43 /*
44 ** Mode parameter values
45 */
46 #define CFMODE_READ 1
47 #define CFMODE_APPEND 2
48 #define CFMODE_WRITE 3
49
50 /*
51 ** A parsed manifest or cluster.
52 */
53 struct Manifest {
54 Blob content; /* The original content blob */
55 int type; /* Type of file */
56 int mode; /* Access mode */
57 char *zComment; /* Decoded comment */
58 double rDate; /* Time in the "D" line */
59 char *zUser; /* Name of the user */
60 char *zRepoCksum; /* MD5 checksum of the baseline content */
61 char *zWiki; /* Text of the wiki page */
62 char *zWikiTitle; /* Name of the wiki page */
63 char *zTicketUuid; /* UUID for a ticket */
64 int nFile; /* Number of F lines */
 
 
65 int nFileAlloc; /* Slots allocated in aFile[] */
66 struct {
67 char *zName; /* Name of a file */
68 char *zUuid; /* UUID of the file */
69 char *zPerm; /* File permissions */
70 char *zPrior; /* Prior name if the name was changed */
71 int iRename; /* index of renamed name in prior/next manifest */
72 } *aFile;
73 int nParent; /* Number of parents */
74 int nParentAlloc; /* Slots allocated in azParent[] */
75 char **azParent; /* UUIDs of parents */
76 int nCChild; /* Number of cluster children */
77 int nCChildAlloc; /* Number of closts allocated in azCChild[] */
78 char **azCChild; /* UUIDs of referenced objects in a cluster */
79 int nTag; /* Number of T lines */
80 int nTagAlloc; /* Slots allocated in aTag[] */
81 struct {
82 char *zName; /* Name of the tag */
83 char *zUuid; /* UUID that the tag is applied to */
84 char *zValue; /* Value if the tag is really a property */
85 } *aTag;
86 int nField; /* Number of J lines */
87 int nFieldAlloc; /* Slots allocated in aField[] */
88 struct {
89 char *zName; /* Key or field name */
90 char *zValue; /* Value of the field */
91 } *aField;
92 int nAttach; /* Number of A lines */
93 int nAttachAlloc; /* Slots allocated in aAttach[] */
94 struct {
95 char *zUuid; /* UUID of the attachment */
96 char *zName; /* Name of the attachment */
97 char *zDesc; /* Description of the attachment */
98 } *aAttach;
99 };
100 #endif
101
102
103 /*
@@ -108,11 +97,10 @@
108 free(p->aFile);
109 free(p->azParent);
110 free(p->azCChild);
111 free(p->aTag);
112 free(p->aField);
113 free(p->aAttach);
114 memset(p, 0, sizeof(*p));
115 }
116
117 /*
118 ** Parse a blob into a Manifest object. The Manifest object
@@ -178,44 +166,42 @@
178 cPrevType = z[0];
179 seenHeader = 1;
180 if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
181 switch( z[0] ){
182 /*
183 ** A <uuid> <filename> <description>
184 **
185 ** Identifies an attachment to either a wiki page or a ticket.
186 ** <uuid> is the artifact that is the attachment.
187 */
188 case 'A': {
189 char *zName, *zUuid, *zDesc;
190 md5sum_step_text(blob_buffer(&line), blob_size(&line));
191 if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
192 if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
193 if( blob_token(&line, &a3)==0 ) goto manifest_syntax_error;
194 zUuid = blob_terminate(&a1);
195 zName = blob_terminate(&a2);
196 zDesc = blob_terminate(&a3);
197 if( blob_size(&a1)!=UUID_SIZE ) goto manifest_syntax_error;
198 if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
199 defossilize(zName);
200 if( !file_is_simple_pathname(zName) ){
201 goto manifest_syntax_error;
202 }
203 defossilize(zDesc);
204 if( p->nAttach>=p->nAttachAlloc ){
205 p->nAttachAlloc = p->nAttachAlloc*2 + 10;
206 p->aAttach = realloc(p->aAttach,
207 p->nAttachAlloc*sizeof(p->aAttach[0]) );
208 if( p->aAttach==0 ) fossil_panic("out of memory");
209 }
210 i = p->nAttach++;
211 p->aAttach[i].zUuid = zUuid;
212 p->aAttach[i].zName = zName;
213 p->aAttach[i].zDesc = zDesc;
214 if( i>0 && strcmp(p->aAttach[i-1].zUuid, zUuid)>=0 ){
215 goto manifest_syntax_error;
216 }
217 break;
218 }
219
220 /*
221 ** C <comment>
@@ -247,33 +233,10 @@
247 if( p->rDate!=0.0 ) goto manifest_syntax_error;
248 if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
249 if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
250 zDate = blob_terminate(&a1);
251 p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate);
252 break;
253 }
254
255 /*
256 ** E <mode>
257 **
258 ** Access mode. <mode> can be one of "read", "append",
259 ** or "write".
260 */
261 case 'E': {
262 md5sum_step_text(blob_buffer(&line), blob_size(&line));
263 if( p->mode!=0 ) goto manifest_syntax_error;
264 if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
265 if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
266 if( blob_eq(&a1, "write") ){
267 p->mode = CFMODE_WRITE;
268 }else if( blob_eq(&a1, "append") ){
269 p->mode = CFMODE_APPEND;
270 }else if( blob_eq(&a1, "read") ){
271 p->mode = CFMODE_READ;
272 }else{
273 goto manifest_syntax_error;
274 }
275 break;
276 }
277
278 /*
279 ** F <filename> <uuid> ?<permissions>? ?<old-name>?
@@ -608,72 +571,74 @@
608 if( p->nFile>0 || p->zRepoCksum!=0 ){
609 if( p->nCChild>0 ) goto manifest_syntax_error;
610 if( p->rDate==0.0 ) goto manifest_syntax_error;
611 if( p->nField>0 ) goto manifest_syntax_error;
612 if( p->zTicketUuid ) goto manifest_syntax_error;
613 if( p->nAttach>0 ) goto manifest_syntax_error;
614 if( p->zWiki ) goto manifest_syntax_error;
615 if( p->zWikiTitle ) goto manifest_syntax_error;
616 if( p->zTicketUuid ) goto manifest_syntax_error;
 
617 p->type = CFTYPE_MANIFEST;
618 }else if( p->nCChild>0 ){
619 if( p->rDate>0.0 ) goto manifest_syntax_error;
620 if( p->zComment!=0 ) goto manifest_syntax_error;
621 if( p->zUser!=0 ) goto manifest_syntax_error;
622 if( p->nTag>0 ) goto manifest_syntax_error;
623 if( p->nParent>0 ) goto manifest_syntax_error;
624 if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
625 if( p->nField>0 ) goto manifest_syntax_error;
626 if( p->zTicketUuid ) goto manifest_syntax_error;
627 if( p->nAttach>0 ) goto manifest_syntax_error;
628 if( p->zWiki ) goto manifest_syntax_error;
629 if( p->zWikiTitle ) goto manifest_syntax_error;
 
630 if( !seenZ ) goto manifest_syntax_error;
631 p->type = CFTYPE_CLUSTER;
632 }else if( p->nField>0 ){
633 if( p->rDate==0.0 ) goto manifest_syntax_error;
634 if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
635 if( p->zWiki ) goto manifest_syntax_error;
636 if( p->zWikiTitle ) goto manifest_syntax_error;
637 if( p->nCChild>0 ) goto manifest_syntax_error;
638 if( p->nTag>0 ) goto manifest_syntax_error;
639 if( p->zTicketUuid==0 ) goto manifest_syntax_error;
640 if( p->zUser==0 ) goto manifest_syntax_error;
 
641 if( !seenZ ) goto manifest_syntax_error;
642 p->type = CFTYPE_TICKET;
643 }else if( p->zWiki!=0 ){
644 if( p->rDate==0.0 ) goto manifest_syntax_error;
645 if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
646 if( p->nCChild>0 ) goto manifest_syntax_error;
647 if( p->nTag>0 ) goto manifest_syntax_error;
648 if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
649 if( p->zWikiTitle==0 ) goto manifest_syntax_error;
 
650 if( !seenZ ) goto manifest_syntax_error;
651 p->type = CFTYPE_WIKI;
652 }else if( p->nTag>0 ){
653 if( p->rDate<=0.0 ) goto manifest_syntax_error;
654 if( p->zRepoCksum!=0 ) goto manifest_syntax_error;
655 if( p->nParent>0 ) goto manifest_syntax_error;
656 if( p->nAttach>0 ) goto manifest_syntax_error;
657 if( p->nField>0 ) goto manifest_syntax_error;
658 if( p->zWiki ) goto manifest_syntax_error;
659 if( p->zWikiTitle ) goto manifest_syntax_error;
660 if( p->zTicketUuid ) goto manifest_syntax_error;
 
661 if( !seenZ ) goto manifest_syntax_error;
662 p->type = CFTYPE_CONTROL;
663 }else{
664 if( p->nCChild>0 ) goto manifest_syntax_error;
665 if( p->rDate==0.0 ) goto manifest_syntax_error;
 
 
 
 
 
 
 
666 if( p->nField>0 ) goto manifest_syntax_error;
667 if( p->zTicketUuid ) goto manifest_syntax_error;
668 if( p->nAttach>0 ) goto manifest_syntax_error;
669 if( p->zWiki ) goto manifest_syntax_error;
670 if( p->zWikiTitle ) goto manifest_syntax_error;
671 if( p->zTicketUuid ) goto manifest_syntax_error;
 
672 p->type = CFTYPE_MANIFEST;
673 }
674
675 md5sum_init();
676 return 1;
677
678 manifest_syntax_error:
679 /*fprintf(stderr, "Manifest error on line %i\n", lineNo);fflush(stderr);*/
680
--- src/manifest.c
+++ src/manifest.c
@@ -37,67 +37,56 @@
37 #define CFTYPE_MANIFEST 1
38 #define CFTYPE_CLUSTER 2
39 #define CFTYPE_CONTROL 3
40 #define CFTYPE_WIKI 4
41 #define CFTYPE_TICKET 5
42 #define CFTYPE_ATTACHMENT 6
 
 
 
 
 
 
43
44 /*
45 ** A parsed manifest or cluster.
46 */
47 struct Manifest {
48 Blob content; /* The original content blob */
49 int type; /* Type of artifact. One of CFTYPE_xxxxx */
50 char *zComment; /* Decoded comment. The C card. */
51 double rDate; /* Date and time from D card. 0.0 if no D card. */
52 char *zUser; /* Name of the user from the U card. */
53 char *zRepoCksum; /* MD5 checksum of the baseline content. R card. */
54 char *zWiki; /* Text of the wiki page. W card. */
55 char *zWikiTitle; /* Name of the wiki page. L card. */
56 char *zTicketUuid; /* UUID for a ticket. K card. */
57 char *zAttachName; /* Filename of an attachment. A card. */
58 char *zAttachSrc; /* UUID of document being attached. A card. */
59 char *zAttachTarget; /* Ticket or wiki that attachment applies to. A card */
60 int nFile; /* Number of F cards */
61 int nFileAlloc; /* Slots allocated in aFile[] */
62 struct {
63 char *zName; /* Name of a file */
64 char *zUuid; /* UUID of the file */
65 char *zPerm; /* File permissions */
66 char *zPrior; /* Prior name if the name was changed */
67 int iRename; /* index of renamed name in prior/next manifest */
68 } *aFile; /* One entry for each F card */
69 int nParent; /* Number of parents. */
70 int nParentAlloc; /* Slots allocated in azParent[] */
71 char **azParent; /* UUIDs of parents. One for each P card argument */
72 int nCChild; /* Number of cluster children */
73 int nCChildAlloc; /* Number of closts allocated in azCChild[] */
74 char **azCChild; /* UUIDs of referenced objects in a cluster. M cards */
75 int nTag; /* Number of T Cards */
76 int nTagAlloc; /* Slots allocated in aTag[] */
77 struct {
78 char *zName; /* Name of the tag */
79 char *zUuid; /* UUID that the tag is applied to */
80 char *zValue; /* Value if the tag is really a property */
81 } *aTag; /* One for each T card */
82 int nField; /* Number of J cards */
83 int nFieldAlloc; /* Slots allocated in aField[] */
84 struct {
85 char *zName; /* Key or field name */
86 char *zValue; /* Value of the field */
87 } *aField; /* One for each J card */
 
 
 
 
 
 
 
88 };
89 #endif
90
91
92 /*
@@ -108,11 +97,10 @@
97 free(p->aFile);
98 free(p->azParent);
99 free(p->azCChild);
100 free(p->aTag);
101 free(p->aField);
 
102 memset(p, 0, sizeof(*p));
103 }
104
105 /*
106 ** Parse a blob into a Manifest object. The Manifest object
@@ -178,44 +166,42 @@
166 cPrevType = z[0];
167 seenHeader = 1;
168 if( blob_token(&line, &token)!=1 ) goto manifest_syntax_error;
169 switch( z[0] ){
170 /*
171 ** A (+|-)<filename> target source
172 **
173 ** Identifies an attachment to either a wiki page or a ticket.
174 ** <uuid> is the artifact that is the attachment.
175 */
176 case 'A': {
177 char *zName, *zTarget, *zSrc;
178 md5sum_step_text(blob_buffer(&line), blob_size(&line));
179 if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
180 if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
181 if( blob_token(&line, &a3)==0 ) goto manifest_syntax_error;
182 if( p->zAttachName!=0 ) goto manifest_syntax_error;
183 zName = blob_terminate(&a1);
184 zTarget = blob_terminate(&a2);
185 zSrc = blob_terminate(&a3);
 
186 defossilize(zName);
187 if( zName[0]!='+' && zName[0]!='-' ){
188 goto manifest_syntax_error;
189 }
190 if( !file_is_simple_pathname(&zName[1]) ){
191 goto manifest_syntax_error;
192 }
193 defossilize(zTarget);
194 if( (blob_size(&a2)!=UUID_SIZE || !validate16(zTarget, UUID_SIZE))
195 && !wiki_name_is_wellformed((const unsigned char *)zTarget) ){
196 goto manifest_syntax_error;
197 }
198 if( blob_size(&a3)!=UUID_SIZE ) goto manifest_syntax_error;
199 if( !validate16(zSrc, UUID_SIZE) ) goto manifest_syntax_error;
200 p->zAttachName = zName;
201 p->zAttachSrc = zSrc;
202 p->zAttachTarget = zTarget;
 
203 break;
204 }
205
206 /*
207 ** C <comment>
@@ -247,33 +233,10 @@
233 if( p->rDate!=0.0 ) goto manifest_syntax_error;
234 if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
235 if( blob_token(&line, &a2)!=0 ) goto manifest_syntax_error;
236 zDate = blob_terminate(&a1);
237 p->rDate = db_double(0.0, "SELECT julianday(%Q)", zDate);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238 break;
239 }
240
241 /*
242 ** F <filename> <uuid> ?<permissions>? ?<old-name>?
@@ -608,72 +571,74 @@
571 if( p->nFile>0 || p->zRepoCksum!=0 ){
572 if( p->nCChild>0 ) goto manifest_syntax_error;
573 if( p->rDate==0.0 ) goto manifest_syntax_error;
574 if( p->nField>0 ) goto manifest_syntax_error;
575 if( p->zTicketUuid ) goto manifest_syntax_error;
 
576 if( p->zWiki ) goto manifest_syntax_error;
577 if( p->zWikiTitle ) goto manifest_syntax_error;
578 if( p->zTicketUuid ) goto manifest_syntax_error;
579 if( p->zAttachName ) goto manifest_syntax_error;
580 p->type = CFTYPE_MANIFEST;
581 }else if( p->nCChild>0 ){
582 if( p->rDate>0.0 ) goto manifest_syntax_error;
583 if( p->zComment!=0 ) goto manifest_syntax_error;
584 if( p->zUser!=0 ) goto manifest_syntax_error;
585 if( p->nTag>0 ) goto manifest_syntax_error;
586 if( p->nParent>0 ) goto manifest_syntax_error;
 
587 if( p->nField>0 ) goto manifest_syntax_error;
588 if( p->zTicketUuid ) goto manifest_syntax_error;
 
589 if( p->zWiki ) goto manifest_syntax_error;
590 if( p->zWikiTitle ) goto manifest_syntax_error;
591 if( p->zAttachName ) goto manifest_syntax_error;
592 if( !seenZ ) goto manifest_syntax_error;
593 p->type = CFTYPE_CLUSTER;
594 }else if( p->nField>0 ){
595 if( p->rDate==0.0 ) goto manifest_syntax_error;
 
596 if( p->zWiki ) goto manifest_syntax_error;
597 if( p->zWikiTitle ) goto manifest_syntax_error;
598 if( p->nCChild>0 ) goto manifest_syntax_error;
599 if( p->nTag>0 ) goto manifest_syntax_error;
600 if( p->zTicketUuid==0 ) goto manifest_syntax_error;
601 if( p->zUser==0 ) goto manifest_syntax_error;
602 if( p->zAttachName ) goto manifest_syntax_error;
603 if( !seenZ ) goto manifest_syntax_error;
604 p->type = CFTYPE_TICKET;
605 }else if( p->zWiki!=0 ){
606 if( p->rDate==0.0 ) goto manifest_syntax_error;
 
607 if( p->nCChild>0 ) goto manifest_syntax_error;
608 if( p->nTag>0 ) goto manifest_syntax_error;
609 if( p->zTicketUuid!=0 ) goto manifest_syntax_error;
610 if( p->zWikiTitle==0 ) goto manifest_syntax_error;
611 if( p->zAttachName ) goto manifest_syntax_error;
612 if( !seenZ ) goto manifest_syntax_error;
613 p->type = CFTYPE_WIKI;
614 }else if( p->nTag>0 ){
615 if( p->rDate<=0.0 ) goto manifest_syntax_error;
 
616 if( p->nParent>0 ) goto manifest_syntax_error;
 
 
 
617 if( p->zWikiTitle ) goto manifest_syntax_error;
618 if( p->zTicketUuid ) goto manifest_syntax_error;
619 if( p->zAttachName ) goto manifest_syntax_error;
620 if( !seenZ ) goto manifest_syntax_error;
621 p->type = CFTYPE_CONTROL;
622 }else if( p->zAttachName ){
623 if( p->nCChild>0 ) goto manifest_syntax_error;
624 if( p->rDate==0.0 ) goto manifest_syntax_error;
625 if( p->zTicketUuid ) goto manifest_syntax_error;
626 if( p->zWikiTitle ) goto manifest_syntax_error;
627 p->type = CFTYPE_ATTACHMENT;
628 }else{
629 if( p->nCChild>0 ) goto manifest_syntax_error;
630 if( p->rDate<=0.0 ) goto manifest_syntax_error;
631 if( p->nParent>0 ) goto manifest_syntax_error;
632 if( p->nField>0 ) goto manifest_syntax_error;
633 if( p->zTicketUuid ) goto manifest_syntax_error;
 
634 if( p->zWiki ) goto manifest_syntax_error;
635 if( p->zWikiTitle ) goto manifest_syntax_error;
636 if( p->zTicketUuid ) goto manifest_syntax_error;
637 if( p->zAttachName ) goto manifest_syntax_error;
638 p->type = CFTYPE_MANIFEST;
639 }
 
640 md5sum_init();
641 return 1;
642
643 manifest_syntax_error:
644 /*fprintf(stderr, "Manifest error on line %i\n", lineNo);fflush(stderr);*/
645
+237 -85
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -1,26 +1,23 @@
11
<title>Fossil File Formats</title>
22
<h1 align="center">
33
Fossil File Formats
44
</h1>
55
6
-<p>The global state of a fossil repository is kept simple so that it can
6
+The global state of a fossil repository is kept simple so that it can
77
endure in useful form for decades or centuries.
88
A fossil repository is intended to be readable,
9
-searchable, and extensible by people not yet born.</p>
9
+searchable, and extensible by people not yet born.
1010
11
-<p>
1211
The global state of a fossil repository is an unordered
1312
set of <i>artifacts</i>.
1413
An artifact might be a source code file, the text of a wiki page,
1514
part of a trouble ticket, or one of several special control artifacts
1615
used to show the relationships between other artifacts within the
1716
project. Each artifact is normally represented on disk as a separate
1817
file. Artifacts can be text or binary.
19
-</p>
2018
21
-<p>
2219
In addition to the global state,
2320
each fossil repository also contains local state.
2421
The local state consists of web-page formatting
2522
preferences, authorized users, ticket display and reporting formats,
2623
and so forth. The global state is shared in common among all
@@ -29,82 +26,73 @@
2926
The local state is not versioned and is not synchronized
3027
with the global state.
3128
The local state is not composed of artifacts and is not intended to be enduring.
3229
This document is concerned with global state only. Local state is only
3330
mentioned here in order to distinguish it from global state.
34
-</p>
3531
36
-<p>
3732
Each artifact in the repository is named by its SHA1 hash.
3833
No prefixes or meta information is added to a artifact before
3934
its hash is computed. The name of a artifact in the repository
4035
is exactly the same SHA1 hash that is computed by sha1sum
4136
on the file as it exists in your source tree.</p>
4237
43
-<p>
4438
Some artifacts have a particular format which gives them special
45
-meaning to fossil. Fossil recognizes:</p>
39
+meaning to fossil. Fossil recognizes:
4640
4741
<ul>
48
-<li> Manifests </li>
49
-<li> Clusters </li>
50
-<li> Control Artifacts </li>
51
-<li> Wiki Pages </li>
52
-<li> Ticket Changes </li>
42
+<li> [#manifest | Manifests] </li>
43
+<li> [#cluster | Clusters] </li>
44
+<li> [#ctrl | Control Artifacts] </li>
45
+<li> [#wikichng | Wiki Pages] </li>
46
+<li> [#tktchng | Ticket Changes] </li>
47
+<li> [#artifact | Artifacts] </li>
5348
</ul>
5449
55
-<p>These five artifact types are described in the sequel.</p>
50
+These five artifact types are described in the sequel.
5651
57
-<p>In the current implementation (as of 2009-01-25) the artifacts that
52
+In the current implementation (as of 2009-01-25) the artifacts that
5853
make up a fossil repository are stored in in as delta- and zlib-compressed
5954
blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
6055
is an implementation detail and might change in a future release. For
6156
the purpose of this article "file format" means the format of the artifacts,
6257
not how the artifacts are stored on disk. It is the artifact format that
6358
is intended to be enduring. The specifics of how artifacts are stored on
6459
disk, though stable, is not intended to live as long as the
65
-artifact format.</p>
60
+artifact format.
6661
62
+<a name="manifest"></a>
6763
<h2>1.0 The Manifest</h2>
6864
69
-<p>A manifest defines a check-in or version of the project
65
+A manifest defines a check-in or version of the project
7066
source tree. The manifest contains a list of artifacts for
7167
each file in the project and the corresponding filenames, as
7268
well as information such as parent check-ins, the name of the
7369
programmer who created the check-in, the date and time when
7470
the check-in was created, and any check-in comments associated
75
-with the check-in.</p>
71
+with the check-in.
7672
77
-<p>
7873
Any artifact in the repository that follows the syntactic rules
7974
of a manifest is a manifest. Note that a manifest can
8075
be both a real manifest and also a content file, though this
8176
is rare.
82
-</p>
8377
84
-<p>
8578
A manifest is a text file. Newline characters
8679
(ASCII 0x0a) separate the file into "cards".
8780
Each card begins with a single
8881
character "card type". Zero or more arguments may follow
8982
the card type. All arguments are separated from each other
9083
and from the card-type character by a single space
9184
character. There is no surplus white space between arguments
9285
and no leading or trailing whitespace except for the newline
9386
character that acts as the card separator.
94
-</p>
9587
96
-<p>
9788
All cards of the manifest occur in strict sorted lexicographical order.
9889
No card may be duplicated.
9990
The entire manifest may be PGP clear-signed, but otherwise it
10091
may contain no additional text or data beyond what is described here.
101
-</p>
10292
103
-<p>
10493
Allowed cards in the manifest are as follows:
105
-</p>
10694
10795
<blockquote>
10896
<b>C</b> <i>checkin-comment</i><br>
10997
<b>D</b> <i>time-and-date-stamp</i><br>
11098
<b>F</b> <i>filename</i> <i>SHA1-hash</i> <i>permissions</i> <i>old-name</i><br>
@@ -113,11 +101,10 @@
113101
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name <b>*</b> ?value?</i><br>
114102
<b>U</b> <i>user-login</i><br>
115103
<b>Z</b> <i>manifest-checksum</i>
116104
</blockquote>
117105
118
-<p>
119106
A manifest must have exactly one C-card. The sole argument to
120107
the C-card is a check-in comment that describes the check-in that
121108
the manifest defines. The check-in comment is text. The following
122109
escape sequences are applied to the text:
123110
A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
@@ -124,24 +111,20 @@
124111
newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
125112
(ASCII 0x5C) is represented as two backslashes "\\". Apart from
126113
space and newline, no other whitespace characters are allowed in
127114
the check-in comment. Nor are any unprintable characters allowed
128115
in the comment.
129
-</p>
130116
131
-<p>
132117
A manifest must have exactly one D-card. The sole argument to
133118
the D-card is a date-time stamp in the ISO8601 format. The
134119
date and time should be in coordinated universal time (UTC).
135120
The format is:
136
-</p>
137121
138122
<blockquote>
139123
<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>
140124
</blockquote>
141125
142
-<p>
143126
A manifest has zero or more F-cards. Each F-card defines a file
144127
(other than the manifest itself) which is part of the check-in that
145128
the manifest defines. There are two, three, or four arguments.
146129
The first argument
147130
is the pathname of the file in the check-in relative to the root
@@ -157,13 +140,11 @@
157140
always readable and writable. This can be expressed by "w" permission
158141
if desired but is optional.
159142
The optional 4th argument is the name of the same file as it existed in
160143
the parent check-in. If the name of the file is unchanged from its
161144
parent, then the 4th argument is omitted.
162
-</p>
163145
164
-<p>
165146
A manifest has zero or one P-cards. Most manifests have one P-card.
166147
The P-card has a varying number of arguments that
167148
defines other manifests from which the current manifest
168149
is derived. Each argument is an 40-character lowercase
169150
hexadecimal SHA1 of the predecessor manifest. All arguments
@@ -171,13 +152,11 @@
171152
The first predecessor is the direct ancestor of the manifest.
172153
Other arguments define manifests with which the first was
173154
merged to yield the current manifest. Most manifests have
174155
a P-card with a single argument. The first manifest in the
175156
project has no ancestors and thus has no P-card.
176
-</p>
177157
178
-<p>
179158
A manifest may optionally have a single R-card. The R-card has
180159
a single argument which is the MD5 checksum of all files in
181160
the check-in except the manifest itself. The checksum is expressed
182161
as 32-characters of lowercase hexadecimal. The checksum is
183162
computed as follows: For each file in the check-in (except for
@@ -185,13 +164,11 @@
185164
take the pathname of the file relative to the root of the
186165
repository, append a single space (ASCII 0x20), the
187166
size of the file in ASCII decimal, a single newline
188167
character (ASCII 0x0A), and the complete text of the file.
189168
Compute the MD5 checksum of the the result.
190
-</p>
191169
192
-<p>
193170
A manifest might contain one or more T-cards used to set tags or
194171
properties on the check-in. The format of the T-card is the same as
195172
described in <i>Control Artifacts</i> section below, except that the
196173
second argument is the single characcter "<b>*</b>" instead of an
197174
artifact ID. The <b>*</b> in place of the artifact ID indicates that
@@ -199,42 +176,35 @@
199176
possible to encode the current artifact ID as part of an artifact,
200177
since the act of inserting the artifact ID would change the artifact ID,
201178
hence a <b>*</b> is used to represent "self". T-cards are typically
202179
added to manifests in order to set the <b>branch</b> property and a
203180
symbolic name when the check-in is intended to start a new branch.
204
-</p>
205181
206
-<p>
207182
Each manifest has a single U-card. The argument to the U-card is
208183
the login of the user who created the manifest. The login name
209184
is encoded using the same character escapes as is used for the
210185
check-in comment argument to the C-card.
211
-</p>
212186
213
-<p>
214187
A manifest has an option Z-card as its last line. The argument
215188
to the Z-card is a 32-character lowercase hexadecimal MD5 hash
216189
of all prior lines of the manifest up to and including the newline
217190
character that immediately precedes the "Z". The Z-card is just
218191
a sanity check to prove that the manifest is well-formed and
219192
consistent.
220
-</p>
221193
222
-<p>A sample manifest from Fossil itself can be seen
194
+A sample manifest from Fossil itself can be seen
223195
[/artifact/28987096ac | here].
224196
197
+<a name="cluster"></a>
225198
<h2>2.0 Clusters</h2>
226199
227
-<p>
228200
A cluster is a artifact that declares the existence of other artifacts.
229201
Clusters are used during repository synchronization to help
230202
reduce network traffic. As such, clusters are an optimization and
231203
may be removed from a repository without loss or damage to the
232204
underlying project code.
233
-</p>
234205
235
-<p>
236206
Clusters follow a syntax that is very similar to manifests.
237207
A Cluster is a line-oriented text file. Newline characters
238208
(ASCII 0x0a) separate the artifact into cards. Each card begins with a single
239209
character "card type". Zero or more arguments may follow
240210
the card type. All arguments are separated from each other
@@ -245,67 +215,58 @@
245215
All cards of a cluster occur in strict sorted lexicographical order.
246216
No card may be duplicated.
247217
The cluster may not contain additional text or data beyond
248218
what is described here.
249219
Unlike manifests, clusters are never PGP signed.
250
-</p>
251220
252
-<p>
253221
Allowed cards in the cluster are as follows:
254
-</p>
255222
256223
<blockquote>
257224
<b>M</b> <i>artifact-id</i><br />
258225
<b>Z</b> <i>checksum</i>
259226
</blockquote>
260227
261
-<p>
262228
A cluster contains one or more "M" cards followed by a single "Z"
263229
line. Each M card has a single argument which is the artifact ID of
264230
another artifact in the repository. The Z card work exactly like
265231
the Z card of a manifest. The argument to the Z card is the
266232
lower-case hexadecimal representation of the MD5 checksum of all
267233
prior cards in the cluster. Note that the Z card is required
268234
on a cluster.
269
-</p>
270235
271
-<p>An example cluster from Fossil can be seen
272
-[/artifact/d03dbdd73a2a8 | here].</p>
236
+An example cluster from Fossil can be seen
237
+[/artifact/d03dbdd73a2a8 | here].
273238
274
-
239
+<a name="ctrl"></a>
275240
<h2>3.0 Control Artifacts</h2>
276241
277
-<p>
278242
Control artifacts are used to assign properties to other artifacts
279243
within the repository. The basic format of a control artifact is
280244
the same as a manifest or cluster. A control artifact is a text
281245
files divided into cards by newline characters. Each card has a
282246
single-character card type followed by arguments. Spaces separate
283247
the card type and the arguments. No surplus whitespace is allowed.
284248
All cards must occur in strict lexigraphical order.
285
-</p>
286249
287
-<p>
288250
Allowed cards in a control artifact are as follows:
289
-</p>
290251
291252
<blockquote>
292253
<b>D</b> <i>time-and-date-stamp</i><br />
293254
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
255
+<b>U</b> <i>user-name</i><br />
294256
<b>Z</b> <i>checksum</i><br />
295257
</blockquote>
296258
297
-<p>
298259
A control artifact must have one D card and one Z card and
299260
one or more T cards. No other cards or other text is
300261
allowed in a control artifact. Control artifacts might be PGP
301
-clearsigned.</p>
262
+clearsigned.
302263
303
-<p>The D card and the Z card of a control artifact are the same
304
-as in a manifest.</p>
264
+The D card and the Z card of a control artifact are the same
265
+as in a manifest.
305266
306
-<p>The T card represents a "tag" or property that is applied to
267
+The T card represents a "tag" or property that is applied to
307268
some other artifact. The T card has two or three values. The
308269
second argument is the 40 character lowercase artifact ID of the artifact
309270
to which the tag is to be applied. The
310271
first value is the tag name. The first character of the tag
311272
is either "+", "-", or "*". A "+" means the tag should be added
@@ -313,28 +274,37 @@
313274
The "*" character means the tag should be added to the artifact
314275
and all direct descendants (but not branches) of the artifact down
315276
to but not including the first descendant that contains a
316277
more recent "-" tag with the same name.
317278
The optional third argument is the value of the tag. A tag
318
-without a value is a boolean.</p>
279
+without a value is a boolean.
319280
320
-<p>When two or more tags with the same name are applied to the
281
+When two or more tags with the same name are applied to the
321282
same artifact, the tag with the latest (most recent) date is
322
-used.</p>
283
+used.
323284
324
-<p>Some tags have special meaning. The "comment" tag when applied
285
+Some tags have special meaning. The "comment" tag when applied
325286
to a check-in will override the check-in comment of that check-in
326
-for display purposes.</p>
287
+for display purposes. The "user" tag overrides the name of the
288
+check-in user. The "date" tag overrides the check-in date.
289
+The "branch" tag sets the name of the branch that at check-in
290
+belongs to. Symbolic tags begin with the "sym-" prefix.
291
+
292
+The U card is the name of the user that created the control
293
+artifact. The Z card is the usual artifact checksum.
294
+
295
+An example control artifacts can be seen [/info/9d302ccda8 | here].
296
+
327297
328298
<a name="wikichng"></a>
329299
<h2>4.0 Wiki Pages</h2>
330300
331
-<p>A wiki page is an artifact with a format similar to manifests,
301
+A wiki page is an artifact with a format similar to manifests,
332302
clusters, and control artifacts. The artifact is divided into
333303
cards by newline characters. The format of each card is as in
334304
manifests, clusters, and control artifacts. Wiki artifacts accept
335
-the following card types:</p>
305
+the following card types:
336306
337307
<blockquote>
338308
<b>D</b> <i>time-and-date-stamp</i><br />
339309
<b>L</b> <i>wiki-title</i><br />
340310
<b>P</b> <i>parent-artifact-id</i>+<br />
@@ -341,63 +311,245 @@
341311
<b>U</b> <i>user-name</i><br />
342312
<b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
343313
<b>Z</b> <i>checksum</i>
344314
</blockquote>
345315
346
-<p>The D card is the date and time when the wiki page was edited.
316
+The D card is the date and time when the wiki page was edited.
347317
The P card specifies the parent wiki pages, if any. The L card
348318
gives the name of the wiki page. The U card specifies the login
349319
of the user who made this edit to the wiki page. The Z card is
350
-the usual checksum over the either artifact.</p>
320
+the usual checksum over the either artifact.
351321
352
-<p>The W card is used to specify the text of the wiki page. The
322
+The W card is used to specify the text of the wiki page. The
353323
argument to the W card is an integer which is the number of bytes
354324
of text in the wiki page. That text follows the newline character
355325
that terminates the W card. The wiki text is always followed by one
356
-extra newline.</p>
326
+extra newline.
327
+
328
+An example wiki artifact can be seen
329
+[/artifact/7b2f5fd0e0 | here].
357330
358331
<a name="tktchng"></a>
359332
<h2>5.0 Ticket Changes</h2>
360333
361
-<p>A ticket-change artifact represents a change to a trouble ticket.
362
-The following cards are allowed on a ticket change artifact:</p>
334
+A ticket-change artifact represents a change to a trouble ticket.
335
+The following cards are allowed on a ticket change artifact:
363336
364337
<blockquote>
365338
<b>D</b> <i>time-and-date-stamp</i><br />
366339
<b>J</b> ?<b>+</b>?<i>name</i> ?<i>value</i>?<br />
367340
<b>K</b> <i>ticket-id</i><br />
368341
<b>U</b> <i>user-name</i><br />
369342
<b>Z</b> <i>checksum</i>
370343
</blockquote>
371344
372
-<p>
373345
The D card is the usual date and time stamp and represents the point
374346
in time when the change was entered. The U card is the login of the
375347
programmer who entered this change. The Z card is the checksum over
376
-the entire artifact.</p>
348
+the entire artifact.
377349
378
-<p>
379350
Every ticket has a unique ID. The ticket to which this change is applied
380351
is specified by the K card. A ticket exists if it contains one or
381352
more changes. The first "change" to a ticket is what brings the
382
-ticket into existence.</p>
353
+ticket into existence.
383354
384
-<p>
385355
J cards specify changes to the "value" of "fields" in the ticket.
386356
If the <i>value</i> parameter of the J card is omitted, then the
387357
field is set to an empty string.
388358
Each fossil server has a ticket configuration which specifies the fields its
389359
understands. The ticket configuration is part of the local state for
390360
the repository and thus can vary from one repository to another.
391361
Hence a J card might specify a <i>field</i> that do not exist in the
392362
local ticket configuration. If a J card specifies a <i>field</i> that
393363
is not in the local configuration, then that J card
394
-is simply ignored.</p>
364
+is simply ignored.
395365
396
-<p>
397366
The first argument of the J card is the field name. The second
398367
value is the field value. If the field name begins with "+" then
399368
the value is appended to the prior value. Otherwise, the value
400369
on the J card replaces any previous value of the field.
401370
The field name and value are both encoded using the character
402371
escapes defined for the C card of a manifest.
403
-</p>
372
+
373
+An example ticket-change artifact can be seen
374
+[/artifact/91f1ec6af053 | here].
375
+
376
+<a name="attachment"></a>
377
+<h2>6.0 Attachments</h2>
378
+
379
+An attachment artifact associates some other artifact that is the
380
+attachment (the source artifact) with a ticket or wiki page to which
381
+the attachment is connected (the target artifact).
382
+The following cards are allowed on an attachment artifact:
383
+
384
+<blockquote>
385
+<b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i>
386
+<b>C</b> <i>comment</i><br>
387
+<b>D</b> <i>time-and-date-stamp</i><br />
388
+<b>U</b> <i>user-name</i><br />
389
+<b>Z</b> <i>checksum</i>
390
+</blockquote>
391
+
392
+The A card specifies a filename for the attachment in its first argument.
393
+The filename is preceeded by "+" to add the attachment or "-" to
394
+remove the attachment. The second argument to the A card is the name
395
+of the wiki page or ticket to which the attachment is connected. The
396
+third argument is is the 40-character artifact ID of the attachment
397
+itself. Every attachment artifact must have exactly one A card.
398
+
399
+The C card is an optional comment describing what the attachment is about.
400
+The C card is optional, but there can only be one.
401
+
402
+A single D card is required to give the date and time when the attachment
403
+was applied.
404
+
405
+A single U card gives the name of the user to added the attachment.
406
+If an attachment is added anonymously, then the U card may be omitted.
407
+
408
+The Z card is the usual checksum over the rest of the attachment artifact.
409
+
410
+
411
+<a name="summary"></a>
412
+<h2>7.0 Card Summary</h2>
413
+
414
+The following table summaries the various kinds of cards that
415
+appear on Fossil artifacts:
416
+
417
+<table border=1 width="100%">
418
+<tr>
419
+<th rowspan=2 valign=bottom>Card Format</th>
420
+<th colspan=6>Used By</th>
421
+</tr>
422
+<tr>
423
+<th>Manifest</th>
424
+<th>Cluster</th>
425
+<th>Control</th>
426
+<th>Wiki</th>
427
+<th>Ticket</th>
428
+<th>Attachment</th>
429
+</tr>
430
+<tr>
431
+<td><b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i></td>
432
+<td>&nbsp;</td>
433
+<td>&nbsp;</td>
434
+<td>&nbsp;</td>
435
+<td>&nbsp;</td>
436
+<td>&nbsp;</td>
437
+<td align=center><b>X</b></td>
438
+</tr>
439
+<tr>
440
+<td><b>C</b> <i>coment-text</i></td>
441
+<td align=center><b>X</b></td>
442
+<td>&nbsp;</td>
443
+<td>&nbsp;</td>
444
+<td>&nbsp;</td>
445
+<td>&nbsp;</td>
446
+<td align=center><b>X</b></td>
447
+</tr>
448
+<tr>
449
+<td><b>D</b> <i>date-time-stamp</i></td>
450
+<td align=center><b>X</b></td>
451
+<td align=center>&nbsp;</td>
452
+<td align=center><b>X</b></td>
453
+<td align=center><b>X</b></td>
454
+<td align=center><b>X</b></td>
455
+<td align=center><b>X</b></td>
456
+</tr>
457
+<tr>
458
+<td><b>F</b> <i>filename uuid permissions oldname</i></td>
459
+<td align=center><b>X</b></td>
460
+<td align=center>&nbsp;</td>
461
+<td align=center>&nbsp;</td>
462
+<td align=center>&nbsp;</td>
463
+<td align=center>&nbsp;</td>
464
+<td align=center>&nbsp;</td>
465
+</tr>
466
+<tr>
467
+<td><b>J</b> <i>name value</i></td>
468
+<td align=center>&nbsp;</td>
469
+<td align=center>&nbsp;</td>
470
+<td align=center>&nbsp;</td>
471
+<td align=center>&nbsp;</td>
472
+<td align=center><b>X</b></td>
473
+<td align=center>&nbsp;</td>
474
+</tr>
475
+<tr>
476
+<td><b>K</b> <i>ticket-uuid</i></td>
477
+<td align=center>&nbsp;</td>
478
+<td align=center>&nbsp;</td>
479
+<td align=center>&nbsp;</td>
480
+<td align=center>&nbsp;</td>
481
+<td align=center><b>X</b></td>
482
+<td align=center>&nbsp;</td>
483
+</tr>
484
+<tr>
485
+<td><b>L</b> <i>wiki-title</i></td>
486
+<td align=center>&nbsp;</td>
487
+<td align=center>&nbsp;</td>
488
+<td align=center>&nbsp;</td>
489
+<td align=center><b>X</b></td>
490
+<td align=center>&nbsp;</td>
491
+<td align=center>&nbsp;</td>
492
+</tr>
493
+<tr>
494
+<td><b>M</b> <i>uuid</i></td>
495
+<td align=center>&nbsp;</td>
496
+<td align=center><b>X</b></td>
497
+<td align=center>&nbsp;</td>
498
+<td align=center>&nbsp;</td>
499
+<td align=center>&nbsp;</td>
500
+<td align=center>&nbsp;</td>
501
+</tr>
502
+<tr>
503
+<td><b>P</b> <i>uuid ...</i></td>
504
+<td align=center><b>X</b></td>
505
+<td align=center>&nbsp;</td>
506
+<td align=center>&nbsp;</td>
507
+<td align=center><b>X</b></td>
508
+<td align=center>&nbsp;</td>
509
+<td align=center>&nbsp;</td>
510
+</tr>
511
+<tr>
512
+<td><b>R</b> <i>md5sum</i></td>
513
+<td align=center><b>X</b></td>
514
+<td align=center>&nbsp;</td>
515
+<td align=center>&nbsp;</td>
516
+<td align=center>&nbsp;</td>
517
+<td align=center>&nbsp;</td>
518
+<td align=center>&nbsp;</td>
519
+<tr>
520
+<td><b>T</b> (<b>+</b>|<b>*</b>|<b>-</b>)<i>tagname uuid value</i></td>
521
+<td align=center><b>X</b></td>
522
+<td align=center>&nbsp;</td>
523
+<td align=center><b>X</b></td>
524
+<td align=center>&nbsp;</td>
525
+<td align=center>&nbsp;</td>
526
+<td align=center>&nbsp;</td>
527
+</tr>
528
+<tr>
529
+<td><b>U</b> <i>username</i></td>
530
+<td align=center><b>X</b></td>
531
+<td align=center>&nbsp;</td>
532
+<td align=center><b>X</b></td>
533
+<td align=center><b>X</b></td>
534
+<td align=center><b>X</b></td>
535
+<td align=center><b>X</b></td>
536
+</tr>
537
+<tr>
538
+<td><b>W</b> <i>size</i></td>
539
+<td align=center>&nbsp;</td>
540
+<td align=center>&nbsp;</td>
541
+<td align=center>&nbsp;</td>
542
+<td align=center><b>X</b></td>
543
+<td align=center>&nbsp;</td>
544
+<td align=center>&nbsp;</td>
545
+</tr>
546
+<tr>
547
+<td><b>Z</b> <i>md5sum</i></td>
548
+<td align=center><b>X</b></td>
549
+<td align=center><b>X</b></td>
550
+<td align=center><b>X</b></td>
551
+<td align=center><b>X</b></td>
552
+<td align=center><b>X</b></td>
553
+<td align=center><b>X</b></td>
554
+</tr>
555
+</table>
404556
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -1,26 +1,23 @@
1 <title>Fossil File Formats</title>
2 <h1 align="center">
3 Fossil File Formats
4 </h1>
5
6 <p>The global state of a fossil repository is kept simple so that it can
7 endure in useful form for decades or centuries.
8 A fossil repository is intended to be readable,
9 searchable, and extensible by people not yet born.</p>
10
11 <p>
12 The global state of a fossil repository is an unordered
13 set of <i>artifacts</i>.
14 An artifact might be a source code file, the text of a wiki page,
15 part of a trouble ticket, or one of several special control artifacts
16 used to show the relationships between other artifacts within the
17 project. Each artifact is normally represented on disk as a separate
18 file. Artifacts can be text or binary.
19 </p>
20
21 <p>
22 In addition to the global state,
23 each fossil repository also contains local state.
24 The local state consists of web-page formatting
25 preferences, authorized users, ticket display and reporting formats,
26 and so forth. The global state is shared in common among all
@@ -29,82 +26,73 @@
29 The local state is not versioned and is not synchronized
30 with the global state.
31 The local state is not composed of artifacts and is not intended to be enduring.
32 This document is concerned with global state only. Local state is only
33 mentioned here in order to distinguish it from global state.
34 </p>
35
36 <p>
37 Each artifact in the repository is named by its SHA1 hash.
38 No prefixes or meta information is added to a artifact before
39 its hash is computed. The name of a artifact in the repository
40 is exactly the same SHA1 hash that is computed by sha1sum
41 on the file as it exists in your source tree.</p>
42
43 <p>
44 Some artifacts have a particular format which gives them special
45 meaning to fossil. Fossil recognizes:</p>
46
47 <ul>
48 <li> Manifests </li>
49 <li> Clusters </li>
50 <li> Control Artifacts </li>
51 <li> Wiki Pages </li>
52 <li> Ticket Changes </li>
 
53 </ul>
54
55 <p>These five artifact types are described in the sequel.</p>
56
57 <p>In the current implementation (as of 2009-01-25) the artifacts that
58 make up a fossil repository are stored in in as delta- and zlib-compressed
59 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
60 is an implementation detail and might change in a future release. For
61 the purpose of this article "file format" means the format of the artifacts,
62 not how the artifacts are stored on disk. It is the artifact format that
63 is intended to be enduring. The specifics of how artifacts are stored on
64 disk, though stable, is not intended to live as long as the
65 artifact format.</p>
66
 
67 <h2>1.0 The Manifest</h2>
68
69 <p>A manifest defines a check-in or version of the project
70 source tree. The manifest contains a list of artifacts for
71 each file in the project and the corresponding filenames, as
72 well as information such as parent check-ins, the name of the
73 programmer who created the check-in, the date and time when
74 the check-in was created, and any check-in comments associated
75 with the check-in.</p>
76
77 <p>
78 Any artifact in the repository that follows the syntactic rules
79 of a manifest is a manifest. Note that a manifest can
80 be both a real manifest and also a content file, though this
81 is rare.
82 </p>
83
84 <p>
85 A manifest is a text file. Newline characters
86 (ASCII 0x0a) separate the file into "cards".
87 Each card begins with a single
88 character "card type". Zero or more arguments may follow
89 the card type. All arguments are separated from each other
90 and from the card-type character by a single space
91 character. There is no surplus white space between arguments
92 and no leading or trailing whitespace except for the newline
93 character that acts as the card separator.
94 </p>
95
96 <p>
97 All cards of the manifest occur in strict sorted lexicographical order.
98 No card may be duplicated.
99 The entire manifest may be PGP clear-signed, but otherwise it
100 may contain no additional text or data beyond what is described here.
101 </p>
102
103 <p>
104 Allowed cards in the manifest are as follows:
105 </p>
106
107 <blockquote>
108 <b>C</b> <i>checkin-comment</i><br>
109 <b>D</b> <i>time-and-date-stamp</i><br>
110 <b>F</b> <i>filename</i> <i>SHA1-hash</i> <i>permissions</i> <i>old-name</i><br>
@@ -113,11 +101,10 @@
113 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name <b>*</b> ?value?</i><br>
114 <b>U</b> <i>user-login</i><br>
115 <b>Z</b> <i>manifest-checksum</i>
116 </blockquote>
117
118 <p>
119 A manifest must have exactly one C-card. The sole argument to
120 the C-card is a check-in comment that describes the check-in that
121 the manifest defines. The check-in comment is text. The following
122 escape sequences are applied to the text:
123 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
@@ -124,24 +111,20 @@
124 newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
125 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
126 space and newline, no other whitespace characters are allowed in
127 the check-in comment. Nor are any unprintable characters allowed
128 in the comment.
129 </p>
130
131 <p>
132 A manifest must have exactly one D-card. The sole argument to
133 the D-card is a date-time stamp in the ISO8601 format. The
134 date and time should be in coordinated universal time (UTC).
135 The format is:
136 </p>
137
138 <blockquote>
139 <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>
140 </blockquote>
141
142 <p>
143 A manifest has zero or more F-cards. Each F-card defines a file
144 (other than the manifest itself) which is part of the check-in that
145 the manifest defines. There are two, three, or four arguments.
146 The first argument
147 is the pathname of the file in the check-in relative to the root
@@ -157,13 +140,11 @@
157 always readable and writable. This can be expressed by "w" permission
158 if desired but is optional.
159 The optional 4th argument is the name of the same file as it existed in
160 the parent check-in. If the name of the file is unchanged from its
161 parent, then the 4th argument is omitted.
162 </p>
163
164 <p>
165 A manifest has zero or one P-cards. Most manifests have one P-card.
166 The P-card has a varying number of arguments that
167 defines other manifests from which the current manifest
168 is derived. Each argument is an 40-character lowercase
169 hexadecimal SHA1 of the predecessor manifest. All arguments
@@ -171,13 +152,11 @@
171 The first predecessor is the direct ancestor of the manifest.
172 Other arguments define manifests with which the first was
173 merged to yield the current manifest. Most manifests have
174 a P-card with a single argument. The first manifest in the
175 project has no ancestors and thus has no P-card.
176 </p>
177
178 <p>
179 A manifest may optionally have a single R-card. The R-card has
180 a single argument which is the MD5 checksum of all files in
181 the check-in except the manifest itself. The checksum is expressed
182 as 32-characters of lowercase hexadecimal. The checksum is
183 computed as follows: For each file in the check-in (except for
@@ -185,13 +164,11 @@
185 take the pathname of the file relative to the root of the
186 repository, append a single space (ASCII 0x20), the
187 size of the file in ASCII decimal, a single newline
188 character (ASCII 0x0A), and the complete text of the file.
189 Compute the MD5 checksum of the the result.
190 </p>
191
192 <p>
193 A manifest might contain one or more T-cards used to set tags or
194 properties on the check-in. The format of the T-card is the same as
195 described in <i>Control Artifacts</i> section below, except that the
196 second argument is the single characcter "<b>*</b>" instead of an
197 artifact ID. The <b>*</b> in place of the artifact ID indicates that
@@ -199,42 +176,35 @@
199 possible to encode the current artifact ID as part of an artifact,
200 since the act of inserting the artifact ID would change the artifact ID,
201 hence a <b>*</b> is used to represent "self". T-cards are typically
202 added to manifests in order to set the <b>branch</b> property and a
203 symbolic name when the check-in is intended to start a new branch.
204 </p>
205
206 <p>
207 Each manifest has a single U-card. The argument to the U-card is
208 the login of the user who created the manifest. The login name
209 is encoded using the same character escapes as is used for the
210 check-in comment argument to the C-card.
211 </p>
212
213 <p>
214 A manifest has an option Z-card as its last line. The argument
215 to the Z-card is a 32-character lowercase hexadecimal MD5 hash
216 of all prior lines of the manifest up to and including the newline
217 character that immediately precedes the "Z". The Z-card is just
218 a sanity check to prove that the manifest is well-formed and
219 consistent.
220 </p>
221
222 <p>A sample manifest from Fossil itself can be seen
223 [/artifact/28987096ac | here].
224
 
225 <h2>2.0 Clusters</h2>
226
227 <p>
228 A cluster is a artifact that declares the existence of other artifacts.
229 Clusters are used during repository synchronization to help
230 reduce network traffic. As such, clusters are an optimization and
231 may be removed from a repository without loss or damage to the
232 underlying project code.
233 </p>
234
235 <p>
236 Clusters follow a syntax that is very similar to manifests.
237 A Cluster is a line-oriented text file. Newline characters
238 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
239 character "card type". Zero or more arguments may follow
240 the card type. All arguments are separated from each other
@@ -245,67 +215,58 @@
245 All cards of a cluster occur in strict sorted lexicographical order.
246 No card may be duplicated.
247 The cluster may not contain additional text or data beyond
248 what is described here.
249 Unlike manifests, clusters are never PGP signed.
250 </p>
251
252 <p>
253 Allowed cards in the cluster are as follows:
254 </p>
255
256 <blockquote>
257 <b>M</b> <i>artifact-id</i><br />
258 <b>Z</b> <i>checksum</i>
259 </blockquote>
260
261 <p>
262 A cluster contains one or more "M" cards followed by a single "Z"
263 line. Each M card has a single argument which is the artifact ID of
264 another artifact in the repository. The Z card work exactly like
265 the Z card of a manifest. The argument to the Z card is the
266 lower-case hexadecimal representation of the MD5 checksum of all
267 prior cards in the cluster. Note that the Z card is required
268 on a cluster.
269 </p>
270
271 <p>An example cluster from Fossil can be seen
272 [/artifact/d03dbdd73a2a8 | here].</p>
273
274
275 <h2>3.0 Control Artifacts</h2>
276
277 <p>
278 Control artifacts are used to assign properties to other artifacts
279 within the repository. The basic format of a control artifact is
280 the same as a manifest or cluster. A control artifact is a text
281 files divided into cards by newline characters. Each card has a
282 single-character card type followed by arguments. Spaces separate
283 the card type and the arguments. No surplus whitespace is allowed.
284 All cards must occur in strict lexigraphical order.
285 </p>
286
287 <p>
288 Allowed cards in a control artifact are as follows:
289 </p>
290
291 <blockquote>
292 <b>D</b> <i>time-and-date-stamp</i><br />
293 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
 
294 <b>Z</b> <i>checksum</i><br />
295 </blockquote>
296
297 <p>
298 A control artifact must have one D card and one Z card and
299 one or more T cards. No other cards or other text is
300 allowed in a control artifact. Control artifacts might be PGP
301 clearsigned.</p>
302
303 <p>The D card and the Z card of a control artifact are the same
304 as in a manifest.</p>
305
306 <p>The T card represents a "tag" or property that is applied to
307 some other artifact. The T card has two or three values. The
308 second argument is the 40 character lowercase artifact ID of the artifact
309 to which the tag is to be applied. The
310 first value is the tag name. The first character of the tag
311 is either "+", "-", or "*". A "+" means the tag should be added
@@ -313,28 +274,37 @@
313 The "*" character means the tag should be added to the artifact
314 and all direct descendants (but not branches) of the artifact down
315 to but not including the first descendant that contains a
316 more recent "-" tag with the same name.
317 The optional third argument is the value of the tag. A tag
318 without a value is a boolean.</p>
319
320 <p>When two or more tags with the same name are applied to the
321 same artifact, the tag with the latest (most recent) date is
322 used.</p>
323
324 <p>Some tags have special meaning. The "comment" tag when applied
325 to a check-in will override the check-in comment of that check-in
326 for display purposes.</p>
 
 
 
 
 
 
 
 
 
327
328 <a name="wikichng"></a>
329 <h2>4.0 Wiki Pages</h2>
330
331 <p>A wiki page is an artifact with a format similar to manifests,
332 clusters, and control artifacts. The artifact is divided into
333 cards by newline characters. The format of each card is as in
334 manifests, clusters, and control artifacts. Wiki artifacts accept
335 the following card types:</p>
336
337 <blockquote>
338 <b>D</b> <i>time-and-date-stamp</i><br />
339 <b>L</b> <i>wiki-title</i><br />
340 <b>P</b> <i>parent-artifact-id</i>+<br />
@@ -341,63 +311,245 @@
341 <b>U</b> <i>user-name</i><br />
342 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
343 <b>Z</b> <i>checksum</i>
344 </blockquote>
345
346 <p>The D card is the date and time when the wiki page was edited.
347 The P card specifies the parent wiki pages, if any. The L card
348 gives the name of the wiki page. The U card specifies the login
349 of the user who made this edit to the wiki page. The Z card is
350 the usual checksum over the either artifact.</p>
351
352 <p>The W card is used to specify the text of the wiki page. The
353 argument to the W card is an integer which is the number of bytes
354 of text in the wiki page. That text follows the newline character
355 that terminates the W card. The wiki text is always followed by one
356 extra newline.</p>
 
 
 
357
358 <a name="tktchng"></a>
359 <h2>5.0 Ticket Changes</h2>
360
361 <p>A ticket-change artifact represents a change to a trouble ticket.
362 The following cards are allowed on a ticket change artifact:</p>
363
364 <blockquote>
365 <b>D</b> <i>time-and-date-stamp</i><br />
366 <b>J</b> ?<b>+</b>?<i>name</i> ?<i>value</i>?<br />
367 <b>K</b> <i>ticket-id</i><br />
368 <b>U</b> <i>user-name</i><br />
369 <b>Z</b> <i>checksum</i>
370 </blockquote>
371
372 <p>
373 The D card is the usual date and time stamp and represents the point
374 in time when the change was entered. The U card is the login of the
375 programmer who entered this change. The Z card is the checksum over
376 the entire artifact.</p>
377
378 <p>
379 Every ticket has a unique ID. The ticket to which this change is applied
380 is specified by the K card. A ticket exists if it contains one or
381 more changes. The first "change" to a ticket is what brings the
382 ticket into existence.</p>
383
384 <p>
385 J cards specify changes to the "value" of "fields" in the ticket.
386 If the <i>value</i> parameter of the J card is omitted, then the
387 field is set to an empty string.
388 Each fossil server has a ticket configuration which specifies the fields its
389 understands. The ticket configuration is part of the local state for
390 the repository and thus can vary from one repository to another.
391 Hence a J card might specify a <i>field</i> that do not exist in the
392 local ticket configuration. If a J card specifies a <i>field</i> that
393 is not in the local configuration, then that J card
394 is simply ignored.</p>
395
396 <p>
397 The first argument of the J card is the field name. The second
398 value is the field value. If the field name begins with "+" then
399 the value is appended to the prior value. Otherwise, the value
400 on the J card replaces any previous value of the field.
401 The field name and value are both encoded using the character
402 escapes defined for the C card of a manifest.
403 </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -1,26 +1,23 @@
1 <title>Fossil File Formats</title>
2 <h1 align="center">
3 Fossil File Formats
4 </h1>
5
6 The global state of a fossil repository is kept simple so that it can
7 endure in useful form for decades or centuries.
8 A fossil repository is intended to be readable,
9 searchable, and extensible by people not yet born.
10
 
11 The global state of a fossil repository is an unordered
12 set of <i>artifacts</i>.
13 An artifact might be a source code file, the text of a wiki page,
14 part of a trouble ticket, or one of several special control artifacts
15 used to show the relationships between other artifacts within the
16 project. Each artifact is normally represented on disk as a separate
17 file. Artifacts can be text or binary.
 
18
 
19 In addition to the global state,
20 each fossil repository also contains local state.
21 The local state consists of web-page formatting
22 preferences, authorized users, ticket display and reporting formats,
23 and so forth. The global state is shared in common among all
@@ -29,82 +26,73 @@
26 The local state is not versioned and is not synchronized
27 with the global state.
28 The local state is not composed of artifacts and is not intended to be enduring.
29 This document is concerned with global state only. Local state is only
30 mentioned here in order to distinguish it from global state.
 
31
 
32 Each artifact in the repository is named by its SHA1 hash.
33 No prefixes or meta information is added to a artifact before
34 its hash is computed. The name of a artifact in the repository
35 is exactly the same SHA1 hash that is computed by sha1sum
36 on the file as it exists in your source tree.</p>
37
 
38 Some artifacts have a particular format which gives them special
39 meaning to fossil. Fossil recognizes:
40
41 <ul>
42 <li> [#manifest | Manifests] </li>
43 <li> [#cluster | Clusters] </li>
44 <li> [#ctrl | Control Artifacts] </li>
45 <li> [#wikichng | Wiki Pages] </li>
46 <li> [#tktchng | Ticket Changes] </li>
47 <li> [#artifact | Artifacts] </li>
48 </ul>
49
50 These five artifact types are described in the sequel.
51
52 In the current implementation (as of 2009-01-25) the artifacts that
53 make up a fossil repository are stored in in as delta- and zlib-compressed
54 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
55 is an implementation detail and might change in a future release. For
56 the purpose of this article "file format" means the format of the artifacts,
57 not how the artifacts are stored on disk. It is the artifact format that
58 is intended to be enduring. The specifics of how artifacts are stored on
59 disk, though stable, is not intended to live as long as the
60 artifact format.
61
62 <a name="manifest"></a>
63 <h2>1.0 The Manifest</h2>
64
65 A manifest defines a check-in or version of the project
66 source tree. The manifest contains a list of artifacts for
67 each file in the project and the corresponding filenames, as
68 well as information such as parent check-ins, the name of the
69 programmer who created the check-in, the date and time when
70 the check-in was created, and any check-in comments associated
71 with the check-in.
72
 
73 Any artifact in the repository that follows the syntactic rules
74 of a manifest is a manifest. Note that a manifest can
75 be both a real manifest and also a content file, though this
76 is rare.
 
77
 
78 A manifest is a text file. Newline characters
79 (ASCII 0x0a) separate the file into "cards".
80 Each card begins with a single
81 character "card type". Zero or more arguments may follow
82 the card type. All arguments are separated from each other
83 and from the card-type character by a single space
84 character. There is no surplus white space between arguments
85 and no leading or trailing whitespace except for the newline
86 character that acts as the card separator.
 
87
 
88 All cards of the manifest occur in strict sorted lexicographical order.
89 No card may be duplicated.
90 The entire manifest may be PGP clear-signed, but otherwise it
91 may contain no additional text or data beyond what is described here.
 
92
 
93 Allowed cards in the manifest are as follows:
 
94
95 <blockquote>
96 <b>C</b> <i>checkin-comment</i><br>
97 <b>D</b> <i>time-and-date-stamp</i><br>
98 <b>F</b> <i>filename</i> <i>SHA1-hash</i> <i>permissions</i> <i>old-name</i><br>
@@ -113,11 +101,10 @@
101 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name <b>*</b> ?value?</i><br>
102 <b>U</b> <i>user-login</i><br>
103 <b>Z</b> <i>manifest-checksum</i>
104 </blockquote>
105
 
106 A manifest must have exactly one C-card. The sole argument to
107 the C-card is a check-in comment that describes the check-in that
108 the manifest defines. The check-in comment is text. The following
109 escape sequences are applied to the text:
110 A space (ASCII 0x20) is represented as "\s" (ASCII 0x5C, 0x73). A
@@ -124,24 +111,20 @@
111 newline (ASCII 0x0a) is "\n" (ASCII 0x6C, x6E). A backslash
112 (ASCII 0x5C) is represented as two backslashes "\\". Apart from
113 space and newline, no other whitespace characters are allowed in
114 the check-in comment. Nor are any unprintable characters allowed
115 in the comment.
 
116
 
117 A manifest must have exactly one D-card. The sole argument to
118 the D-card is a date-time stamp in the ISO8601 format. The
119 date and time should be in coordinated universal time (UTC).
120 The format is:
 
121
122 <blockquote>
123 <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>
124 </blockquote>
125
 
126 A manifest has zero or more F-cards. Each F-card defines a file
127 (other than the manifest itself) which is part of the check-in that
128 the manifest defines. There are two, three, or four arguments.
129 The first argument
130 is the pathname of the file in the check-in relative to the root
@@ -157,13 +140,11 @@
140 always readable and writable. This can be expressed by "w" permission
141 if desired but is optional.
142 The optional 4th argument is the name of the same file as it existed in
143 the parent check-in. If the name of the file is unchanged from its
144 parent, then the 4th argument is omitted.
 
145
 
146 A manifest has zero or one P-cards. Most manifests have one P-card.
147 The P-card has a varying number of arguments that
148 defines other manifests from which the current manifest
149 is derived. Each argument is an 40-character lowercase
150 hexadecimal SHA1 of the predecessor manifest. All arguments
@@ -171,13 +152,11 @@
152 The first predecessor is the direct ancestor of the manifest.
153 Other arguments define manifests with which the first was
154 merged to yield the current manifest. Most manifests have
155 a P-card with a single argument. The first manifest in the
156 project has no ancestors and thus has no P-card.
 
157
 
158 A manifest may optionally have a single R-card. The R-card has
159 a single argument which is the MD5 checksum of all files in
160 the check-in except the manifest itself. The checksum is expressed
161 as 32-characters of lowercase hexadecimal. The checksum is
162 computed as follows: For each file in the check-in (except for
@@ -185,13 +164,11 @@
164 take the pathname of the file relative to the root of the
165 repository, append a single space (ASCII 0x20), the
166 size of the file in ASCII decimal, a single newline
167 character (ASCII 0x0A), and the complete text of the file.
168 Compute the MD5 checksum of the the result.
 
169
 
170 A manifest might contain one or more T-cards used to set tags or
171 properties on the check-in. The format of the T-card is the same as
172 described in <i>Control Artifacts</i> section below, except that the
173 second argument is the single characcter "<b>*</b>" instead of an
174 artifact ID. The <b>*</b> in place of the artifact ID indicates that
@@ -199,42 +176,35 @@
176 possible to encode the current artifact ID as part of an artifact,
177 since the act of inserting the artifact ID would change the artifact ID,
178 hence a <b>*</b> is used to represent "self". T-cards are typically
179 added to manifests in order to set the <b>branch</b> property and a
180 symbolic name when the check-in is intended to start a new branch.
 
181
 
182 Each manifest has a single U-card. The argument to the U-card is
183 the login of the user who created the manifest. The login name
184 is encoded using the same character escapes as is used for the
185 check-in comment argument to the C-card.
 
186
 
187 A manifest has an option Z-card as its last line. The argument
188 to the Z-card is a 32-character lowercase hexadecimal MD5 hash
189 of all prior lines of the manifest up to and including the newline
190 character that immediately precedes the "Z". The Z-card is just
191 a sanity check to prove that the manifest is well-formed and
192 consistent.
 
193
194 A sample manifest from Fossil itself can be seen
195 [/artifact/28987096ac | here].
196
197 <a name="cluster"></a>
198 <h2>2.0 Clusters</h2>
199
 
200 A cluster is a artifact that declares the existence of other artifacts.
201 Clusters are used during repository synchronization to help
202 reduce network traffic. As such, clusters are an optimization and
203 may be removed from a repository without loss or damage to the
204 underlying project code.
 
205
 
206 Clusters follow a syntax that is very similar to manifests.
207 A Cluster is a line-oriented text file. Newline characters
208 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
209 character "card type". Zero or more arguments may follow
210 the card type. All arguments are separated from each other
@@ -245,67 +215,58 @@
215 All cards of a cluster occur in strict sorted lexicographical order.
216 No card may be duplicated.
217 The cluster may not contain additional text or data beyond
218 what is described here.
219 Unlike manifests, clusters are never PGP signed.
 
220
 
221 Allowed cards in the cluster are as follows:
 
222
223 <blockquote>
224 <b>M</b> <i>artifact-id</i><br />
225 <b>Z</b> <i>checksum</i>
226 </blockquote>
227
 
228 A cluster contains one or more "M" cards followed by a single "Z"
229 line. Each M card has a single argument which is the artifact ID of
230 another artifact in the repository. The Z card work exactly like
231 the Z card of a manifest. The argument to the Z card is the
232 lower-case hexadecimal representation of the MD5 checksum of all
233 prior cards in the cluster. Note that the Z card is required
234 on a cluster.
 
235
236 An example cluster from Fossil can be seen
237 [/artifact/d03dbdd73a2a8 | here].
238
239 <a name="ctrl"></a>
240 <h2>3.0 Control Artifacts</h2>
241
 
242 Control artifacts are used to assign properties to other artifacts
243 within the repository. The basic format of a control artifact is
244 the same as a manifest or cluster. A control artifact is a text
245 files divided into cards by newline characters. Each card has a
246 single-character card type followed by arguments. Spaces separate
247 the card type and the arguments. No surplus whitespace is allowed.
248 All cards must occur in strict lexigraphical order.
 
249
 
250 Allowed cards in a control artifact are as follows:
 
251
252 <blockquote>
253 <b>D</b> <i>time-and-date-stamp</i><br />
254 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
255 <b>U</b> <i>user-name</i><br />
256 <b>Z</b> <i>checksum</i><br />
257 </blockquote>
258
 
259 A control artifact must have one D card and one Z card and
260 one or more T cards. No other cards or other text is
261 allowed in a control artifact. Control artifacts might be PGP
262 clearsigned.
263
264 The D card and the Z card of a control artifact are the same
265 as in a manifest.
266
267 The T card represents a "tag" or property that is applied to
268 some other artifact. The T card has two or three values. The
269 second argument is the 40 character lowercase artifact ID of the artifact
270 to which the tag is to be applied. The
271 first value is the tag name. The first character of the tag
272 is either "+", "-", or "*". A "+" means the tag should be added
@@ -313,28 +274,37 @@
274 The "*" character means the tag should be added to the artifact
275 and all direct descendants (but not branches) of the artifact down
276 to but not including the first descendant that contains a
277 more recent "-" tag with the same name.
278 The optional third argument is the value of the tag. A tag
279 without a value is a boolean.
280
281 When two or more tags with the same name are applied to the
282 same artifact, the tag with the latest (most recent) date is
283 used.
284
285 Some tags have special meaning. The "comment" tag when applied
286 to a check-in will override the check-in comment of that check-in
287 for display purposes. The "user" tag overrides the name of the
288 check-in user. The "date" tag overrides the check-in date.
289 The "branch" tag sets the name of the branch that at check-in
290 belongs to. Symbolic tags begin with the "sym-" prefix.
291
292 The U card is the name of the user that created the control
293 artifact. The Z card is the usual artifact checksum.
294
295 An example control artifacts can be seen [/info/9d302ccda8 | here].
296
297
298 <a name="wikichng"></a>
299 <h2>4.0 Wiki Pages</h2>
300
301 A wiki page is an artifact with a format similar to manifests,
302 clusters, and control artifacts. The artifact is divided into
303 cards by newline characters. The format of each card is as in
304 manifests, clusters, and control artifacts. Wiki artifacts accept
305 the following card types:
306
307 <blockquote>
308 <b>D</b> <i>time-and-date-stamp</i><br />
309 <b>L</b> <i>wiki-title</i><br />
310 <b>P</b> <i>parent-artifact-id</i>+<br />
@@ -341,63 +311,245 @@
311 <b>U</b> <i>user-name</i><br />
312 <b>W</b> <i>size</i> <b>\n</b> <i>text</i> <b>\n</b><br />
313 <b>Z</b> <i>checksum</i>
314 </blockquote>
315
316 The D card is the date and time when the wiki page was edited.
317 The P card specifies the parent wiki pages, if any. The L card
318 gives the name of the wiki page. The U card specifies the login
319 of the user who made this edit to the wiki page. The Z card is
320 the usual checksum over the either artifact.
321
322 The W card is used to specify the text of the wiki page. The
323 argument to the W card is an integer which is the number of bytes
324 of text in the wiki page. That text follows the newline character
325 that terminates the W card. The wiki text is always followed by one
326 extra newline.
327
328 An example wiki artifact can be seen
329 [/artifact/7b2f5fd0e0 | here].
330
331 <a name="tktchng"></a>
332 <h2>5.0 Ticket Changes</h2>
333
334 A ticket-change artifact represents a change to a trouble ticket.
335 The following cards are allowed on a ticket change artifact:
336
337 <blockquote>
338 <b>D</b> <i>time-and-date-stamp</i><br />
339 <b>J</b> ?<b>+</b>?<i>name</i> ?<i>value</i>?<br />
340 <b>K</b> <i>ticket-id</i><br />
341 <b>U</b> <i>user-name</i><br />
342 <b>Z</b> <i>checksum</i>
343 </blockquote>
344
 
345 The D card is the usual date and time stamp and represents the point
346 in time when the change was entered. The U card is the login of the
347 programmer who entered this change. The Z card is the checksum over
348 the entire artifact.
349
 
350 Every ticket has a unique ID. The ticket to which this change is applied
351 is specified by the K card. A ticket exists if it contains one or
352 more changes. The first "change" to a ticket is what brings the
353 ticket into existence.
354
 
355 J cards specify changes to the "value" of "fields" in the ticket.
356 If the <i>value</i> parameter of the J card is omitted, then the
357 field is set to an empty string.
358 Each fossil server has a ticket configuration which specifies the fields its
359 understands. The ticket configuration is part of the local state for
360 the repository and thus can vary from one repository to another.
361 Hence a J card might specify a <i>field</i> that do not exist in the
362 local ticket configuration. If a J card specifies a <i>field</i> that
363 is not in the local configuration, then that J card
364 is simply ignored.
365
 
366 The first argument of the J card is the field name. The second
367 value is the field value. If the field name begins with "+" then
368 the value is appended to the prior value. Otherwise, the value
369 on the J card replaces any previous value of the field.
370 The field name and value are both encoded using the character
371 escapes defined for the C card of a manifest.
372
373 An example ticket-change artifact can be seen
374 [/artifact/91f1ec6af053 | here].
375
376 <a name="attachment"></a>
377 <h2>6.0 Attachments</h2>
378
379 An attachment artifact associates some other artifact that is the
380 attachment (the source artifact) with a ticket or wiki page to which
381 the attachment is connected (the target artifact).
382 The following cards are allowed on an attachment artifact:
383
384 <blockquote>
385 <b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i>
386 <b>C</b> <i>comment</i><br>
387 <b>D</b> <i>time-and-date-stamp</i><br />
388 <b>U</b> <i>user-name</i><br />
389 <b>Z</b> <i>checksum</i>
390 </blockquote>
391
392 The A card specifies a filename for the attachment in its first argument.
393 The filename is preceeded by "+" to add the attachment or "-" to
394 remove the attachment. The second argument to the A card is the name
395 of the wiki page or ticket to which the attachment is connected. The
396 third argument is is the 40-character artifact ID of the attachment
397 itself. Every attachment artifact must have exactly one A card.
398
399 The C card is an optional comment describing what the attachment is about.
400 The C card is optional, but there can only be one.
401
402 A single D card is required to give the date and time when the attachment
403 was applied.
404
405 A single U card gives the name of the user to added the attachment.
406 If an attachment is added anonymously, then the U card may be omitted.
407
408 The Z card is the usual checksum over the rest of the attachment artifact.
409
410
411 <a name="summary"></a>
412 <h2>7.0 Card Summary</h2>
413
414 The following table summaries the various kinds of cards that
415 appear on Fossil artifacts:
416
417 <table border=1 width="100%">
418 <tr>
419 <th rowspan=2 valign=bottom>Card Format</th>
420 <th colspan=6>Used By</th>
421 </tr>
422 <tr>
423 <th>Manifest</th>
424 <th>Cluster</th>
425 <th>Control</th>
426 <th>Wiki</th>
427 <th>Ticket</th>
428 <th>Attachment</th>
429 </tr>
430 <tr>
431 <td><b>A</b> (<b>+</b>|<b>-</b>)<i>filename target source</i></td>
432 <td>&nbsp;</td>
433 <td>&nbsp;</td>
434 <td>&nbsp;</td>
435 <td>&nbsp;</td>
436 <td>&nbsp;</td>
437 <td align=center><b>X</b></td>
438 </tr>
439 <tr>
440 <td><b>C</b> <i>coment-text</i></td>
441 <td align=center><b>X</b></td>
442 <td>&nbsp;</td>
443 <td>&nbsp;</td>
444 <td>&nbsp;</td>
445 <td>&nbsp;</td>
446 <td align=center><b>X</b></td>
447 </tr>
448 <tr>
449 <td><b>D</b> <i>date-time-stamp</i></td>
450 <td align=center><b>X</b></td>
451 <td align=center>&nbsp;</td>
452 <td align=center><b>X</b></td>
453 <td align=center><b>X</b></td>
454 <td align=center><b>X</b></td>
455 <td align=center><b>X</b></td>
456 </tr>
457 <tr>
458 <td><b>F</b> <i>filename uuid permissions oldname</i></td>
459 <td align=center><b>X</b></td>
460 <td align=center>&nbsp;</td>
461 <td align=center>&nbsp;</td>
462 <td align=center>&nbsp;</td>
463 <td align=center>&nbsp;</td>
464 <td align=center>&nbsp;</td>
465 </tr>
466 <tr>
467 <td><b>J</b> <i>name value</i></td>
468 <td align=center>&nbsp;</td>
469 <td align=center>&nbsp;</td>
470 <td align=center>&nbsp;</td>
471 <td align=center>&nbsp;</td>
472 <td align=center><b>X</b></td>
473 <td align=center>&nbsp;</td>
474 </tr>
475 <tr>
476 <td><b>K</b> <i>ticket-uuid</i></td>
477 <td align=center>&nbsp;</td>
478 <td align=center>&nbsp;</td>
479 <td align=center>&nbsp;</td>
480 <td align=center>&nbsp;</td>
481 <td align=center><b>X</b></td>
482 <td align=center>&nbsp;</td>
483 </tr>
484 <tr>
485 <td><b>L</b> <i>wiki-title</i></td>
486 <td align=center>&nbsp;</td>
487 <td align=center>&nbsp;</td>
488 <td align=center>&nbsp;</td>
489 <td align=center><b>X</b></td>
490 <td align=center>&nbsp;</td>
491 <td align=center>&nbsp;</td>
492 </tr>
493 <tr>
494 <td><b>M</b> <i>uuid</i></td>
495 <td align=center>&nbsp;</td>
496 <td align=center><b>X</b></td>
497 <td align=center>&nbsp;</td>
498 <td align=center>&nbsp;</td>
499 <td align=center>&nbsp;</td>
500 <td align=center>&nbsp;</td>
501 </tr>
502 <tr>
503 <td><b>P</b> <i>uuid ...</i></td>
504 <td align=center><b>X</b></td>
505 <td align=center>&nbsp;</td>
506 <td align=center>&nbsp;</td>
507 <td align=center><b>X</b></td>
508 <td align=center>&nbsp;</td>
509 <td align=center>&nbsp;</td>
510 </tr>
511 <tr>
512 <td><b>R</b> <i>md5sum</i></td>
513 <td align=center><b>X</b></td>
514 <td align=center>&nbsp;</td>
515 <td align=center>&nbsp;</td>
516 <td align=center>&nbsp;</td>
517 <td align=center>&nbsp;</td>
518 <td align=center>&nbsp;</td>
519 <tr>
520 <td><b>T</b> (<b>+</b>|<b>*</b>|<b>-</b>)<i>tagname uuid value</i></td>
521 <td align=center><b>X</b></td>
522 <td align=center>&nbsp;</td>
523 <td align=center><b>X</b></td>
524 <td align=center>&nbsp;</td>
525 <td align=center>&nbsp;</td>
526 <td align=center>&nbsp;</td>
527 </tr>
528 <tr>
529 <td><b>U</b> <i>username</i></td>
530 <td align=center><b>X</b></td>
531 <td align=center>&nbsp;</td>
532 <td align=center><b>X</b></td>
533 <td align=center><b>X</b></td>
534 <td align=center><b>X</b></td>
535 <td align=center><b>X</b></td>
536 </tr>
537 <tr>
538 <td><b>W</b> <i>size</i></td>
539 <td align=center>&nbsp;</td>
540 <td align=center>&nbsp;</td>
541 <td align=center>&nbsp;</td>
542 <td align=center><b>X</b></td>
543 <td align=center>&nbsp;</td>
544 <td align=center>&nbsp;</td>
545 </tr>
546 <tr>
547 <td><b>Z</b> <i>md5sum</i></td>
548 <td align=center><b>X</b></td>
549 <td align=center><b>X</b></td>
550 <td align=center><b>X</b></td>
551 <td align=center><b>X</b></td>
552 <td align=center><b>X</b></td>
553 <td align=center><b>X</b></td>
554 </tr>
555 </table>
556

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button