Fossil SCM

Abandon the HNAME table idea. Instead, continue to use the BLOB.UUID as the primary artifact name and add the ALIAS table for aliased artifact names after a hash algorithm change. Add the optional alias argument to the M-card.

drh 2017-02-27 22:20 fossil-2.0
Commit 2e42c9cb89ac25e6ee503705070e9022a7e49c7d
+1 -1
--- src/content.c
+++ src/content.c
@@ -1128,11 +1128,11 @@
11281128
"cherry-pick target of", 0);
11291129
nErr += check_exists(p->aCherrypick[i].zCPBase, flags, p,
11301130
"cherry-pick baseline of", 0);
11311131
}
11321132
for(i=0; i<p->nCChild; i++){
1133
- nErr += check_exists(p->azCChild[i], flags, p, "in", 0);
1133
+ nErr += check_exists(p->aCChild[i].zUuid, flags, p, "in", 0);
11341134
}
11351135
for(i=0; i<p->nTag; i++){
11361136
nErr += check_exists(p->aTag[i].zUuid, flags, p, "target of", 0);
11371137
}
11381138
manifest_destroy(p);
11391139
--- src/content.c
+++ src/content.c
@@ -1128,11 +1128,11 @@
1128 "cherry-pick target of", 0);
1129 nErr += check_exists(p->aCherrypick[i].zCPBase, flags, p,
1130 "cherry-pick baseline of", 0);
1131 }
1132 for(i=0; i<p->nCChild; i++){
1133 nErr += check_exists(p->azCChild[i], flags, p, "in", 0);
1134 }
1135 for(i=0; i<p->nTag; i++){
1136 nErr += check_exists(p->aTag[i].zUuid, flags, p, "target of", 0);
1137 }
1138 manifest_destroy(p);
1139
--- src/content.c
+++ src/content.c
@@ -1128,11 +1128,11 @@
1128 "cherry-pick target of", 0);
1129 nErr += check_exists(p->aCherrypick[i].zCPBase, flags, p,
1130 "cherry-pick baseline of", 0);
1131 }
1132 for(i=0; i<p->nCChild; i++){
1133 nErr += check_exists(p->aCChild[i].zUuid, flags, p, "in", 0);
1134 }
1135 for(i=0; i<p->nTag; i++){
1136 nErr += check_exists(p->aTag[i].zUuid, flags, p, "target of", 0);
1137 }
1138 manifest_destroy(p);
1139
+17 -8
--- src/manifest.c
+++ src/manifest.c
@@ -95,12 +95,15 @@
9595
struct {
9696
char *zCPTarget; /* Hash for cherry-picked version w/ +|- prefix */
9797
char *zCPBase; /* Hash for cherry-pick baseline. NULL for singletons */
9898
} *aCherrypick;
9999
int nCChild; /* Number of cluster children */
100
- int nCChildAlloc; /* Number of closts allocated in azCChild[] */
101
- char **azCChild; /* Hashes of referenced objects in a cluster. M cards */
100
+ int nCChildAlloc; /* Number of cluster allocated in aCChild[] */
101
+ struct {
102
+ char *zUuid; /* Hashes of referenced objects in cluster. M cards */
103
+ char *zAlias; /* Alias arguments on a cluster */
104
+ } *aCChild;
102105
int nTag; /* Number of T Cards */
103106
int nTagAlloc; /* Slots allocated in aTag[] */
104107
struct TagType {
105108
char *zName; /* Name of the tag */
106109
char *zUuid; /* Hash of artifact that the tag is applied to */
@@ -138,11 +141,11 @@
138141
void manifest_destroy(Manifest *p){
139142
if( p ){
140143
blob_reset(&p->content);
141144
fossil_free(p->aFile);
142145
fossil_free(p->azParent);
143
- fossil_free(p->azCChild);
146
+ fossil_free(p->aCChild);
144147
fossil_free(p->aTag);
145148
fossil_free(p->aField);
146149
fossil_free(p->aCherrypick);
147150
if( p->pBaseline ) manifest_destroy(p->pBaseline);
148151
memset(p, 0, sizeof(*p));
@@ -643,23 +646,29 @@
643646
**
644647
** An M-line identifies another artifact by its hash. M-lines
645648
** occur in clusters only.
646649
*/
647650
case 'M': {
651
+ char *zAlias;
648652
zUuid = next_token(&x, &sz);
649653
if( zUuid==0 ) SYNTAX("missing hash on M-card");
650654
if( hname_validate(zUuid,sz)==HNAME_NONE ){
651655
SYNTAX("Invalid hash on M-card");
652656
}
657
+ zAlias = next_token(&x, &sz);
658
+ if( zAlias && hname_validate(zAlias,sz)==HNAME_NONE ){
659
+ SYNTAX("Invalid alias hash on M-card");
660
+ }
653661
if( p->nCChild>=p->nCChildAlloc ){
654662
p->nCChildAlloc = p->nCChildAlloc*2 + 10;
655
- p->azCChild = fossil_realloc(p->azCChild
656
- , p->nCChildAlloc*sizeof(p->azCChild[0]) );
663
+ p->aCChild = fossil_realloc(p->aCChild
664
+ , p->nCChildAlloc*sizeof(p->aCChild[0]) );
657665
}
658666
i = p->nCChild++;
659
- p->azCChild[i] = zUuid;
660
- if( i>0 && fossil_strcmp(p->azCChild[i-1], zUuid)>=0 ){
667
+ p->aCChild[i].zUuid = zUuid;
668
+ p->aCChild[i].zAlias = zAlias;
669
+ if( i>0 && fossil_strcmp(p->aCChild[i-1].zUuid, zUuid)>=0 ){
661670
SYNTAX("M-card in the wrong order");
662671
}
663672
break;
664673
}
665674
@@ -2006,11 +2015,11 @@
20062015
static Stmt del1;
20072016
tag_insert("cluster", 1, 0, rid, p->rDate, rid);
20082017
db_static_prepare(&del1, "DELETE FROM unclustered WHERE rid=:rid");
20092018
for(i=0; i<p->nCChild; i++){
20102019
int mid;
2011
- mid = uuid_to_rid(p->azCChild[i], 1);
2020
+ mid = uuid_to_rid(p->aCChild[i].zUuid, 1);
20122021
if( mid>0 ){
20132022
db_bind_int(&del1, ":rid", mid);
20142023
db_step(&del1);
20152024
db_reset(&del1);
20162025
}
20172026
--- src/manifest.c
+++ src/manifest.c
@@ -95,12 +95,15 @@
95 struct {
96 char *zCPTarget; /* Hash for cherry-picked version w/ +|- prefix */
97 char *zCPBase; /* Hash for cherry-pick baseline. NULL for singletons */
98 } *aCherrypick;
99 int nCChild; /* Number of cluster children */
100 int nCChildAlloc; /* Number of closts allocated in azCChild[] */
101 char **azCChild; /* Hashes of referenced objects in a cluster. M cards */
 
 
 
102 int nTag; /* Number of T Cards */
103 int nTagAlloc; /* Slots allocated in aTag[] */
104 struct TagType {
105 char *zName; /* Name of the tag */
106 char *zUuid; /* Hash of artifact that the tag is applied to */
@@ -138,11 +141,11 @@
138 void manifest_destroy(Manifest *p){
139 if( p ){
140 blob_reset(&p->content);
141 fossil_free(p->aFile);
142 fossil_free(p->azParent);
143 fossil_free(p->azCChild);
144 fossil_free(p->aTag);
145 fossil_free(p->aField);
146 fossil_free(p->aCherrypick);
147 if( p->pBaseline ) manifest_destroy(p->pBaseline);
148 memset(p, 0, sizeof(*p));
@@ -643,23 +646,29 @@
643 **
644 ** An M-line identifies another artifact by its hash. M-lines
645 ** occur in clusters only.
646 */
647 case 'M': {
 
648 zUuid = next_token(&x, &sz);
649 if( zUuid==0 ) SYNTAX("missing hash on M-card");
650 if( hname_validate(zUuid,sz)==HNAME_NONE ){
651 SYNTAX("Invalid hash on M-card");
652 }
 
 
 
 
653 if( p->nCChild>=p->nCChildAlloc ){
654 p->nCChildAlloc = p->nCChildAlloc*2 + 10;
655 p->azCChild = fossil_realloc(p->azCChild
656 , p->nCChildAlloc*sizeof(p->azCChild[0]) );
657 }
658 i = p->nCChild++;
659 p->azCChild[i] = zUuid;
660 if( i>0 && fossil_strcmp(p->azCChild[i-1], zUuid)>=0 ){
 
661 SYNTAX("M-card in the wrong order");
662 }
663 break;
664 }
665
@@ -2006,11 +2015,11 @@
2006 static Stmt del1;
2007 tag_insert("cluster", 1, 0, rid, p->rDate, rid);
2008 db_static_prepare(&del1, "DELETE FROM unclustered WHERE rid=:rid");
2009 for(i=0; i<p->nCChild; i++){
2010 int mid;
2011 mid = uuid_to_rid(p->azCChild[i], 1);
2012 if( mid>0 ){
2013 db_bind_int(&del1, ":rid", mid);
2014 db_step(&del1);
2015 db_reset(&del1);
2016 }
2017
--- src/manifest.c
+++ src/manifest.c
@@ -95,12 +95,15 @@
95 struct {
96 char *zCPTarget; /* Hash for cherry-picked version w/ +|- prefix */
97 char *zCPBase; /* Hash for cherry-pick baseline. NULL for singletons */
98 } *aCherrypick;
99 int nCChild; /* Number of cluster children */
100 int nCChildAlloc; /* Number of cluster allocated in aCChild[] */
101 struct {
102 char *zUuid; /* Hashes of referenced objects in cluster. M cards */
103 char *zAlias; /* Alias arguments on a cluster */
104 } *aCChild;
105 int nTag; /* Number of T Cards */
106 int nTagAlloc; /* Slots allocated in aTag[] */
107 struct TagType {
108 char *zName; /* Name of the tag */
109 char *zUuid; /* Hash of artifact that the tag is applied to */
@@ -138,11 +141,11 @@
141 void manifest_destroy(Manifest *p){
142 if( p ){
143 blob_reset(&p->content);
144 fossil_free(p->aFile);
145 fossil_free(p->azParent);
146 fossil_free(p->aCChild);
147 fossil_free(p->aTag);
148 fossil_free(p->aField);
149 fossil_free(p->aCherrypick);
150 if( p->pBaseline ) manifest_destroy(p->pBaseline);
151 memset(p, 0, sizeof(*p));
@@ -643,23 +646,29 @@
646 **
647 ** An M-line identifies another artifact by its hash. M-lines
648 ** occur in clusters only.
649 */
650 case 'M': {
651 char *zAlias;
652 zUuid = next_token(&x, &sz);
653 if( zUuid==0 ) SYNTAX("missing hash on M-card");
654 if( hname_validate(zUuid,sz)==HNAME_NONE ){
655 SYNTAX("Invalid hash on M-card");
656 }
657 zAlias = next_token(&x, &sz);
658 if( zAlias && hname_validate(zAlias,sz)==HNAME_NONE ){
659 SYNTAX("Invalid alias hash on M-card");
660 }
661 if( p->nCChild>=p->nCChildAlloc ){
662 p->nCChildAlloc = p->nCChildAlloc*2 + 10;
663 p->aCChild = fossil_realloc(p->aCChild
664 , p->nCChildAlloc*sizeof(p->aCChild[0]) );
665 }
666 i = p->nCChild++;
667 p->aCChild[i].zUuid = zUuid;
668 p->aCChild[i].zAlias = zAlias;
669 if( i>0 && fossil_strcmp(p->aCChild[i-1].zUuid, zUuid)>=0 ){
670 SYNTAX("M-card in the wrong order");
671 }
672 break;
673 }
674
@@ -2006,11 +2015,11 @@
2015 static Stmt del1;
2016 tag_insert("cluster", 1, 0, rid, p->rDate, rid);
2017 db_static_prepare(&del1, "DELETE FROM unclustered WHERE rid=:rid");
2018 for(i=0; i<p->nCChild; i++){
2019 int mid;
2020 mid = uuid_to_rid(p->aCChild[i].zUuid, 1);
2021 if( mid>0 ){
2022 db_bind_int(&del1, ":rid", mid);
2023 db_step(&del1);
2024 db_reset(&del1);
2025 }
2026
+9 -22
--- src/rebuild.c
+++ src/rebuild.c
@@ -78,26 +78,20 @@
7878
@ mtime INTEGER, -- Time last modified. Seconds since 1970
7979
@ cols TEXT, -- A color-key specification
8080
@ sqlcode TEXT -- An SQL SELECT statement for this report
8181
@ );
8282
;
83
-static const char zCreateHnameTable[] =
84
-@ -- The hname table provides mappings from artifact hashes (hval) to the
85
-@ -- artifact id (rid). This table was added in Fossil-2.0. Prior to
86
-@ -- Fossil-2.0, there was only a single SHA1 hash value for each artifact
87
-@ -- which was stored in the BLOB.UUID field. With the introduction of
88
-@ -- multiple hash algorithms, the hval to rid mapping went from one-to-one to
89
-@ -- many-to-one and a new table became necessary.
83
+static const char zSchemaUpdate3[] =
84
+@ -- Make sure the alias table exists.
9085
@ --
91
-@ CREATE TABLE hname(
86
+@ CREATE TABLE alias(
9287
@ hval TEXT, -- Hex-encoded hash value
93
-@ htype ANY, -- Type of hash. Preferred hash: 0
88
+@ htype ANY, -- Type of hash.
9489
@ rid INTEGER REFERENCES blob, -- Blob that this hash names
9590
@ PRIMARY KEY(hval,htype)
9691
@ ) WITHOUT ROWID;
97
-@ INSERT INTO hname(hval,htype,rid) SELECT uuid,0,rid FROM blob;
98
-@ CREATE INDEX hname_rid ON hname(rid,htype);
92
+@ CREATE INDEX alias_rid ON alias(rid,htype)
9993
;
10094
10195
/*
10296
** Update the schema as necessary
10397
*/
@@ -174,20 +168,13 @@
174168
"ALTER TABLE concealed ADD COLUMN mtime INTEGER;"
175169
"UPDATE concealed SET mtime=now();"
176170
);
177171
}
178172
179
- /* If the hname table is missing, that means we are dealing with an
180
- ** older Fossil 1.x database. Create the hname table an populate it
181
- ** with the SHA1 hash values in the blob.uuid field.
182
- **
183
- ** TODO: After all the rest of the code is updated to use the hname
184
- ** table instead of the blob.uuid column, also delete the blob.uuid
185
- ** column.
186
- */
187
- if( !db_table_exists("repository", "hname") ){
188
- db_multi_exec("%s", zCreateHnameTable/*safe-for-%s*/);
173
+ /* If the alias table is missing, create it. */
174
+ if( !db_table_exists("repository", "alias") ){
175
+ db_multi_exec("%s", zSchemaUpdate3/*safe-for-%s*/);
189176
}
190177
}
191178
192179
/*
193180
** Variables used to store state information about an on-going "rebuild"
@@ -800,11 +787,11 @@
800787
p = manifest_get(rid, CFTYPE_CLUSTER, 0);
801788
if( p==0 ){
802789
fossil_fatal("bad cluster: rid=%d", rid);
803790
}
804791
for(i=0; i<p->nCChild; i++){
805
- const char *zUuid = p->azCChild[i];
792
+ const char *zUuid = p->aCChild[i].zUuid;
806793
int crid = name_to_rid(zUuid);
807794
if( crid==0 ){
808795
fossil_warning("cluster (rid=%d) references unknown artifact %s",
809796
rid, zUuid);
810797
continue;
811798
--- src/rebuild.c
+++ src/rebuild.c
@@ -78,26 +78,20 @@
78 @ mtime INTEGER, -- Time last modified. Seconds since 1970
79 @ cols TEXT, -- A color-key specification
80 @ sqlcode TEXT -- An SQL SELECT statement for this report
81 @ );
82 ;
83 static const char zCreateHnameTable[] =
84 @ -- The hname table provides mappings from artifact hashes (hval) to the
85 @ -- artifact id (rid). This table was added in Fossil-2.0. Prior to
86 @ -- Fossil-2.0, there was only a single SHA1 hash value for each artifact
87 @ -- which was stored in the BLOB.UUID field. With the introduction of
88 @ -- multiple hash algorithms, the hval to rid mapping went from one-to-one to
89 @ -- many-to-one and a new table became necessary.
90 @ --
91 @ CREATE TABLE hname(
92 @ hval TEXT, -- Hex-encoded hash value
93 @ htype ANY, -- Type of hash. Preferred hash: 0
94 @ rid INTEGER REFERENCES blob, -- Blob that this hash names
95 @ PRIMARY KEY(hval,htype)
96 @ ) WITHOUT ROWID;
97 @ INSERT INTO hname(hval,htype,rid) SELECT uuid,0,rid FROM blob;
98 @ CREATE INDEX hname_rid ON hname(rid,htype);
99 ;
100
101 /*
102 ** Update the schema as necessary
103 */
@@ -174,20 +168,13 @@
174 "ALTER TABLE concealed ADD COLUMN mtime INTEGER;"
175 "UPDATE concealed SET mtime=now();"
176 );
177 }
178
179 /* If the hname table is missing, that means we are dealing with an
180 ** older Fossil 1.x database. Create the hname table an populate it
181 ** with the SHA1 hash values in the blob.uuid field.
182 **
183 ** TODO: After all the rest of the code is updated to use the hname
184 ** table instead of the blob.uuid column, also delete the blob.uuid
185 ** column.
186 */
187 if( !db_table_exists("repository", "hname") ){
188 db_multi_exec("%s", zCreateHnameTable/*safe-for-%s*/);
189 }
190 }
191
192 /*
193 ** Variables used to store state information about an on-going "rebuild"
@@ -800,11 +787,11 @@
800 p = manifest_get(rid, CFTYPE_CLUSTER, 0);
801 if( p==0 ){
802 fossil_fatal("bad cluster: rid=%d", rid);
803 }
804 for(i=0; i<p->nCChild; i++){
805 const char *zUuid = p->azCChild[i];
806 int crid = name_to_rid(zUuid);
807 if( crid==0 ){
808 fossil_warning("cluster (rid=%d) references unknown artifact %s",
809 rid, zUuid);
810 continue;
811
--- src/rebuild.c
+++ src/rebuild.c
@@ -78,26 +78,20 @@
78 @ mtime INTEGER, -- Time last modified. Seconds since 1970
79 @ cols TEXT, -- A color-key specification
80 @ sqlcode TEXT -- An SQL SELECT statement for this report
81 @ );
82 ;
83 static const char zSchemaUpdate3[] =
84 @ -- Make sure the alias table exists.
 
 
 
 
 
85 @ --
86 @ CREATE TABLE alias(
87 @ hval TEXT, -- Hex-encoded hash value
88 @ htype ANY, -- Type of hash.
89 @ rid INTEGER REFERENCES blob, -- Blob that this hash names
90 @ PRIMARY KEY(hval,htype)
91 @ ) WITHOUT ROWID;
92 @ CREATE INDEX alias_rid ON alias(rid,htype)
 
93 ;
94
95 /*
96 ** Update the schema as necessary
97 */
@@ -174,20 +168,13 @@
168 "ALTER TABLE concealed ADD COLUMN mtime INTEGER;"
169 "UPDATE concealed SET mtime=now();"
170 );
171 }
172
173 /* If the alias table is missing, create it. */
174 if( !db_table_exists("repository", "alias") ){
175 db_multi_exec("%s", zSchemaUpdate3/*safe-for-%s*/);
 
 
 
 
 
 
 
176 }
177 }
178
179 /*
180 ** Variables used to store state information about an on-going "rebuild"
@@ -800,11 +787,11 @@
787 p = manifest_get(rid, CFTYPE_CLUSTER, 0);
788 if( p==0 ){
789 fossil_fatal("bad cluster: rid=%d", rid);
790 }
791 for(i=0; i<p->nCChild; i++){
792 const char *zUuid = p->aCChild[i].zUuid;
793 int crid = name_to_rid(zUuid);
794 if( crid==0 ){
795 fossil_warning("cluster (rid=%d) references unknown artifact %s",
796 rid, zUuid);
797 continue;
798
+11 -9
--- src/schema.c
+++ src/schema.c
@@ -79,11 +79,11 @@
7979
@ --
8080
@ CREATE TABLE blob(
8181
@ rid INTEGER PRIMARY KEY, -- Record ID
8282
@ rcvid INTEGER, -- Origin of this record
8383
@ size INTEGER, -- Size of content. -1 for a phantom.
84
-@ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content
84
+@ uuid TEXT UNIQUE NOT NULL, -- hash of the content
8585
@ content BLOB, -- Compressed content of this record
8686
@ CHECK( length(uuid)==40 AND rid>0 )
8787
@ );
8888
@ CREATE TABLE delta(
8989
@ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed
@@ -107,23 +107,25 @@
107107
@ mtime DATETIME, -- Time of receipt. Julian day.
108108
@ nonce TEXT UNIQUE, -- Nonce used for login
109109
@ ipaddr TEXT -- Remote IP address. NULL for direct.
110110
@ );
111111
@
112
-@ -- The hname table maps hash values (hval) into artifact IDs (rid).
113
-@ -- Prior to Fossil 2.0 (early 2017) there was only a single SHA1 hash
114
-@ -- value, and so the one-to-one mapping was accomplished using the
115
-@ -- BLOB.UUID column. Beginning with 2.0, the mapping is many-to-one
116
-@ -- and so a separate table became necessary.
112
+@ -- The canonical name of each artifact is given by the BLOB.UUID field.
113
+@ -- But artifacts can also have aliases. Aliases arise, for example, when
114
+@ -- the naming hash algorithm changes, or as a result of trying to provide
115
+@ -- compatibility with a different VCS.
116
+@ --
117
+@ -- Each entry in the ALIAS table provides an alternative name by which an
118
+@ -- artifact can be called.
117119
@ --
118
-@ CREATE TABLE hname(
120
+@ CREATE TABLE alias(
119121
@ hval TEXT, -- Hex-encoded hash value
120
-@ htype ANY, -- Type of hash. Preferred hash: 0
122
+@ htype ANY, -- Type of hash.
121123
@ rid INTEGER REFERENCES blob, -- Blob that this hash names
122124
@ PRIMARY KEY(hval,htype)
123125
@ ) WITHOUT ROWID;
124
-@ CREATE INDEX hname_rid ON hname(rid,htype)
126
+@ CREATE INDEX alias_rid ON alias(rid,htype)
125127
@
126128
@ -- Information about users
127129
@ --
128130
@ -- The user.pw field can be either cleartext of the password, or
129131
@ -- a SHA1 hash of the password. If the user.pw field is exactly 40
130132
--- src/schema.c
+++ src/schema.c
@@ -79,11 +79,11 @@
79 @ --
80 @ CREATE TABLE blob(
81 @ rid INTEGER PRIMARY KEY, -- Record ID
82 @ rcvid INTEGER, -- Origin of this record
83 @ size INTEGER, -- Size of content. -1 for a phantom.
84 @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content
85 @ content BLOB, -- Compressed content of this record
86 @ CHECK( length(uuid)==40 AND rid>0 )
87 @ );
88 @ CREATE TABLE delta(
89 @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed
@@ -107,23 +107,25 @@
107 @ mtime DATETIME, -- Time of receipt. Julian day.
108 @ nonce TEXT UNIQUE, -- Nonce used for login
109 @ ipaddr TEXT -- Remote IP address. NULL for direct.
110 @ );
111 @
112 @ -- The hname table maps hash values (hval) into artifact IDs (rid).
113 @ -- Prior to Fossil 2.0 (early 2017) there was only a single SHA1 hash
114 @ -- value, and so the one-to-one mapping was accomplished using the
115 @ -- BLOB.UUID column. Beginning with 2.0, the mapping is many-to-one
116 @ -- and so a separate table became necessary.
 
 
117 @ --
118 @ CREATE TABLE hname(
119 @ hval TEXT, -- Hex-encoded hash value
120 @ htype ANY, -- Type of hash. Preferred hash: 0
121 @ rid INTEGER REFERENCES blob, -- Blob that this hash names
122 @ PRIMARY KEY(hval,htype)
123 @ ) WITHOUT ROWID;
124 @ CREATE INDEX hname_rid ON hname(rid,htype)
125 @
126 @ -- Information about users
127 @ --
128 @ -- The user.pw field can be either cleartext of the password, or
129 @ -- a SHA1 hash of the password. If the user.pw field is exactly 40
130
--- src/schema.c
+++ src/schema.c
@@ -79,11 +79,11 @@
79 @ --
80 @ CREATE TABLE blob(
81 @ rid INTEGER PRIMARY KEY, -- Record ID
82 @ rcvid INTEGER, -- Origin of this record
83 @ size INTEGER, -- Size of content. -1 for a phantom.
84 @ uuid TEXT UNIQUE NOT NULL, -- hash of the content
85 @ content BLOB, -- Compressed content of this record
86 @ CHECK( length(uuid)==40 AND rid>0 )
87 @ );
88 @ CREATE TABLE delta(
89 @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed
@@ -107,23 +107,25 @@
107 @ mtime DATETIME, -- Time of receipt. Julian day.
108 @ nonce TEXT UNIQUE, -- Nonce used for login
109 @ ipaddr TEXT -- Remote IP address. NULL for direct.
110 @ );
111 @
112 @ -- The canonical name of each artifact is given by the BLOB.UUID field.
113 @ -- But artifacts can also have aliases. Aliases arise, for example, when
114 @ -- the naming hash algorithm changes, or as a result of trying to provide
115 @ -- compatibility with a different VCS.
116 @ --
117 @ -- Each entry in the ALIAS table provides an alternative name by which an
118 @ -- artifact can be called.
119 @ --
120 @ CREATE TABLE alias(
121 @ hval TEXT, -- Hex-encoded hash value
122 @ htype ANY, -- Type of hash.
123 @ rid INTEGER REFERENCES blob, -- Blob that this hash names
124 @ PRIMARY KEY(hval,htype)
125 @ ) WITHOUT ROWID;
126 @ CREATE INDEX alias_rid ON alias(rid,htype)
127 @
128 @ -- Information about users
129 @ --
130 @ -- The user.pw field can be either cleartext of the password, or
131 @ -- a SHA1 hash of the password. If the user.pw field is exactly 40
132
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -27,18 +27,28 @@
2727
with the global state.
2828
The local state is not composed of artifacts and is not intended to be enduring.
2929
This document is concerned with global state only. Local state is only
3030
mentioned here in order to distinguish it from global state.
3131
32
-Each artifact in the repository is named by its SHA1 hash.
32
+Each artifact in the repository is named by a hash of the artifact
33
+content.
3334
No prefixes or meta information is added to an artifact before
34
-its hash is computed. The name of an 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>
35
+its hash is computed.
36
+
37
+Each repository uses a single hash algorithm to compute artifact names.
38
+The default algorithm is currently SHA3-256, though this might change
39
+in future releases of Fossil. Historical versions of Fossil used
40
+SHA1. The hash algorithm for a repository can be changed. When a hash
41
+algorithm change occurs, a set of aliases are set up (using the
42
+two-argument version of the M-card on cluster artifacts) so that the
43
+older hash values can be mapped into the new hash values for artifacts
44
+that were added to the repository before the hash algorithm change.
3745
3846
Some artifacts have a particular format which gives them special
39
-meaning to fossil. Fossil recognizes:
47
+meaning to Fossil. The special artifacts are calls "structural
48
+artifacts". Fossil recognizes the following kinds of structural
49
+artifacts:
4050
4151
<ul>
4252
<li> [#manifest | Manifests] </li>
4353
<li> [#cluster | Clusters] </li>
4454
<li> [#ctrl | Control Artifacts] </li>
@@ -46,13 +56,13 @@
4656
<li> [#tktchng | Ticket Changes] </li>
4757
<li> [#attachment | Attachments] </li>
4858
<li> [#event | TechNotes] </li>
4959
</ul>
5060
51
-These seven artifact types are described in the following sections.
61
+These seven structural artifact types are described in the following sections.
5262
53
-In the current implementation (as of 2009-01-25) the artifacts that
63
+In the current implementation (as of 2017-02-27) the artifacts that
5464
make up a fossil repository are stored as delta- and zlib-compressed
5565
blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
5666
is an implementation detail and might change in a future release. For
5767
the purpose of this article "file format" means the format of the artifacts,
5868
not how the artifacts are stored on disk. It is the artifact format that
@@ -98,14 +108,14 @@
98108
99109
<blockquote>
100110
<b>B</b> <i>baseline-manifest</i><br>
101111
<b>C</b> <i>checkin-comment</i><br>
102112
<b>D</b> <i>time-and-date-stamp</i><br>
103
-<b>F</b> <i>filename</i> ?<i>SHA1-hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br>
113
+<b>F</b> <i>filename</i> ?<i>hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br>
104114
<b>N</b> <i>mimetype</i><br>
105
-<b>P</b> <i>SHA1-hash</i>+<br>
106
-<b>Q</b> (<b>+</b>|<b>-</b>)<i>SHA1-hash</i> ?<i>SHA1-hash</i>?<br>
115
+<b>P</b> <i>artifact-hash</i>+<br>
116
+<b>Q</b> (<b>+</b>|<b>-</b>)<i>artifact-hash</i> ?<i>artifact-hash</i>?<br>
107117
<b>R</b> <i>repository-checksum</i><br>
108118
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
109119
<b>U</b> <i>user-login</i><br>
110120
<b>Z</b> <i>manifest-checksum</i>
111121
</blockquote>
@@ -145,11 +155,11 @@
145155
check-in relative to the root of the project file hierarchy. No ".."
146156
or "." directories are allowed within the filename. Space characters
147157
are escaped as in C-card comment text. Backslash characters and
148158
newlines are not allowed within filenames. The directory separator
149159
character is a forward slash (ASCII 0x2F). The second argument to the
150
-F-card is the full 40-character lower-case hexadecimal SHA1 hash of
160
+F-card is the lower-case hexadecimal artifact hash of
151161
the content artifact. The second argument is required for baseline
152162
manifests but is optional for delta manifests. When the second
153163
argument to the F-card is omitted, it means that the file has been
154164
deleted relative to the baseline (files removed in baseline manifests
155165
versions are <em>not</em> added as F-cards). The optional 3rd argument
@@ -167,14 +177,14 @@
167177
is used.
168178
169179
A manifest has zero or one P-cards. Most manifests have one P-card.
170180
The P-card has a varying number of arguments that
171181
define other manifests from which the current manifest
172
-is derived. Each argument is a 40-character lowercase
173
-hexadecimal SHA1 of a predecessor manifest. All arguments
182
+is derived. Each argument is a lowercase
183
+hexadecimal artifact hash of a predecessor manifest. All arguments
174184
to the P-card must be unique within that card.
175
-The first argument is the SHA1 of the direct ancestor of the manifest.
185
+The first argument is the artifact hash of the direct ancestor of the manifest.
176186
Other arguments define manifests with which the first was
177187
merged to yield the current manifest. Most manifests have
178188
a P-card with a single argument. The first manifest in the
179189
project has no ancestors and thus has no P-card or (depending
180190
on the Fossil version) an empty P-card (no arguments).
@@ -241,13 +251,13 @@
241251
<a name="cluster"></a>
242252
<h2>2.0 Clusters</h2>
243253
244254
A cluster is an artifact that declares the existence of other artifacts.
245255
Clusters are used during repository synchronization to help
246
-reduce network traffic. As such, clusters are an optimization and
247
-may be removed from a repository without loss or damage to the
248
-underlying project code.
256
+reduce network traffic. Clusters are also used to record aliases
257
+for artifact names, so that if the artifact hash algorithm changes,
258
+artifacts can still be looked up using the older hash algorithm.
249259
250260
Clusters follow a syntax that is very similar to manifests.
251261
A cluster is a line-oriented text file. Newline characters
252262
(ASCII 0x0a) separate the artifact into cards. Each card begins with a single
253263
character "card type". Zero or more arguments may follow
@@ -263,17 +273,19 @@
263273
Unlike manifests, clusters are never PGP signed.
264274
265275
Allowed cards in the cluster are as follows:
266276
267277
<blockquote>
268
-<b>M</b> <i>artifact-id</i><br />
278
+<b>M</b> <i>artifact-id</i> ?<i>alias</i><br />
269279
<b>Z</b> <i>checksum</i>
270280
</blockquote>
271281
272282
A cluster contains one or more "M" cards followed by a single "Z"
273
-card. Each M card has a single argument which is the artifact ID of
274
-another artifact in the repository. The Z card works exactly like
283
+card. Each M card has at least on argument which is the artifact ID of
284
+another artifact in the repository. If the M card has a second argument,
285
+the second argument is an alias for the artifact name.
286
+The Z card works exactly like
275287
the Z card of a manifest. The argument to the Z card is the
276288
lower-case hexadecimal representation of the MD5 checksum of all
277289
prior cards in the cluster. The Z-card is required.
278290
279291
An example cluster from Fossil can be seen
@@ -647,11 +659,11 @@
647659
<td>&nbsp;</td>
648660
<td>&nbsp;</td>
649661
<td>&nbsp;</td>
650662
</tr>
651663
<tr>
652
-<td><b>M</b> <i>uuid</i></td>
664
+<td><b>M</b> <i>uuid</i> ?<i>alias</i>?</td>
653665
<td>&nbsp;</td>
654666
<td align=center><b>1+</b></td>
655667
<td>&nbsp;</td>
656668
<td>&nbsp;</td>
657669
<td>&nbsp;</td>
658670
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -27,18 +27,28 @@
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 an artifact before
34 its hash is computed. The name of an 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>
@@ -46,13 +56,13 @@
46 <li> [#tktchng | Ticket Changes] </li>
47 <li> [#attachment | Attachments] </li>
48 <li> [#event | TechNotes] </li>
49 </ul>
50
51 These seven artifact types are described in the following sections.
52
53 In the current implementation (as of 2009-01-25) the artifacts that
54 make up a fossil repository are stored as delta- and zlib-compressed
55 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
56 is an implementation detail and might change in a future release. For
57 the purpose of this article "file format" means the format of the artifacts,
58 not how the artifacts are stored on disk. It is the artifact format that
@@ -98,14 +108,14 @@
98
99 <blockquote>
100 <b>B</b> <i>baseline-manifest</i><br>
101 <b>C</b> <i>checkin-comment</i><br>
102 <b>D</b> <i>time-and-date-stamp</i><br>
103 <b>F</b> <i>filename</i> ?<i>SHA1-hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br>
104 <b>N</b> <i>mimetype</i><br>
105 <b>P</b> <i>SHA1-hash</i>+<br>
106 <b>Q</b> (<b>+</b>|<b>-</b>)<i>SHA1-hash</i> ?<i>SHA1-hash</i>?<br>
107 <b>R</b> <i>repository-checksum</i><br>
108 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
109 <b>U</b> <i>user-login</i><br>
110 <b>Z</b> <i>manifest-checksum</i>
111 </blockquote>
@@ -145,11 +155,11 @@
145 check-in relative to the root of the project file hierarchy. No ".."
146 or "." directories are allowed within the filename. Space characters
147 are escaped as in C-card comment text. Backslash characters and
148 newlines are not allowed within filenames. The directory separator
149 character is a forward slash (ASCII 0x2F). The second argument to the
150 F-card is the full 40-character lower-case hexadecimal SHA1 hash of
151 the content artifact. The second argument is required for baseline
152 manifests but is optional for delta manifests. When the second
153 argument to the F-card is omitted, it means that the file has been
154 deleted relative to the baseline (files removed in baseline manifests
155 versions are <em>not</em> added as F-cards). The optional 3rd argument
@@ -167,14 +177,14 @@
167 is used.
168
169 A manifest has zero or one P-cards. Most manifests have one P-card.
170 The P-card has a varying number of arguments that
171 define other manifests from which the current manifest
172 is derived. Each argument is a 40-character lowercase
173 hexadecimal SHA1 of a predecessor manifest. All arguments
174 to the P-card must be unique within that card.
175 The first argument is the SHA1 of the direct ancestor of the manifest.
176 Other arguments define manifests with which the first was
177 merged to yield the current manifest. Most manifests have
178 a P-card with a single argument. The first manifest in the
179 project has no ancestors and thus has no P-card or (depending
180 on the Fossil version) an empty P-card (no arguments).
@@ -241,13 +251,13 @@
241 <a name="cluster"></a>
242 <h2>2.0 Clusters</h2>
243
244 A cluster is an artifact that declares the existence of other artifacts.
245 Clusters are used during repository synchronization to help
246 reduce network traffic. As such, clusters are an optimization and
247 may be removed from a repository without loss or damage to the
248 underlying project code.
249
250 Clusters follow a syntax that is very similar to manifests.
251 A cluster is a line-oriented text file. Newline characters
252 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
253 character "card type". Zero or more arguments may follow
@@ -263,17 +273,19 @@
263 Unlike manifests, clusters are never PGP signed.
264
265 Allowed cards in the cluster are as follows:
266
267 <blockquote>
268 <b>M</b> <i>artifact-id</i><br />
269 <b>Z</b> <i>checksum</i>
270 </blockquote>
271
272 A cluster contains one or more "M" cards followed by a single "Z"
273 card. Each M card has a single argument which is the artifact ID of
274 another artifact in the repository. The Z card works exactly like
 
 
275 the Z card of a manifest. The argument to the Z card is the
276 lower-case hexadecimal representation of the MD5 checksum of all
277 prior cards in the cluster. The Z-card is required.
278
279 An example cluster from Fossil can be seen
@@ -647,11 +659,11 @@
647 <td>&nbsp;</td>
648 <td>&nbsp;</td>
649 <td>&nbsp;</td>
650 </tr>
651 <tr>
652 <td><b>M</b> <i>uuid</i></td>
653 <td>&nbsp;</td>
654 <td align=center><b>1+</b></td>
655 <td>&nbsp;</td>
656 <td>&nbsp;</td>
657 <td>&nbsp;</td>
658
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -27,18 +27,28 @@
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 a hash of the artifact
33 content.
34 No prefixes or meta information is added to an artifact before
35 its hash is computed.
36
37 Each repository uses a single hash algorithm to compute artifact names.
38 The default algorithm is currently SHA3-256, though this might change
39 in future releases of Fossil. Historical versions of Fossil used
40 SHA1. The hash algorithm for a repository can be changed. When a hash
41 algorithm change occurs, a set of aliases are set up (using the
42 two-argument version of the M-card on cluster artifacts) so that the
43 older hash values can be mapped into the new hash values for artifacts
44 that were added to the repository before the hash algorithm change.
45
46 Some artifacts have a particular format which gives them special
47 meaning to Fossil. The special artifacts are calls "structural
48 artifacts". Fossil recognizes the following kinds of structural
49 artifacts:
50
51 <ul>
52 <li> [#manifest | Manifests] </li>
53 <li> [#cluster | Clusters] </li>
54 <li> [#ctrl | Control Artifacts] </li>
@@ -46,13 +56,13 @@
56 <li> [#tktchng | Ticket Changes] </li>
57 <li> [#attachment | Attachments] </li>
58 <li> [#event | TechNotes] </li>
59 </ul>
60
61 These seven structural artifact types are described in the following sections.
62
63 In the current implementation (as of 2017-02-27) the artifacts that
64 make up a fossil repository are stored as delta- and zlib-compressed
65 blobs in an <a href="http://www.sqlite.org/">SQLite</a> database. This
66 is an implementation detail and might change in a future release. For
67 the purpose of this article "file format" means the format of the artifacts,
68 not how the artifacts are stored on disk. It is the artifact format that
@@ -98,14 +108,14 @@
108
109 <blockquote>
110 <b>B</b> <i>baseline-manifest</i><br>
111 <b>C</b> <i>checkin-comment</i><br>
112 <b>D</b> <i>time-and-date-stamp</i><br>
113 <b>F</b> <i>filename</i> ?<i>hash</i>? ?<i>permissions</i>? ?<i>old-name</i>?<br>
114 <b>N</b> <i>mimetype</i><br>
115 <b>P</b> <i>artifact-hash</i>+<br>
116 <b>Q</b> (<b>+</b>|<b>-</b>)<i>artifact-hash</i> ?<i>artifact-hash</i>?<br>
117 <b>R</b> <i>repository-checksum</i><br>
118 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name</i> <b>*</b> ?<i>value</i>?<br>
119 <b>U</b> <i>user-login</i><br>
120 <b>Z</b> <i>manifest-checksum</i>
121 </blockquote>
@@ -145,11 +155,11 @@
155 check-in relative to the root of the project file hierarchy. No ".."
156 or "." directories are allowed within the filename. Space characters
157 are escaped as in C-card comment text. Backslash characters and
158 newlines are not allowed within filenames. The directory separator
159 character is a forward slash (ASCII 0x2F). The second argument to the
160 F-card is the lower-case hexadecimal artifact hash of
161 the content artifact. The second argument is required for baseline
162 manifests but is optional for delta manifests. When the second
163 argument to the F-card is omitted, it means that the file has been
164 deleted relative to the baseline (files removed in baseline manifests
165 versions are <em>not</em> added as F-cards). The optional 3rd argument
@@ -167,14 +177,14 @@
177 is used.
178
179 A manifest has zero or one P-cards. Most manifests have one P-card.
180 The P-card has a varying number of arguments that
181 define other manifests from which the current manifest
182 is derived. Each argument is a lowercase
183 hexadecimal artifact hash of a predecessor manifest. All arguments
184 to the P-card must be unique within that card.
185 The first argument is the artifact hash of the direct ancestor of the manifest.
186 Other arguments define manifests with which the first was
187 merged to yield the current manifest. Most manifests have
188 a P-card with a single argument. The first manifest in the
189 project has no ancestors and thus has no P-card or (depending
190 on the Fossil version) an empty P-card (no arguments).
@@ -241,13 +251,13 @@
251 <a name="cluster"></a>
252 <h2>2.0 Clusters</h2>
253
254 A cluster is an artifact that declares the existence of other artifacts.
255 Clusters are used during repository synchronization to help
256 reduce network traffic. Clusters are also used to record aliases
257 for artifact names, so that if the artifact hash algorithm changes,
258 artifacts can still be looked up using the older hash algorithm.
259
260 Clusters follow a syntax that is very similar to manifests.
261 A cluster is a line-oriented text file. Newline characters
262 (ASCII 0x0a) separate the artifact into cards. Each card begins with a single
263 character "card type". Zero or more arguments may follow
@@ -263,17 +273,19 @@
273 Unlike manifests, clusters are never PGP signed.
274
275 Allowed cards in the cluster are as follows:
276
277 <blockquote>
278 <b>M</b> <i>artifact-id</i> ?<i>alias</i><br />
279 <b>Z</b> <i>checksum</i>
280 </blockquote>
281
282 A cluster contains one or more "M" cards followed by a single "Z"
283 card. Each M card has at least on argument which is the artifact ID of
284 another artifact in the repository. If the M card has a second argument,
285 the second argument is an alias for the artifact name.
286 The Z card works exactly like
287 the Z card of a manifest. The argument to the Z card is the
288 lower-case hexadecimal representation of the MD5 checksum of all
289 prior cards in the cluster. The Z-card is required.
290
291 An example cluster from Fossil can be seen
@@ -647,11 +659,11 @@
659 <td>&nbsp;</td>
660 <td>&nbsp;</td>
661 <td>&nbsp;</td>
662 </tr>
663 <tr>
664 <td><b>M</b> <i>uuid</i> ?<i>alias</i>?</td>
665 <td>&nbsp;</td>
666 <td align=center><b>1+</b></td>
667 <td>&nbsp;</td>
668 <td>&nbsp;</td>
669 <td>&nbsp;</td>
670

Keyboard Shortcuts

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