Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Record whether or not files have their execute permission bit set. Set or clear the execute permission bit upon checkout. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
33c31f73cde7cb812aa1c2320c114f70 |
| User & Date: | drh 2008-02-21 14:27:34.000 |
Context
|
2008-02-21
| ||
| 16:16 | fixed a small copy/paste error in /setup_ticket check-in: ed26056bb5 user: wanderi1 tags: trunk | |
| 14:27 | Record whether or not files have their execute permission bit set. Set or clear the execute permission bit upon checkout. check-in: 33c31f73cd user: drh tags: trunk | |
|
2008-02-14
| ||
| 02:49 | Continuing work on tickets (still not working right.) Improvements to the web pages. check-in: 3122fc4c7e user: drh tags: trunk | |
Changes
Changes to src/blob.c.
| ︙ | ︙ | |||
239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
** pBig in order to cause p to be nul-terminated. If pBig
** should not be modified, then use blob_str() instead of this
** routine. blob_str() will make a copy of the p if necessary
** to avoid modifying pBig.
*/
char *blob_terminate(Blob *p){
blob_is_init(p);
p->aData[p->nUsed] = 0;
return p->aData;
}
/*
** Compare two blobs.
*/
| > | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
** pBig in order to cause p to be nul-terminated. If pBig
** should not be modified, then use blob_str() instead of this
** routine. blob_str() will make a copy of the p if necessary
** to avoid modifying pBig.
*/
char *blob_terminate(Blob *p){
blob_is_init(p);
if( p->nUsed==0 ) return "";
p->aData[p->nUsed] = 0;
return p->aData;
}
/*
** Compare two blobs.
*/
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
Stmt q;
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 */
Blob manifest;
Blob muuid; /* Manifest uuid */
Blob mcksum; /* Self-checksum on the manifest */
Blob cksum1, cksum2; /* Before and after commit checksums */
Blob cksum1b; /* Checksum recorded in the manifest */
noSign = find_option("nosign","",0)!=0;
| > > | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
Stmt q;
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/" */
Blob filename; /* complete filename */
Blob manifest;
Blob muuid; /* Manifest uuid */
Blob mcksum; /* Self-checksum on the manifest */
Blob cksum1, cksum2; /* Before and after commit checksums */
Blob cksum1b; /* Checksum recorded in the manifest */
noSign = find_option("nosign","",0)!=0;
|
| ︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 |
zDate = db_text(0, "SELECT datetime('now')");
zDate[10] = 'T';
blob_appendf(&manifest, "D %s\n", zDate);
db_prepare(&q,
"SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid"
" WHERE NOT deleted AND vfile.vid=%d"
" ORDER BY 1", vid);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zUuid = db_column_text(&q, 1);
| > > > > > > > > > > > | > | 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
zDate = db_text(0, "SELECT datetime('now')");
zDate[10] = 'T';
blob_appendf(&manifest, "D %s\n", zDate);
db_prepare(&q,
"SELECT pathname, uuid FROM vfile JOIN blob ON vfile.mrid=blob.rid"
" WHERE NOT deleted AND vfile.vid=%d"
" ORDER BY 1", vid);
blob_zero(&filename);
blob_appendf(&filename, "%s/", g.zLocalRoot);
nBasename = blob_size(&filename);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zPerm;
blob_append(&filename, zName, -1);
if( file_isexe(blob_str(&filename)) ){
zPerm = " x";
}else{
zPerm = "";
}
blob_resize(&filename, nBasename);
blob_appendf(&manifest, "F %F %s%s\n", zName, zUuid, zPerm);
}
blob_reset(&filename);
db_finalize(&q);
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
blob_appendf(&manifest, "P %s", zUuid);
db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
db_bind_int(&q2, ":id", 0);
while( db_step(&q2)==SQLITE_ROW ){
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
** Read the manifest file given by vid out of the repository
** and store it in the root of the local check-out.
*/
void manifest_to_disk(int vid){
char *zManFile;
Blob manifest;
Blob hash;
blob_zero(&manifest);
zManFile = mprintf("%smanifest", g.zLocalRoot);
content_get(vid, &manifest);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
blob_zero(&hash);
sha1sum_blob(&manifest, &hash);
| > > > > < > > > > > > > > > > > > > | 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 |
** Read the manifest file given by vid out of the repository
** and store it in the root of the local check-out.
*/
void manifest_to_disk(int vid){
char *zManFile;
Blob manifest;
Blob hash;
Blob filename;
int baseLen;
int i;
Manifest m;
blob_zero(&manifest);
zManFile = mprintf("%smanifest", g.zLocalRoot);
content_get(vid, &manifest);
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);
manifest_parse(&m, &manifest);
blob_zero(&filename);
blob_appendf(&filename, "%s/", g.zLocalRoot);
baseLen = blob_size(&filename);
for(i=0; i<m.nFile; i++){
int isExe;
blob_append(&filename, m.aFile[i].zName, -1);
isExe = m.aFile[i].zPerm && strstr(m.aFile[i].zPerm, "x");
file_setexe(blob_str(&filename), isExe);
blob_resize(&filename, baseLen);
}
blob_reset(&filename);
manifest_clear(&m);
}
/*
** COMMAND: checkout
**
** Usage: %fossil checkout VERSION ?-f|--force?
** Check out a version specified on the command-line. This command
|
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
int file_isfile(const char *zFilename){
struct stat buf;
if( stat(zFilename, &buf)!=0 ){
return 0;
}
return S_ISREG(buf.st_mode);
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename){
struct stat buf;
if( stat(zFilename, &buf)!=0 ){
return 0;
}
return S_ISDIR(buf.st_mode) ? 1 : 2;
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
int file_isfile(const char *zFilename){
struct stat buf;
if( stat(zFilename, &buf)!=0 ){
return 0;
}
return S_ISREG(buf.st_mode);
}
/*
** Return TRUE if the named file is an executable. Return false
** for directories, devices, fifos, symlinks, etc.
*/
int file_isexe(const char *zFilename){
struct stat buf;
if( stat(zFilename, &buf)!=0 ){
return 0;
}
return ((S_IXUSR|S_IXGRP|S_IXOTH)&buf.st_mode)!=0;
}
/*
** Set or clear the execute bit on a file.
*/
void file_setexe(const char *zFilename, int onoff){
#ifndef __MINGW32__
struct stat buf;
if( stat(zFilename, &buf)!=0 ) return;
if( onoff ){
if( (buf.st_mode & 0111)==0 ){
chmod(zFilename, buf.st_mode | 0111);
}
}else{
if( (buf.st_mode & 0111)!=0 ){
chmod(zFilename, buf.st_mode & ~0111);
}
}
#endif
}
/*
** Return 1 if zFilename is a directory. Return 0 if zFilename
** does not exist. Return 2 if zFilename exists but is something
** other than a directory.
*/
int file_isdir(const char *zFilename){
struct stat buf;
if( stat(zFilename, &buf)!=0 ){
return 0;
}
return S_ISDIR(buf.st_mode) ? 1 : 2;
}
/*
** Create the directory named in the argument, if it does not already
** exist. If forceFlag is 1, delete any prior non-directory object
** with the same name.
**
** Return the number of errors.
*/
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
556 557 558 559 560 561 562 |
void vdiff_page(void){
int rid;
Stmt q;
char *zUuid;
login_check_credentials();
if( !g.okHistory ){ login_needed(); return; }
| | | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 |
void vdiff_page(void){
int rid;
Stmt q;
char *zUuid;
login_check_credentials();
if( !g.okHistory ){ login_needed(); return; }
style_header("Baseline Changes");
rid = name_to_rid(PD("name",""));
if( rid==0 ){
cgi_redirect("index");
}
db_prepare(&q,
"SELECT pid, fid, name"
" FROM mlink, filename"
" WHERE mlink.mid=%d"
" AND filename.fnid=mlink.fnid"
" ORDER BY name",
rid
);
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
@ <h2>All Changes In Baseline
hyperlink_to_uuid(zUuid);
@ </h2>
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q,0);
int fid = db_column_int(&q,1);
const char *zName = db_column_text(&q,2);
@ <p><a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></p>
|
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
char *zWikiTitle; /* Name of the wiki page */
char *zTicketUuid; /* UUID for a ticket */
int nFile; /* Number of F lines */
int nFileAlloc; /* Slots allocated in aFile[] */
struct {
char *zName; /* Name of a file */
char *zUuid; /* UUID of the file */
} *aFile;
int nParent; /* Number of parents */
int nParentAlloc; /* Slots allocated in azParent[] */
char **azParent; /* UUIDs of parents */
int nCChild; /* Number of cluster children */
int nCChildAlloc; /* Number of closts allocated in azCChild[] */
char **azCChild; /* UUIDs of referenced objects in a cluster */
| > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
char *zWikiTitle; /* Name of the wiki page */
char *zTicketUuid; /* UUID for a ticket */
int nFile; /* Number of F lines */
int nFileAlloc; /* Slots allocated in aFile[] */
struct {
char *zName; /* Name of a file */
char *zUuid; /* UUID of the file */
char *zPerm; /* File permissions */
} *aFile;
int nParent; /* Number of parents */
int nParentAlloc; /* Slots allocated in azParent[] */
char **azParent; /* UUIDs of parents */
int nCChild; /* Number of cluster children */
int nCChildAlloc; /* Number of closts allocated in azCChild[] */
char **azCChild; /* UUIDs of referenced objects in a cluster */
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
memcpy(p->zUuid, blob_buffer(&selfuuid), UUID_SIZE);
p->zUuid[UUID_SIZE] = 0;
blob_zero(pContent);
pContent = &p->content;
blob_zero(&a1);
blob_zero(&a2);
md5sum_init();
while( blob_line(pContent, &line) ){
char *z = blob_buffer(&line);
lineNo++;
if( z[0]=='-' ){
if( strncmp(z, "-----BEGIN PGP ", 15)!=0 ){
goto manifest_syntax_error;
| > | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
memcpy(p->zUuid, blob_buffer(&selfuuid), UUID_SIZE);
p->zUuid[UUID_SIZE] = 0;
blob_zero(pContent);
pContent = &p->content;
blob_zero(&a1);
blob_zero(&a2);
blob_zero(&a3);
md5sum_init();
while( blob_line(pContent, &line) ){
char *z = blob_buffer(&line);
lineNo++;
if( z[0]=='-' ){
if( strncmp(z, "-----BEGIN PGP ", 15)!=0 ){
goto manifest_syntax_error;
|
| ︙ | ︙ | |||
273 274 275 276 277 278 279 |
}else{
goto manifest_syntax_error;
}
break;
}
/*
| | | < > > > | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
}else{
goto manifest_syntax_error;
}
break;
}
/*
** F <filename> <uuid> ?<permissions>?
**
** Identifies a file in a manifest. Multiple F lines are
** allowed in a manifest. F lines are not allowed in any
** other control file. The filename is fossil-encoded.
*/
case 'F': {
char *zName, *zUuid, *zPerm;
md5sum_step_text(blob_buffer(&line), blob_size(&line));
if( blob_token(&line, &a1)==0 ) goto manifest_syntax_error;
if( blob_token(&line, &a2)==0 ) goto manifest_syntax_error;
zName = blob_terminate(&a1);
zUuid = blob_terminate(&a2);
blob_token(&line, &a3);
zPerm = blob_terminate(&a3);
if( blob_size(&a2)!=UUID_SIZE ) goto manifest_syntax_error;
if( !validate16(zUuid, UUID_SIZE) ) goto manifest_syntax_error;
defossilize(zName);
if( !file_is_simple_pathname(zName) ){
goto manifest_syntax_error;
}
if( p->nFile>=p->nFileAlloc ){
p->nFileAlloc = p->nFileAlloc*2 + 10;
p->aFile = realloc(p->aFile, p->nFileAlloc*sizeof(p->aFile[0]) );
if( p->aFile==0 ) fossil_panic("out of memory");
}
i = p->nFile++;
p->aFile[i].zName = zName;
p->aFile[i].zUuid = zUuid;
p->aFile[i].zPerm = zPerm;
if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){
goto manifest_syntax_error;
}
break;
}
/*
|
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
297 298 299 300 301 302 303 | @ -- The difference between vfile.chnged==2 and a regular add is that @ -- with vfile.chnged==2 we know that the current version of the file @ -- is already in the repository. @ -- @ -- @ CREATE TABLE vfile( @ id INTEGER PRIMARY KEY, -- ID of the checked out file | | | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | @ -- The difference between vfile.chnged==2 and a regular add is that @ -- with vfile.chnged==2 we know that the current version of the file @ -- is already in the repository. @ -- @ -- @ CREATE TABLE vfile( @ id INTEGER PRIMARY KEY, -- ID of the checked out file @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add @ deleted BOOLEAN DEFAULT 0, -- True if deleted @ rid INTEGER, -- Originally from this repository record @ mrid INTEGER, -- Based on this record due to a merge @ pathname TEXT, -- Full pathname @ UNIQUE(pathname,vid) @ ); |
| ︙ | ︙ | |||
319 320 321 322 323 324 325 | @ CREATE TABLE vmerge( @ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged @ merge INTEGER, -- Merged with this record @ UNIQUE(id, merge) @ ); @ ; | < < < < < < < < < < < < < < < | 319 320 321 322 323 324 325 | @ CREATE TABLE vmerge( @ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged @ merge INTEGER, -- Merged with this record @ UNIQUE(id, merge) @ ); @ ; |
Changes to src/update.c.
| ︙ | ︙ | |||
65 66 67 68 69 70 71 |
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("cannot find current version");
}
if( db_exists("SELECT 1 FROM vmerge") ){
fossil_fatal("cannot update an uncommitted merge");
}
| < < < < < < < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("cannot find current version");
}
if( db_exists("SELECT 1 FROM vmerge") ){
fossil_fatal("cannot update an uncommitted merge");
}
if( g.argc==3 ){
tid = name_to_rid(g.argv[2]);
if( tid==0 ){
fossil_fatal("not a version: %s", g.argv[2]);
}
if( !is_a_version(tid) ){
|
| ︙ | ︙ |