Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch exe-permission-fix Excluding Merge-Ins
This is equivalent to a diff from 3c39caac39 to 157eed29f4
2011-02-28
| ||
14:18 | All of the execute permission bit handling appears to be working now, though beta testing would be good. Ticket [baf9b6b11e08c1]. check-in: 3ad119b703 user: drh tags: trunk | |
13:26 | Fix the "revert" command so that it distinguishes between files that were added versus files imported by merge. Added files are not unlinked. Ticket [baf9b6b11e08c1]. Closed-Leaf check-in: 157eed29f4 user: drh tags: exe-permission-fix | |
03:26 | Try to get the "stash" command using execute permission bits correctly. Continuing work on the "revert" command - but it is still not working quite right. Ticket [baf9b6b11e08c1d0b]. check-in: ae3409bf49 user: drh tags: exe-permission-fix | |
2011-02-27
| ||
23:31 | Change the ZIP file generator so that it sets the execute bit approprately. Ticket [baf9b6b11e08c1d]. check-in: b57bc473b0 user: drh tags: trunk | |
22:22 | Untested changes trying to get execute permission to be set correctly following "update", "merge", "stash", etc. Ticket [baf9b6b11e08c1d]. This is a big mess and is going to take some time to get right. check-in: 081aefde56 user: drh tags: exe-permission-fix | |
21:45 | Fix the "revert" command so that it restores the correct execute permission to the file. Ticket [baf9b6b11e08c1] check-in: 3c39caac39 user: drh tags: trunk | |
21:08 | Merge the --private sync enhancement into the trunk. check-in: 8b8cc4f1b7 user: drh tags: trunk | |
Changes to src/add.c.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
#else
if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){
db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath);
}
#endif
else{
db_multi_exec(
"INSERT INTO vfile(vid,deleted,rid,mrid,pathname)"
"VALUES(%d,0,0,0,%Q)", vid, zPath);
}
printf("ADDED %s\n", zPath);
}
blob_reset(&pathname);
}
/*
|
| | > |
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
#else if( db_exists("SELECT 1 FROM vfile WHERE pathname=%Q", zPath) ){ db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath); } #endif else{ db_multi_exec( "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" "VALUES(%d,0,0,0,%Q,%d)", vid, zPath,file_isexe(zName)); } printf("ADDED %s\n", zPath); } blob_reset(&pathname); } /* |
Changes to src/file.c.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
fwrite(zBuf, 1, got, out);
}
fclose(in);
fclose(out);
}
/*
** Set or clear the execute bit on a file.
*/
void file_setexe(const char *zFilename, int onoff){
#if !defined(_WIN32)
struct stat buf;
if( stat(zFilename, &buf)!=0 ) return;
if( onoff ){
if( (buf.st_mode & 0111)!=0111 ){
chmod(zFilename, buf.st_mode | 0111);
}
}else{
if( (buf.st_mode & 0111)!=0 ){
chmod(zFilename, buf.st_mode & ~0111);
}
}
#endif /* _WIN32 */
}
/*
** 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.
**
|
| > | > | > > > |
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
fwrite(zBuf, 1, got, out); } fclose(in); fclose(out); } /* ** Set or clear the execute bit on a file. Return true if a change ** occurred and false if this routine is a no-op. */ int file_setexe(const char *zFilename, int onoff){ int rc = 0; #if !defined(_WIN32) struct stat buf; if( stat(zFilename, &buf)!=0 ) return 0; if( onoff ){ if( (buf.st_mode & 0111)!=0111 ){ chmod(zFilename, buf.st_mode | 0111); rc = 1; } }else{ if( (buf.st_mode & 0111)!=0 ){ chmod(zFilename, buf.st_mode & ~0111); rc = 1; } } #endif /* _WIN32 */ return rc; } /* ** 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. ** |
Changes to src/merge.c.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 ... 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 ... 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 ... 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 ... 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 ... 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 ... 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
" idv INTEGER," /* VFILE entry for current version */ " idp INTEGER," /* VFILE entry for the pivot */ " idm INTEGER," /* VFILE entry for version merging in */ " chnged BOOLEAN," /* True if current version has been edited */ " ridv INTEGER," /* Record ID for current version */ " ridp INTEGER," /* Record ID for pivot */ " ridm INTEGER," /* Record ID for merge */ " fnp TEXT," /* The filename in the pivot */ " fnm TEXT" /* the filename in the merged version */ ");" ); /* Add files found in V */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,chnged)" " SELECT pathname, pathname, pathname, id, 0, 0, rid, 0, 0, chnged " " FROM vfile WHERE vid=%d", vid ); /* ** Compute name changes from P->V */ ................................................................................ fossil_free(aChng); db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn"); } /* Add files found in P but not in V */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, 0 " " FROM vfile" " WHERE vid=%d AND pathname NOT IN (SELECT fnp FROM fv)", pid ); /* ** Compute name changes from P->M ................................................................................ } fossil_free(aChng); } /* Add files found in M but not in P or V. */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, 0 " " FROM vfile" " WHERE vid=%d" " AND pathname NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)", mid ); /* ................................................................................ " idm=coalesce((SELECT id FROM vfile WHERE vid=%d AND pathname=fnm),0)," " ridm=coalesce((SELECT rid FROM vfile WHERE vid=%d AND pathname=fnm),0)", pid, pid, mid, mid ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d\n", db_column_int(&q, 0), db_column_int(&q, 5), db_column_int(&q, 6), db_column_int(&q, 7), db_column_int(&q, 4)); printf(" fn = [%s]\n", db_column_text(&q, 1)); printf(" fnp = [%s]\n", db_column_text(&q, 2)); printf(" fnm = [%s]\n", db_column_text(&q, 3)); } db_finalize(&q); } ................................................................................ ); while( db_step(&q)==SQLITE_ROW ){ int idm = db_column_int(&q, 0); int rowid = db_column_int(&q, 1); int idv; const char *zName; db_multi_exec( "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,pathname)" " SELECT %d,3,0,rid,mrid,pathname FROM vfile WHERE id=%d", vid, idm ); idv = db_last_insert_rowid(); db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); zName = db_column_text(&q, 2); printf("ADDED %s\n", zName); if( !nochangeFlag ){ ................................................................................ } db_finalize(&q); /* ** Do a three-way merge on files that have changes on both P->M and P->V. */ db_prepare(&q, "SELECT ridm, idv, ridp, ridv, %s, fn FROM fv" " WHERE idp>0 AND idv>0 AND idm>0" " AND ridm!=ridp AND (ridv!=ridp OR chnged)", glob_expr("fv.fn", zBinGlob) ); while( db_step(&q)==SQLITE_ROW ){ int ridm = db_column_int(&q, 0); int idv = db_column_int(&q, 1); int ridp = db_column_int(&q, 2); int ridv = db_column_int(&q, 3); int isBinary = db_column_int(&q, 4); const char *zName = db_column_text(&q, 5); int rc; char *zFullPath; Blob m, p, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ if( detailFlag ){ printf("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); }else{ ................................................................................ blob_zero(&r); }else{ rc = merge_3way(&p, zFullPath, &m, &r); } if( rc>=0 ){ if( !nochangeFlag ){ blob_write_to_file(&r, zFullPath); } db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); if( rc>0 ){ printf("***** %d merge conflicts in %s\n", rc, zName); nConflict++; } }else{ |
> > | | > | | > | | | | | > | | | > > |
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 ... 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 ... 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 ... 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 ... 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 ... 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 ... 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
" idv INTEGER," /* VFILE entry for current version */ " idp INTEGER," /* VFILE entry for the pivot */ " idm INTEGER," /* VFILE entry for version merging in */ " chnged BOOLEAN," /* True if current version has been edited */ " ridv INTEGER," /* Record ID for current version */ " ridp INTEGER," /* Record ID for pivot */ " ridm INTEGER," /* Record ID for merge */ " isexe BOOLEAN," /* Execute permission enabled */ " fnp TEXT," /* The filename in the pivot */ " fnm TEXT" /* the filename in the merged version */ ");" ); /* Add files found in V */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, id, 0, 0, rid, 0, 0, isexe, chnged " " FROM vfile WHERE vid=%d", vid ); /* ** Compute name changes from P->V */ ................................................................................ fossil_free(aChng); db_multi_exec("UPDATE fv SET fnm=fnp WHERE fnp!=fn"); } /* Add files found in P but not in V */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, isexe, 0 " " FROM vfile" " WHERE vid=%d AND pathname NOT IN (SELECT fnp FROM fv)", pid ); /* ** Compute name changes from P->M ................................................................................ } fossil_free(aChng); } /* Add files found in M but not in P or V. */ db_multi_exec( "INSERT OR IGNORE" " INTO fv(fn,fnp,fnm,idv,idp,idm,ridv,ridp,ridm,isexe,chnged)" " SELECT pathname, pathname, pathname, 0, 0, 0, 0, 0, 0, isexe, 0 " " FROM vfile" " WHERE vid=%d" " AND pathname NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)", mid ); /* ................................................................................ " idm=coalesce((SELECT id FROM vfile WHERE vid=%d AND pathname=fnm),0)," " ridm=coalesce((SELECT rid FROM vfile WHERE vid=%d AND pathname=fnm),0)", pid, pid, mid, mid ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", db_column_int(&q, 0), db_column_int(&q, 5), db_column_int(&q, 6), db_column_int(&q, 7), db_column_int(&q, 4), db_column_int(&q, 8)); printf(" fn = [%s]\n", db_column_text(&q, 1)); printf(" fnp = [%s]\n", db_column_text(&q, 2)); printf(" fnm = [%s]\n", db_column_text(&q, 3)); } db_finalize(&q); } ................................................................................ ); while( db_step(&q)==SQLITE_ROW ){ int idm = db_column_int(&q, 0); int rowid = db_column_int(&q, 1); int idv; const char *zName; db_multi_exec( "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,pathname)" " SELECT %d,3,0,rid,mrid,isexe,pathname FROM vfile WHERE id=%d", vid, idm ); idv = db_last_insert_rowid(); db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); zName = db_column_text(&q, 2); printf("ADDED %s\n", zName); if( !nochangeFlag ){ ................................................................................ } db_finalize(&q); /* ** Do a three-way merge on files that have changes on both P->M and P->V. */ db_prepare(&q, "SELECT ridm, idv, ridp, ridv, %s, fn, isexe FROM fv" " WHERE idp>0 AND idv>0 AND idm>0" " AND ridm!=ridp AND (ridv!=ridp OR chnged)", glob_expr("fv.fn", zBinGlob) ); while( db_step(&q)==SQLITE_ROW ){ int ridm = db_column_int(&q, 0); int idv = db_column_int(&q, 1); int ridp = db_column_int(&q, 2); int ridv = db_column_int(&q, 3); int isBinary = db_column_int(&q, 4); const char *zName = db_column_text(&q, 5); int isExe = db_column_int(&q, 6); int rc; char *zFullPath; Blob m, p, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ if( detailFlag ){ printf("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); }else{ ................................................................................ blob_zero(&r); }else{ rc = merge_3way(&p, zFullPath, &m, &r); } if( rc>=0 ){ if( !nochangeFlag ){ blob_write_to_file(&r, zFullPath); file_setexe(zFullPath, isExe); } db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); if( rc>0 ){ printf("***** %d merge conflicts in %s\n", rc, zName); nConflict++; } }else{ |
Changes to src/stash.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
const char *zOrig = db_column_text(&q, 4); char *zPath = mprintf("%s%s", g.zLocalRoot, zName); Blob content; db_bind_int(&ins, ":rid", rid); db_bind_int(&ins, ":isadd", rid==0); db_bind_int(&ins, ":isrm", deleted); #ifdef _WIN32 db_bind_int(&ins, ":isexe", db_column_int(&q, 1)); #endif db_bind_text(&ins, ":orig", zOrig); db_bind_text(&ins, ":new", zName); if( rid==0 ){ /* A new file */ blob_read_from_file(&content, zPath); db_bind_blob(&ins, ":content", &content); }else if( deleted ){ ................................................................................ "SELECT rid, isRemoved, isExec, origname, newname, delta" " FROM stashfile WHERE stashid=%d", stashid ); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); int isRemoved = db_column_int(&q, 1); const char *zOrig = db_column_text(&q, 3); const char *zNew = db_column_text(&q, 4); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew); Blob delta; undo_save(zNew); blob_zero(&delta); if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); blob_write_to_file(&delta, zNPath); printf("ADD %s\n", zNew); }else if( isRemoved ){ printf("DELETE %s\n", zOrig); unlink(zOPath); }else{ Blob a, b, out, disk; db_ephemeral_blob(&q, 5, &delta); blob_read_from_file(&disk, zOPath); content_get(rid, &a); blob_delta_apply(&a, &delta, &b); if( blob_compare(&disk, &a)==0 ){ blob_write_to_file(&b, zNPath); printf("UPDATE %s\n", zNew); }else{ int rc = merge_3way(&a, zOPath, &b, &out); blob_write_to_file(&out, zNPath); if( rc ){ printf("CONFLICT %s\n", zNew); nConflict++; }else{ printf("MERGE %s\n", zNew); } blob_reset(&out); |
<
<
>
>
>
>
|
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
const char *zOrig = db_column_text(&q, 4); char *zPath = mprintf("%s%s", g.zLocalRoot, zName); Blob content; db_bind_int(&ins, ":rid", rid); db_bind_int(&ins, ":isadd", rid==0); db_bind_int(&ins, ":isrm", deleted); db_bind_int(&ins, ":isexe", db_column_int(&q, 1)); db_bind_text(&ins, ":orig", zOrig); db_bind_text(&ins, ":new", zName); if( rid==0 ){ /* A new file */ blob_read_from_file(&content, zPath); db_bind_blob(&ins, ":content", &content); }else if( deleted ){ ................................................................................ "SELECT rid, isRemoved, isExec, origname, newname, delta" " FROM stashfile WHERE stashid=%d", stashid ); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); int isRemoved = db_column_int(&q, 1); int isExec = db_column_int(&q, 2); const char *zOrig = db_column_text(&q, 3); const char *zNew = db_column_text(&q, 4); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew); Blob delta; undo_save(zNew); blob_zero(&delta); if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); blob_write_to_file(&delta, zNPath); file_setexe(zNPath, isExec); printf("ADD %s\n", zNew); }else if( isRemoved ){ printf("DELETE %s\n", zOrig); unlink(zOPath); }else{ Blob a, b, out, disk; db_ephemeral_blob(&q, 5, &delta); blob_read_from_file(&disk, zOPath); content_get(rid, &a); blob_delta_apply(&a, &delta, &b); if( blob_compare(&disk, &a)==0 ){ blob_write_to_file(&b, zNPath); file_setexe(zNPath, isExec); printf("UPDATE %s\n", zNew); }else{ int rc = merge_3way(&a, zOPath, &b, &out); blob_write_to_file(&out, zNPath); file_setexe(zNPath, isExec); if( rc ){ printf("CONFLICT %s\n", zNew); nConflict++; }else{ printf("MERGE %s\n", zNew); } blob_reset(&out); |
Changes to src/undo.c.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 ... 198 199 200 201 202 203 204 205 206 207 208 209 210 211 ... 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
** true the redo a change. If there is nothing to undo (or redo) then ** this routine is a noop. */ static void undo_one(const char *zPathname, int redoFlag){ Stmt q; char *zFullname; db_prepare(&q, "SELECT content, existsflag FROM undo WHERE pathname=%Q AND redoflag=%d", zPathname, redoFlag ); if( db_step(&q)==SQLITE_ROW ){ int old_exists; int new_exists; Blob current; Blob new; zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname); new_exists = file_size(zFullname)>=0; if( new_exists ){ blob_read_from_file(¤t, zFullname); }else{ blob_zero(¤t); } blob_zero(&new); old_exists = db_column_int(&q, 1); if( old_exists ){ db_ephemeral_blob(&q, 0, &new); } if( old_exists ){ if( new_exists ){ printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); }else{ printf("NEW %s\n", zPathname); } blob_write_to_file(&new, zFullname); }else{ printf("DELETE %s\n", zPathname); unlink(zFullname); } blob_reset(&new); free(zFullname); db_finalize(&q); db_prepare(&q, "UPDATE undo SET content=:c, existsflag=%d, redoflag=NOT redoflag" " WHERE pathname=%Q", new_exists, zPathname ); if( new_exists ){ db_bind_blob(&q, ":c", ¤t); } db_step(&q); blob_reset(¤t); } ................................................................................ int cid; const char *zDb = db_name("localdb"); static const char zSql[] = @ CREATE TABLE %s.undo( @ pathname TEXT UNIQUE, -- Name of the file @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable @ existsflag BOOLEAN, -- True if the file exists @ content BLOB -- Saved content @ ); @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile; @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge; ; if( undoDisable ) return; undo_reset(); ................................................................................ int existsFlag; Stmt q; if( !undoActive ) return; zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); existsFlag = file_size(zFullname)>=0; db_prepare(&q, "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,content)" " VALUES(%Q,0,%d,:c)", zPathname, existsFlag ); if( existsFlag ){ blob_read_from_file(&content, zFullname); db_bind_blob(&q, ":c", &content); } free(zFullname); db_step(&q); |
> | > > > > > > | > | > | | | |
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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 ... 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 ... 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
** true the redo a change. If there is nothing to undo (or redo) then ** this routine is a noop. */ static void undo_one(const char *zPathname, int redoFlag){ Stmt q; char *zFullname; db_prepare(&q, "SELECT content, existsflag, isExe FROM undo" " WHERE pathname=%Q AND redoflag=%d", zPathname, redoFlag ); if( db_step(&q)==SQLITE_ROW ){ int old_exists; int new_exists; int old_exe; int new_exe; Blob current; Blob new; zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname); new_exists = file_size(zFullname)>=0; if( new_exists ){ blob_read_from_file(¤t, zFullname); new_exe = file_isexe(zFullname); }else{ blob_zero(¤t); new_exe = 0; } blob_zero(&new); old_exists = db_column_int(&q, 1); old_exe = db_column_int(&q, 2); if( old_exists ){ db_ephemeral_blob(&q, 0, &new); } if( old_exists ){ if( new_exists ){ printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); }else{ printf("NEW %s\n", zPathname); } blob_write_to_file(&new, zFullname); file_setexe(zFullname, old_exe); }else{ printf("DELETE %s\n", zPathname); unlink(zFullname); } blob_reset(&new); free(zFullname); db_finalize(&q); db_prepare(&q, "UPDATE undo SET content=:c, existsflag=%d, isExe=%d," " redoflag=NOT redoflag" " WHERE pathname=%Q", new_exists, new_exe, zPathname ); if( new_exists ){ db_bind_blob(&q, ":c", ¤t); } db_step(&q); blob_reset(¤t); } ................................................................................ int cid; const char *zDb = db_name("localdb"); static const char zSql[] = @ CREATE TABLE %s.undo( @ pathname TEXT UNIQUE, -- Name of the file @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable @ existsflag BOOLEAN, -- True if the file exists @ isExe BOOLEAN, -- True if the file is executable @ content BLOB -- Saved content @ ); @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile; @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge; ; if( undoDisable ) return; undo_reset(); ................................................................................ int existsFlag; Stmt q; if( !undoActive ) return; zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); existsFlag = file_size(zFullname)>=0; db_prepare(&q, "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,isExe,content)" " VALUES(%Q,0,%d,%d,:c)", zPathname, existsFlag, file_isexe(zFullname) ); if( existsFlag ){ blob_read_from_file(&content, zFullname); db_bind_blob(&q, ":c", &content); } free(zFullname); db_step(&q); |
Changes to src/update.c.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 ... 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 ... 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 ... 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 ... 314 315 316 317 318 319 320 321 322 323 324 325 326 327 ... 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 ... 552 553 554 555 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 586 |
"CREATE TEMP TABLE fv(" " fn TEXT PRIMARY KEY," /* The filename relative to root */ " idv INTEGER," /* VFILE entry for current version */ " idt INTEGER," /* VFILE entry for target version */ " chnged BOOLEAN," /* True if current version has been edited */ " ridv INTEGER," /* Record ID for current version */ " ridt INTEGER," /* Record ID for target */ " fnt TEXT" /* Filename of same file on target version */ ");" ); /* Add files found in the current version */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,chnged)" " SELECT pathname, pathname, id, 0, rid, 0, chnged FROM vfile WHERE vid=%d", vid ); /* Compute file name changes on V->T. Record name changes in files that ** have changed locally. */ find_filename_changes(vid, tid, &nChng, &aChng); ................................................................................ fossil_free(aChng); } /* Add files found in the target version T but missing from the current ** version V. */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,chnged)" " SELECT pathname, pathname, 0, 0, 0, 0, 0 FROM vfile" " WHERE vid=%d" " AND pathname NOT IN (SELECT fnt FROM fv)", tid ); /* ** Compute the file version ids for T ................................................................................ " idt=coalesce((SELECT id FROM vfile WHERE vid=%d AND pathname=fnt),0)," " ridt=coalesce((SELECT rid FROM vfile WHERE vid=%d AND pathname=fnt),0)", tid, tid ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnt, chnged, ridv, ridt FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ printf("%3d: ridv=%-4d ridt=%-4d chnged=%d\n", db_column_int(&q, 0), db_column_int(&q, 4), db_column_int(&q, 5), db_column_int(&q, 3)); printf(" fnv = [%s]\n", db_column_text(&q, 1)); printf(" fnt = [%s]\n", db_column_text(&q, 2)); } db_finalize(&q); } /* If FILES appear on the command-line, remove from the "fv" table ................................................................................ } /* ** Alter the content of the checkout so that it conforms with the ** target */ db_prepare(&q, "SELECT fn, idv, ridv, idt, ridt, chnged, fnt FROM fv ORDER BY 1" ); db_prepare(&mtimeXfer, "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" " WHERE id=:idt" ); assert( g.zLocalRoot!=0 ); assert( strlen(g.zLocalRoot)>1 ); ................................................................................ const char *zName = db_column_text(&q, 0); /* The filename from root */ int idv = db_column_int(&q, 1); /* VFILE entry for current */ int ridv = db_column_int(&q, 2); /* RecordID for current */ int idt = db_column_int(&q, 3); /* VFILE entry for target */ int ridt = db_column_int(&q, 4); /* RecordID for target */ int chnged = db_column_int(&q, 5); /* Current is edited */ const char *zNewName = db_column_text(&q,6);/* New filename */ char *zFullPath; /* Full pathname of the file */ char *zFullNewPath; /* Full pathname of dest */ char nameChng; /* True if the name changed */ zFullPath = mprintf("%s%s", g.zLocalRoot, zName); zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); nameChng = fossil_strcmp(zName, zNewName); ................................................................................ printf("MERGE %s\n", zName); } undo_save(zName); content_get(ridt, &t); content_get(ridv, &v); rc = merge_3way(&v, zFullPath, &t, &r); if( rc>=0 ){ if( !nochangeFlag ) blob_write_to_file(&r, zFullNewPath); if( rc>0 ){ printf("***** %d merge conflicts in %s\n", rc, zNewName); nConflict++; } }else{ if( !nochangeFlag ) blob_write_to_file(&t, zFullNewPath); printf("***** Cannot merge binary file %s\n", zNewName); nConflict++; } if( nameChng && !nochangeFlag ) unlink(zFullPath); blob_reset(&v); blob_reset(&t); blob_reset(&r); ................................................................................ db_prepare(&q, "SELECT name FROM torevert"); if( zRevision==0 ){ int vid = db_lget_int("checkout", 0); zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); } while( db_step(&q)==SQLITE_ROW ){ int isExe = 0; zFile = db_column_text(&q, 0); errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); if( errCode==2 ){ fossil_warning("file not in repository: %s", zFile); }else{ char *zFull = mprintf("%/%/", g.zLocalRoot, zFile); undo_save(zFile); blob_write_to_file(&record, zFull); file_setexe(zFull, isExe); printf("REVERTED: %s\n", zFile); if( zRevision==0 ){ sqlite3_int64 mtime = file_mtime(zFull); db_multi_exec( "UPDATE vfile" " SET mtime=%lld, chnged=0, deleted=0, isexe=%d," " pathname=coalesce(origname,pathname), origname=NULL" " WHERE pathname=%Q", mtime, isExe, zFile ); } free(zFull); } blob_reset(&record); } db_finalize(&q); undo_finish(); db_end_transaction(0); } |
> | | > | | | | | > | > > | > > > | > > > > < > > | < > > > > > > > < | | | | | | | | | < < > |
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 ... 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 ... 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 ... 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 ... 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 ... 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 ... 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
"CREATE TEMP TABLE fv(" " fn TEXT PRIMARY KEY," /* The filename relative to root */ " idv INTEGER," /* VFILE entry for current version */ " idt INTEGER," /* VFILE entry for target version */ " chnged BOOLEAN," /* True if current version has been edited */ " ridv INTEGER," /* Record ID for current version */ " ridt INTEGER," /* Record ID for target */ " isexe BOOLEAN," /* Does target have execute permission? */ " fnt TEXT" /* Filename of same file on target version */ ");" ); /* Add files found in the current version */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged)" " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged" " FROM vfile WHERE vid=%d", vid ); /* Compute file name changes on V->T. Record name changes in files that ** have changed locally. */ find_filename_changes(vid, tid, &nChng, &aChng); ................................................................................ fossil_free(aChng); } /* Add files found in the target version T but missing from the current ** version V. */ db_multi_exec( "INSERT OR IGNORE INTO fv(fn,fnt,idv,idt,ridv,ridt,isexe,chnged)" " SELECT pathname, pathname, 0, 0, 0, 0, isexe, 0 FROM vfile" " WHERE vid=%d" " AND pathname NOT IN (SELECT fnt FROM fv)", tid ); /* ** Compute the file version ids for T ................................................................................ " idt=coalesce((SELECT id FROM vfile WHERE vid=%d AND pathname=fnt),0)," " ridt=coalesce((SELECT rid FROM vfile WHERE vid=%d AND pathname=fnt),0)", tid, tid ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ printf("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", db_column_int(&q, 0), db_column_int(&q, 4), db_column_int(&q, 5), db_column_int(&q, 3), db_column_int(&q, 6)); printf(" fnv = [%s]\n", db_column_text(&q, 1)); printf(" fnt = [%s]\n", db_column_text(&q, 2)); } db_finalize(&q); } /* If FILES appear on the command-line, remove from the "fv" table ................................................................................ } /* ** Alter the content of the checkout so that it conforms with the ** target */ db_prepare(&q, "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe FROM fv ORDER BY 1" ); db_prepare(&mtimeXfer, "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)" " WHERE id=:idt" ); assert( g.zLocalRoot!=0 ); assert( strlen(g.zLocalRoot)>1 ); ................................................................................ const char *zName = db_column_text(&q, 0); /* The filename from root */ int idv = db_column_int(&q, 1); /* VFILE entry for current */ int ridv = db_column_int(&q, 2); /* RecordID for current */ int idt = db_column_int(&q, 3); /* VFILE entry for target */ int ridt = db_column_int(&q, 4); /* RecordID for target */ int chnged = db_column_int(&q, 5); /* Current is edited */ const char *zNewName = db_column_text(&q,6);/* New filename */ int isexe = db_column_int(&q, 6); /* EXE perm for new file */ char *zFullPath; /* Full pathname of the file */ char *zFullNewPath; /* Full pathname of dest */ char nameChng; /* True if the name changed */ zFullPath = mprintf("%s%s", g.zLocalRoot, zName); zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); nameChng = fossil_strcmp(zName, zNewName); ................................................................................ printf("MERGE %s\n", zName); } undo_save(zName); content_get(ridt, &t); content_get(ridv, &v); rc = merge_3way(&v, zFullPath, &t, &r); if( rc>=0 ){ if( !nochangeFlag ){ blob_write_to_file(&r, zFullNewPath); file_setexe(zFullNewPath, isexe); } if( rc>0 ){ printf("***** %d merge conflicts in %s\n", rc, zNewName); nConflict++; } }else{ if( !nochangeFlag ){ blob_write_to_file(&t, zFullNewPath); file_setexe(zFullNewPath, isexe); } printf("***** Cannot merge binary file %s\n", zNewName); nConflict++; } if( nameChng && !nochangeFlag ) unlink(zFullPath); blob_reset(&v); blob_reset(&t); blob_reset(&r); ................................................................................ db_prepare(&q, "SELECT name FROM torevert"); if( zRevision==0 ){ int vid = db_lget_int("checkout", 0); zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid); } while( db_step(&q)==SQLITE_ROW ){ int isExe = 0; char *zFull; zFile = db_column_text(&q, 0); zFull = mprintf("%/%/", g.zLocalRoot, zFile); errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); if( errCode==2 ){ if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ printf("UNMANAGE: %s\n", zFile); }else{ undo_save(zFile); unlink(zFull); printf("DELETE: %s\n", zFile); } db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); }else{ sqlite3_int64 mtime; undo_save(zFile); blob_write_to_file(&record, zFull); file_setexe(zFull, isExe); printf("REVERTED: %s\n", zFile); mtime = file_mtime(zFull); db_multi_exec( "UPDATE vfile" " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid," " pathname=coalesce(origname,pathname), origname=NULL" " WHERE pathname=%Q", mtime, isExe, zFile ); } blob_reset(&record); free(zFull); } db_finalize(&q); undo_finish(); db_end_transaction(0); } |
Changes to src/vfile.c.
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 ... 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 ... 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
ManifestFile *pFile; db_begin_transaction(); p = manifest_get(vid, CFTYPE_MANIFEST); if( p==0 ) return; db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid); db_prepare(&ins, "INSERT INTO vfile(vid,rid,mrid,pathname) " " VALUES(:vid,:id,:id,:name)"); db_bind_int(&ins, ":vid", vid); manifest_file_rewind(p); while( (pFile = manifest_file_next(p,0))!=0 ){ if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue; rid = uuid_to_rid(pFile->zUuid, 0); if( rid==0 || content_size(rid, -1)<0 ){ fossil_warning("content missing for %s", pFile->zName); continue; } db_bind_int(&ins, ":id", rid); db_bind_text(&ins, ":name", pFile->zName); db_step(&ins); db_reset(&ins); } db_finalize(&ins); manifest_destroy(p); ................................................................................ int promptFlag /* Prompt user to confirm overwrites */ ){ Stmt q; Blob content; int nRepos = strlen(g.zLocalRoot); if( vid>0 && id==0 ){ db_prepare(&q, "SELECT id, %Q || pathname, mrid" " FROM vfile" " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); }else{ assert( vid==0 && id>0 ); db_prepare(&q, "SELECT id, %Q || pathname, mrid" " FROM vfile" " WHERE id=%d AND mrid>0", g.zLocalRoot, id); } while( db_step(&q)==SQLITE_ROW ){ int id, rid; const char *zName; id = db_column_int(&q, 0); zName = db_column_text(&q, 1); rid = db_column_int(&q, 2); content_get(rid, &content); if( file_is_the_same(&content, zName) ){ blob_reset(&content); continue; } if( promptFlag && file_size(zName)>=0 ){ Blob ans; char *zMsg; char cReply; zMsg = mprintf("overwrite %s (a=always/y/N)? ", zName); ................................................................................ if( cReply=='n' || cReply=='N' ){ blob_reset(&content); continue; } } if( verbose ) printf("%s\n", &zName[nRepos]); blob_write_to_file(&content, zName); blob_reset(&content); db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", file_mtime(zName), id); } db_finalize(&q); } |
| | > | | | > > > > > > |
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 ... 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 ... 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
ManifestFile *pFile; db_begin_transaction(); p = manifest_get(vid, CFTYPE_MANIFEST); if( p==0 ) return; db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid); db_prepare(&ins, "INSERT INTO vfile(vid,isexe,rid,mrid,pathname) " " VALUES(:vid,:isexe,:id,:id,:name)"); db_bind_int(&ins, ":vid", vid); manifest_file_rewind(p); while( (pFile = manifest_file_next(p,0))!=0 ){ if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue; rid = uuid_to_rid(pFile->zUuid, 0); if( rid==0 || content_size(rid, -1)<0 ){ fossil_warning("content missing for %s", pFile->zName); continue; } db_bind_int(&ins, ":isexe", manifest_file_mperm(pFile)); db_bind_int(&ins, ":id", rid); db_bind_text(&ins, ":name", pFile->zName); db_step(&ins); db_reset(&ins); } db_finalize(&ins); manifest_destroy(p); ................................................................................ int promptFlag /* Prompt user to confirm overwrites */ ){ Stmt q; Blob content; int nRepos = strlen(g.zLocalRoot); if( vid>0 && id==0 ){ db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe" " FROM vfile" " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); }else{ assert( vid==0 && id>0 ); db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe" " FROM vfile" " WHERE id=%d AND mrid>0", g.zLocalRoot, id); } while( db_step(&q)==SQLITE_ROW ){ int id, rid, isExe; const char *zName; id = db_column_int(&q, 0); zName = db_column_text(&q, 1); rid = db_column_int(&q, 2); isExe = db_column_int(&q, 3); content_get(rid, &content); if( file_is_the_same(&content, zName) ){ blob_reset(&content); if( file_setexe(zName, isExe) ){ db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", file_mtime(zName), id); } continue; } if( promptFlag && file_size(zName)>=0 ){ Blob ans; char *zMsg; char cReply; zMsg = mprintf("overwrite %s (a=always/y/N)? ", zName); ................................................................................ if( cReply=='n' || cReply=='N' ){ blob_reset(&content); continue; } } if( verbose ) printf("%s\n", &zName[nRepos]); blob_write_to_file(&content, zName); file_setexe(zName, isExe); blob_reset(&content); db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", file_mtime(zName), id); } db_finalize(&q); } |