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