Overview
SHA1 Hash: | 9fd80090073cc5e781c07d5debab7a3a030503cd |
---|---|
Date: | 2008-11-09 22:43:04 |
User: | drh |
Comment: | Bug fix in the "mv" command. Add filename change tracking to the check-in information screens. You must run rebuild on existing respositories when upgrading to this version of fossil. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/add.c from [905321226f] to [6a50b3b72e].
@@ -194,10 +194,15 @@ file_tree_name(g.argv[2], &orig, 1); db_multi_exec( "INSERT INTO mv VALUES(%B,%B)", &orig, &dest ); }else{ + if( blob_eq(&dest, ".") ){ + blob_reset(&dest); + }else{ + blob_append(&dest, "/", 1); + } for(i=2; i<g.argc-1; i++){ Blob orig; char *zOrig; int nOrig; file_tree_name(g.argv[i], &orig, 1); @@ -218,11 +223,11 @@ zTail = file_tail(zPath); }else{ zTail = &zPath[nOrig+1]; } db_multi_exec( - "INSERT INTO mv VALUES('%s','%s/%s')", + "INSERT INTO mv VALUES('%s','%s%s')", zPath, blob_str(&dest), zTail ); } db_finalize(&q); }
Modified src/info.c from [a90375841a] to [97b0bae401].
@@ -394,30 +394,50 @@ style_header("Baseline Information"); login_anonymous_available(); } db_finalize(&q); showTags(rid, ""); - @ <div class="section">Files Changed</div> + @ <div class="section">File Changes</div> @ <ul> db_prepare(&q, - "SELECT name, pid, fid" + "SELECT a.name, b.name" + " FROM mlink, filename AS a, filename AS b" + " WHERE mid=%d" + " AND a.fnid=mlink.fnid" + " AND b.fnid=mlink.pfnid", + rid + ); + while( db_step(&q)==SQLITE_ROW ){ + const char *zName = db_column_text(&q, 0); + const char *zPrior = db_column_text(&q, 1); + @ <li><b>Renamed:</b> + if( g.okHistory ){ + @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zPrior)</a> to + @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> + }else{ + @ %h(zPrior) to %h(zName)</li> + } + } + db_finalize(&q); + db_prepare(&q, + "SELECT name, pid, fid " " FROM mlink, filename" " WHERE mid=%d" + " AND fid!=pid" " AND filename.fnid=mlink.fnid", rid ); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q, 0); int pid = db_column_int(&q, 1); int fid = db_column_int(&q, 2); - @ <li> if( pid && fid ){ - @ <b>Modified:</b> + @ <li><b>Modified:</b> }else if( fid ){ - @ <b>Added:</b> - }else{ - @ <b>Deleted:</b> + @ <li><b>Added:</b> + }else if( pid ){ + @ <li><b>Deleted:</b> } if( g.okHistory ){ @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a></li> }else{ @ %h(zName)</li>
Modified src/manifest.c from [608b98745d] to [5a2927ef5a].
@@ -65,10 +65,12 @@ int nFileAlloc; /* Slots allocated in aFile[] */ struct { char *zName; /* Name of a file */ char *zUuid; /* UUID of the file */ char *zPerm; /* File permissions */ + char *zPrior; /* Prior name if the name was changed */ + int iRename; /* index of renamed name in prior/next manifest */ } *aFile; int nParent; /* Number of parents */ int nParentAlloc; /* Slots allocated in azParent[] */ char **azParent; /* UUIDs of parents */ int nCChild; /* Number of cluster children */ @@ -300,10 +302,12 @@ if( zPriorName[0] ){ defossilize(zPriorName); if( !file_is_simple_pathname(zPriorName) ){ goto manifest_syntax_error; } + }else{ + zPriorName = 0; } 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"); @@ -310,10 +314,12 @@ } i = p->nFile++; p->aFile[i].zName = zName; p->aFile[i].zUuid = zUuid; p->aFile[i].zPerm = zPerm; + p->aFile[i].zPrior = zPriorName; + p->aFile[i].iRename = -1; if( i>0 && strcmp(p->aFile[i-1].zName, zName)>=0 ){ goto manifest_syntax_error; } break; } @@ -701,18 +707,28 @@ */ static void add_one_mlink( int mid, /* The record ID of the manifest */ const char *zFromUuid, /* UUID for the mlink.pid field */ const char *zToUuid, /* UUID for the mlink.fid field */ - const char *zFilename /* Filename */ + const char *zFilename, /* Filename */ + const char *zPrior /* Previous filename. NULL if unchanged */ ){ - int fnid, pid, fid; + int fnid, pfnid, pid, fid; fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); if( fnid==0 ){ db_multi_exec("INSERT INTO filename(name) VALUES(%Q)", zFilename); fnid = db_last_insert_rowid(); + } + if( zPrior==0 ){ + pfnid = 0; + }else{ + pfnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zPrior); + if( pfnid==0 ){ + db_multi_exec("INSERT INTO filename(name) VALUES(%Q)", zPrior); + pfnid = db_last_insert_rowid(); + } } if( zFromUuid==0 ){ pid = 0; }else{ pid = uuid_to_rid(zFromUuid, 1); @@ -721,22 +737,50 @@ fid = 0; }else{ fid = uuid_to_rid(zToUuid, 1); } db_multi_exec( - "INSERT INTO mlink(mid,pid,fid,fnid)" - "VALUES(%d,%d,%d,%d)", mid, pid, fid, fnid + "INSERT INTO mlink(mid,pid,fid,fnid,pfnid)" + "VALUES(%d,%d,%d,%d,%d)", mid, pid, fid, fnid, pfnid ); if( pid && fid ){ content_deltify(pid, fid, 0); } } /* -** Add mlink table entries associated with manifest cid. -** There is an mlink entry for every file that changed going -** from pid to cid. +** Locate a file named zName in the aFile[] array of the given +** manifest. We assume that filenames are in sorted order. +** Use a binary search. Return turn the index of the matching +** entry. Or return -1 if not found. +*/ +static int find_file_in_manifest(Manifest *p, const char *zName){ + int lwr, upr; + int c; + int i; + lwr = 0; + upr = p->nFile - 1; + while( lwr<=upr ){ + i = (lwr+upr)/2; + c = strcmp(p->aFile[i].zName, zName); + if( c<0 ){ + lwr = i+1; + }else if( c>0 ){ + upr = i-1; + }else{ + return i; + } + } + return -1; +} + +/* +** Add mlink table entries associated with manifest cid. The +** parent manifest is pid. +** +** A single mlink entry is added for every file that changed content +** and/or name going from pid to cid. ** ** Deleted files have mlink.fid=0. ** Added files have mlink.pid=0. ** Edited files have both mlink.pid!=0 and mlink.fid!=0 */ @@ -757,33 +801,64 @@ content_get(cid, &otherContent); } if( blob_size(&otherContent)==0 ) return; if( manifest_parse(&other, &otherContent)==0 ) return; content_deltify(pid, cid, 0); + + /* Use the iRename fields to find the cross-linkage between + ** renamed files. */ + for(j=0; j<pChild->nFile; j++){ + const char *zPrior = pChild->aFile[j].zPrior; + if( zPrior && zPrior[0] ){ + i = find_file_in_manifest(pParent, zPrior); + if( i>=0 ){ + pChild->aFile[j].iRename = i; + pParent->aFile[i].iRename = j; + } + } + } + + /* Construct the mlink entries */ for(i=j=0; i<pParent->nFile && j<pChild->nFile; ){ - int c = strcmp(pParent->aFile[i].zName, pChild->aFile[j].zName); - if( c<0 ){ - add_one_mlink(cid, pParent->aFile[i].zUuid, 0, pParent->aFile[i].zName); + int c; + if( pParent->aFile[i].iRename>=0 ){ + i++; + }else if( (c = strcmp(pParent->aFile[i].zName, pChild->aFile[j].zName))<0 ){ + add_one_mlink(cid, pParent->aFile[i].zUuid,0,pParent->aFile[i].zName,0); i++; }else if( c>0 ){ - add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName); + int rn = pChild->aFile[j].iRename; + if( rn>=0 ){ + add_one_mlink(cid, pParent->aFile[rn].zUuid, pChild->aFile[j].zUuid, + pChild->aFile[j].zName, pParent->aFile[rn].zName); + }else{ + add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName,0); + } j++; }else{ if( strcmp(pParent->aFile[i].zUuid, pChild->aFile[j].zUuid)!=0 ){ - add_one_mlink(cid, pParent->aFile[i].zUuid, pChild->aFile[j].zUuid, - pChild->aFile[j].zName); + add_one_mlink(cid, pParent->aFile[i].zUuid, pChild->aFile[j].zUuid, + pChild->aFile[j].zName, 0); } i++; j++; } } while( i<pParent->nFile ){ - add_one_mlink(cid, pParent->aFile[i].zUuid, 0, pParent->aFile[i].zName); + if( pParent->aFile[i].iRename<0 ){ + add_one_mlink(cid, pParent->aFile[i].zUuid, 0, pParent->aFile[i].zName,0); + } i++; } while( j<pChild->nFile ){ - add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName); + int rn = pChild->aFile[j].iRename; + if( rn>=0 ){ + add_one_mlink(cid, pParent->aFile[rn].zUuid, pChild->aFile[j].zUuid, + pChild->aFile[j].zName, pParent->aFile[rn].zName); + }else{ + add_one_mlink(cid, 0, pChild->aFile[j].zUuid, pChild->aFile[j].zName,0); + } j++; } manifest_clear(&other); }
Modified src/schema.c from [353a2ed8b8] to [d2ac05bf98].
@@ -178,11 +178,12 @@ @ -- @ CREATE TABLE mlink( @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs @ pid INTEGER REFERENCES blob, -- File ID in parent manifest @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest -@ fnid INTEGER REFERENCES filename -- Name of the file +@ fnid INTEGER REFERENCES filename, -- Name of the file +@ pfnid INTEGER REFERENCES filename -- Previous name. 0 if unchanged @ ); @ CREATE INDEX mlink_i1 ON mlink(mid); @ CREATE INDEX mlink_i2 ON mlink(fnid); @ CREATE INDEX mlink_i3 ON mlink(fid); @ CREATE INDEX mlink_i4 ON mlink(pid);