Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Two new settings: "manifest" and "repo-cksum". The first enables the output of the manifest and manifest.uuid files on each checkout. This is now off by default. The second enables repository checksums. It defaults on. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | experimental |
| Files: | files | file ages | folders |
| SHA1: |
2f3b9bd3c5df0640d955d182ff84aa01 |
| User & Date: | drh 2010-10-19 17:54:16.000 |
Context
|
2010-10-19
| ||
| 17:57 | Fix a typo in the file format documentation. check-in: 0f3086bee7 user: drh tags: experimental | |
| 17:54 | Two new settings: "manifest" and "repo-cksum". The first enables the output of the manifest and manifest.uuid files on each checkout. This is now off by default. The second enables repository checksums. It defaults on. check-in: 2f3b9bd3c5 user: drh tags: experimental | |
| 17:01 | Improvements to the file format documentation to better describe the new B-card on manifests. check-in: f56c622b7a user: drh tags: experimental | |
Changes
Changes to src/checkin.c.
| ︙ | ︙ | |||
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
void extra_cmd(void){
Blob path;
Blob repo;
Stmt q;
int n;
const char *zIgnoreFlag = find_option("ignore",0,1);
int allFlag = find_option("dotfiles",0,0)!=0;
db_must_be_within_tree();
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
n = strlen(g.zLocalRoot);
blob_init(&path, g.zLocalRoot, n-1);
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
vfile_scan(0, &path, blob_size(&path), allFlag);
db_prepare(&q,
"SELECT x FROM sfile"
| > | > > | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
void extra_cmd(void){
Blob path;
Blob repo;
Stmt q;
int n;
const char *zIgnoreFlag = find_option("ignore",0,1);
int allFlag = find_option("dotfiles",0,0)!=0;
int outputManifest = db_get_boolean("manifest",0);
db_must_be_within_tree();
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
n = strlen(g.zLocalRoot);
blob_init(&path, g.zLocalRoot, n-1);
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
vfile_scan(0, &path, blob_size(&path), allFlag);
db_prepare(&q,
"SELECT x FROM sfile"
" WHERE x NOT IN ('%s','%s','_FOSSIL_',"
"'_FOSSIL_-journal','.fos','.fos-journal',"
"'_FOSSIL_-wal','_FOSSIL_-shm','.fos-wal',"
"'.fos-shm')"
" AND NOT %s"
" ORDER BY 1",
outputManifest ? "manifest" : "_FOSSIL_",
outputManifest ? "manifest.uuid" : "_FOSSIL_",
glob_expr("x", zIgnoreFlag)
);
if( file_tree_name(g.zRepositoryName, &repo, 0) ){
db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
}
while( db_step(&q)==SQLITE_ROW ){
printf("%s\n", db_column_text(&q, 0));
|
| ︙ | ︙ | |||
599 600 601 602 603 604 605 606 607 608 609 610 611 612 | Stmt q2; char *zUuid, *zDate; int noSign = 0; /* True to omit signing the manifest using GPG */ int isAMerge = 0; /* True if checking in a merge */ int forceFlag = 0; /* Force a fork */ char *zManifestFile; /* Name of the manifest file */ int nBasename; /* Length of "g.zLocalRoot/" */ const char *zBranch; /* Create a new branch with this name */ const char *zBgColor; /* Set background color when branching */ const char *zDateOvrd; /* Override date string */ const char *zUserOvrd; /* Override user name */ const char *zComFile; /* Read commit message from this file */ Blob filename; /* complete filename */ Blob manifest; | > > | 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | Stmt q2; char *zUuid, *zDate; int noSign = 0; /* True to omit signing the manifest using GPG */ int isAMerge = 0; /* True if checking in a merge */ int forceFlag = 0; /* Force a fork */ char *zManifestFile; /* Name of the manifest file */ int nBasename; /* Length of "g.zLocalRoot/" */ int useCksum; /* True if checksums should be computed and verified */ int outputManifest; /* True to output "manifest" and "manifest.uuid" */ const char *zBranch; /* Create a new branch with this name */ const char *zBgColor; /* Set background color when branching */ const char *zDateOvrd; /* Override date string */ const char *zUserOvrd; /* Override user name */ const char *zComFile; /* Read commit message from this file */ Blob filename; /* complete filename */ Blob manifest; |
| ︙ | ︙ | |||
628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
if( zBgColor==0 ) zBgColor = "#fec084"; /* Orange */
}
zDateOvrd = find_option("date-override",0,1);
zUserOvrd = find_option("user-override",0,1);
db_must_be_within_tree();
noSign = db_get_boolean("omitsign", 0)|noSign;
if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
verify_all_options();
/* Get the ID of the parent manifest artifact */
vid = db_lget_int("checkout", 0);
if( content_is_private(vid) ){
g.markPrivate = 1;
}
| > > | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
if( zBgColor==0 ) zBgColor = "#fec084"; /* Orange */
}
zDateOvrd = find_option("date-override",0,1);
zUserOvrd = find_option("user-override",0,1);
db_must_be_within_tree();
noSign = db_get_boolean("omitsign", 0)|noSign;
if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
useCksum = db_get_boolean("repo-cksum", 1);
outputManifest = db_get_boolean("manifest", 0);
verify_all_options();
/* Get the ID of the parent manifest artifact */
vid = db_lget_int("checkout", 0);
if( content_is_private(vid) ){
g.markPrivate = 1;
}
|
| ︙ | ︙ | |||
718 719 720 721 722 723 724 |
*/
if( db_exists("SELECT 1 FROM tagxref"
" WHERE tagid=%d AND rid=%d AND tagtype>0",
TAG_CLOSED, vid) ){
fossil_fatal("cannot commit against a closed leaf");
}
| | | 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 |
*/
if( db_exists("SELECT 1 FROM tagxref"
" WHERE tagid=%d AND rid=%d AND tagtype>0",
TAG_CLOSED, vid) ){
fossil_fatal("cannot commit against a closed leaf");
}
if( useCksum ) vfile_aggregate_checksum_disk(vid, &cksum1);
if( zComment ){
blob_zero(&comment);
blob_append(&comment, zComment, -1);
}else if( zComFile ){
blob_zero(&comment);
blob_read_from_file(&comment, zComFile);
}else{
|
| ︙ | ︙ | |||
841 842 843 844 845 846 847 |
free(zUuid);
}
}
db_finalize(&q2);
}
blob_appendf(&manifest, "\n");
| | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 |
free(zUuid);
}
}
db_finalize(&q2);
}
blob_appendf(&manifest, "\n");
if( useCksum ) blob_appendf(&manifest, "R %b\n", &cksum1);
if( zBranch && zBranch[0] ){
Stmt q;
if( zBgColor && zBgColor[0] ){
blob_appendf(&manifest, "T *bgcolor * %F\n", zBgColor);
}
blob_appendf(&manifest, "T *branch * %F\n", zBranch);
blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
|
| ︙ | ︙ | |||
875 876 877 878 879 880 881 |
Blob ans;
blob_zero(&ans);
prompt_user("unable to sign manifest. continue (y/N)? ", &ans);
if( blob_str(&ans)[0]!='y' ){
fossil_exit(1);
}
}
| | | > | | | | | | | | | | | | | | | | | | | | | | | | > | 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 |
Blob ans;
blob_zero(&ans);
prompt_user("unable to sign manifest. continue (y/N)? ", &ans);
if( blob_str(&ans)[0]!='y' ){
fossil_exit(1);
}
}
if( outputManifest ){
zManifestFile = mprintf("%smanifest", g.zLocalRoot);
blob_write_to_file(&manifest, zManifestFile);
blob_reset(&manifest);
blob_read_from_file(&manifest, zManifestFile);
free(zManifestFile);
}
nvid = content_put(&manifest, 0, 0);
if( nvid==0 ){
fossil_panic("trouble committing manifest: %s", g.zErrMsg);
}
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
manifest_crosslink(nvid, &manifest);
content_deltify(vid, nvid, 0);
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
printf("New_Version: %s\n", zUuid);
if( outputManifest ){
zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
blob_zero(&muuid);
blob_appendf(&muuid, "%s\n", zUuid);
blob_write_to_file(&muuid, zManifestFile);
free(zManifestFile);
blob_reset(&muuid);
}
/* Update the vfile and vmerge tables */
db_multi_exec(
"DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
"DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
"UPDATE vfile SET vid=%d;"
"UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
" WHERE file_is_selected(id);"
, vid, nvid
);
db_lset_int("checkout", nvid);
if( useCksum ){
/* Verify that the repository checksum matches the expected checksum
** calculated before the checkin started (and stored as the R record
** of the manifest file).
*/
vfile_aggregate_checksum_repository(nvid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksum does not match repository after commit");
}
/* Verify that the manifest checksum matches the expected checksum */
vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
if( blob_compare(&cksum1, &cksum1b) ){
fossil_panic("manifest checksum does not agree with manifest: "
"%b versus %b", &cksum1, &cksum1b);
}
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksum does not match manifest after commit: "
"%b versus %b", &cksum1, &cksum2);
}
/* Verify that the commit did not modify any disk images. */
vfile_aggregate_checksum_disk(nvid, &cksum2);
if( blob_compare(&cksum1, &cksum2) ){
fossil_panic("tree checksums before and after commit do not match");
}
}
/* Clear the undo/redo stack */
undo_reset();
/* Commit */
db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
94 95 96 97 98 99 100 |
onoff, vid, zFilename);
}
/*
** Set or clear the execute permission bit (as appropriate) for all
** files in the current check-out.
**
| < | | | < < < < < < > < | | | < < | | | | | | | < | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
onoff, vid, zFilename);
}
/*
** Set or clear the execute permission bit (as appropriate) for all
** files in the current check-out.
**
** If the "manifest" setting is true, then automatically generate
** files named "manifest" and "manifest.uuid" containing, respectively,
** the text of the manifest and the artifact ID of the manifest.
*/
void manifest_to_disk(int vid){
char *zManFile;
Blob manifest;
Blob hash;
Blob filename;
int baseLen;
Manifest *pManifest;
ManifestFile *pFile;
/* Check the EXE permission status of all files
*/
pManifest = manifest_get(vid, CFTYPE_MANIFEST);
if( pManifest==0 ) return;
blob_zero(&filename);
blob_appendf(&filename, "%s/", g.zLocalRoot);
baseLen = blob_size(&filename);
manifest_file_rewind(pManifest);
while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
int isExe;
blob_append(&filename, pFile->zName, -1);
isExe = pFile->zPerm && strstr(pFile->zPerm, "x");
file_setexe(blob_str(&filename), isExe);
set_or_clear_isexe(pFile->zName, vid, isExe);
blob_resize(&filename, baseLen);
}
blob_reset(&filename);
manifest_destroy(pManifest);
if( !db_get_boolean("manifest",0) ) return;
blob_zero(&manifest);
content_get(vid, &manifest);
zManFile = mprintf("%smanifest", g.zLocalRoot);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
blob_zero(&hash);
sha1sum_blob(&manifest, &hash);
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
blob_append(&hash, "\n", 1);
blob_write_to_file(&hash, zManFile);
free(zManFile);
blob_reset(&hash);
}
/*
** COMMAND: checkout
** COMMAND: co
**
** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
1508 1509 1510 1511 1512 1513 1514 |
char const *name; /* Name of the setting */
char const *var; /* Internal variable name used by db_set() */
int width; /* Width of display. 0 for boolean values */
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
| | | | | | | | | > | > | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 |
char const *name; /* Name of the setting */
char const *var; /* Internal variable name used by db_set() */
int width; /* Width of display. 0 for boolean values */
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
{ "auto-captcha", "autocaptcha", 0, "on" },
{ "auto-shun", 0, 0, "on" },
{ "autosync", 0, 0, "on" },
{ "binary-glob", 0, 32, "" },
{ "clearsign", 0, 0, "off" },
{ "diff-command", 0, 16, "" },
{ "dont-push", 0, 0, "off" },
{ "editor", 0, 16, "" },
{ "gdiff-command", 0, 16, "gdiff" },
{ "ignore-glob", 0, 40, "" },
{ "http-port", 0, 16, "8080" },
{ "localauth", 0, 0, "off" },
{ "manifest", 0, 0, "off" },
{ "mtime-changes", 0, 0, "off" },
{ "pgp-command", 0, 32, "gpg --clearsign -o " },
{ "proxy", 0, 32, "off" },
{ "repo-cksum", 0, 0, "on" },
{ "ssh-command", 0, 32, "" },
{ "web-browser", 0, 32, "" },
{ 0,0,0,0 }
};
/*
** COMMAND: settings
|
| ︙ | ︙ | |||
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 | ** ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" ** then only pull operations occur automatically. ** ** binary-glob The VALUE is a comma-separated list of GLOB patterns ** that should be treated as binary files for merging ** purposes. Example: *.xml ** ** clearsign When enabled, fossil will attempt to sign all commits ** with gpg. When disabled (the default), commits will | > > | | 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 | ** ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** Default: on ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" ** then only pull operations occur automatically. ** Default: on ** ** binary-glob The VALUE is a comma-separated list of GLOB patterns ** that should be treated as binary files for merging ** purposes. Example: *.xml ** ** clearsign When enabled, fossil will attempt to sign all commits ** with gpg. When disabled (the default), commits will ** be unsigned. Default: off ** ** diff-command External command to run when performing a diff. ** If undefined, the internal text diff will be used. ** ** dont-push Prevent this repository from pushing from client to ** server. Useful when setting up a private branch. ** |
| ︙ | ︙ | |||
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 | ** Example: *.o,*.obj,*.exe ** ** localauth If enabled, require that HTTP connections from ** 127.0.0.1 be authenticated by password. If ** false, all HTTP requests from localhost have ** unrestricted access to the repository. ** ** mtime-changes Use file modification times (mtimes) to detect when ** files have been modified. (Default "on".) ** ** pgp-command Command used to clear-sign manifests at check-in. ** The default is "gpg --clearsign -o ". ** ** proxy URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined ** then a direct HTTP connection is used. ** ** ssh-command Command used to talk to a remote machine with ** the "ssh://" protocol. ** ** web-browser A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, | > > > > > > > > > | 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 | ** Example: *.o,*.obj,*.exe ** ** localauth If enabled, require that HTTP connections from ** 127.0.0.1 be authenticated by password. If ** false, all HTTP requests from localhost have ** unrestricted access to the repository. ** ** manifest If enabled, automatically create files "manifest" and ** "manifest.uuid" in every checkout. The SQLite and ** Fossil repositories both require this. Default: off. ** ** mtime-changes Use file modification times (mtimes) to detect when ** files have been modified. (Default "on".) ** ** pgp-command Command used to clear-sign manifests at check-in. ** The default is "gpg --clearsign -o ". ** ** proxy URL of the HTTP proxy. If undefined or "off" then ** the "http_proxy" environment variable is consulted. ** If the http_proxy environment variable is undefined ** then a direct HTTP connection is used. ** ** repo-cksum Compute checksums over all files in each checkout ** as a double-check of correctness. Defaults to "on". ** Disable on large repositories for a performance ** improvement. ** ** ssh-command Command used to talk to a remote machine with ** the "ssh://" protocol. ** ** web-browser A shell command used to launch your preferred ** web browser when given a URL as an argument. ** Defaults to "start" on windows, "open" on Mac, |
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
335 336 337 338 339 340 341 |
}
nPrefix = blob_size(&filename);
pManifest = manifest_get(rid, CFTYPE_MANIFEST);
if( pManifest ){
char *zName;
zip_set_timedate(pManifest->rDate);
| > | | | | | | | | | | | | > | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
}
nPrefix = blob_size(&filename);
pManifest = manifest_get(rid, CFTYPE_MANIFEST);
if( pManifest ){
char *zName;
zip_set_timedate(pManifest->rDate);
if( db_get_boolean("manifest", 0) ){
blob_append(&filename, "manifest", -1);
zName = blob_str(&filename);
zip_add_folders(zName);
zip_add_file(zName, &mfile);
sha1sum_blob(&mfile, &hash);
blob_reset(&mfile);
blob_append(&hash, "\n", 1);
blob_resize(&filename, nPrefix);
blob_append(&filename, "manifest.uuid", -1);
zName = blob_str(&filename);
zip_add_file(zName, &hash);
blob_reset(&hash);
}
manifest_file_rewind(pManifest);
while( (pFile = manifest_file_next(pManifest,0))!=0 ){
int fid = uuid_to_rid(pFile->zUuid, 0);
if( fid ){
content_get(fid, &file);
blob_resize(&filename, nPrefix);
blob_append(&filename, pFile->zName, -1);
|
| ︙ | ︙ |