Fossil SCM

All of the execute permission bit handling appears to be working now, though beta testing would be good. Ticket [baf9b6b11e08c1].

drh 2011-02-28 14:18 trunk merge
Commit 3ad119b7036f8f489eb7f309771093582f6f7eae
+3 -2
--- src/add.c
+++ src/add.c
@@ -148,12 +148,13 @@
148148
db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath);
149149
}
150150
#endif
151151
else{
152152
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));
155156
}
156157
printf("ADDED %s\n", zPath);
157158
}
158159
blob_reset(&pathname);
159160
}
160161
--- src/add.c
+++ src/add.c
@@ -148,12 +148,13 @@
148 db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath);
149 }
150 #endif
151 else{
152 db_multi_exec(
153 "INSERT INTO vfile(vid,deleted,rid,mrid,pathname)"
154 "VALUES(%d,0,0,0,%Q)", vid, zPath);
 
155 }
156 printf("ADDED %s\n", zPath);
157 }
158 blob_reset(&pathname);
159 }
160
--- src/add.c
+++ src/add.c
@@ -148,12 +148,13 @@
148 db_multi_exec("UPDATE vfile SET deleted=0 WHERE pathname=%Q", zPath);
149 }
150 #endif
151 else{
152 db_multi_exec(
153 "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)"
154 "VALUES(%d,0,0,0,%Q,%d)",
155 vid, zPath,file_isexe(zName));
156 }
157 printf("ADDED %s\n", zPath);
158 }
159 blob_reset(&pathname);
160 }
161
+8 -3
--- src/file.c
+++ src/file.c
@@ -178,26 +178,31 @@
178178
fclose(in);
179179
fclose(out);
180180
}
181181
182182
/*
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.
184185
*/
185
-void file_setexe(const char *zFilename, int onoff){
186
+int file_setexe(const char *zFilename, int onoff){
187
+ int rc = 0;
186188
#if !defined(_WIN32)
187189
struct stat buf;
188
- if( stat(zFilename, &buf)!=0 ) return;
190
+ if( stat(zFilename, &buf)!=0 ) return 0;
189191
if( onoff ){
190192
if( (buf.st_mode & 0111)!=0111 ){
191193
chmod(zFilename, buf.st_mode | 0111);
194
+ rc = 1;
192195
}
193196
}else{
194197
if( (buf.st_mode & 0111)!=0 ){
195198
chmod(zFilename, buf.st_mode & ~0111);
199
+ rc = 1;
196200
}
197201
}
198202
#endif /* _WIN32 */
203
+ return rc;
199204
}
200205
201206
/*
202207
** Create the directory named in the argument, if it does not already
203208
** exist. If forceFlag is 1, delete any prior non-directory object
204209
--- src/file.c
+++ src/file.c
@@ -178,26 +178,31 @@
178 fclose(in);
179 fclose(out);
180 }
181
182 /*
183 ** Set or clear the execute bit on a file.
 
184 */
185 void file_setexe(const char *zFilename, int onoff){
 
186 #if !defined(_WIN32)
187 struct stat buf;
188 if( stat(zFilename, &buf)!=0 ) return;
189 if( onoff ){
190 if( (buf.st_mode & 0111)!=0111 ){
191 chmod(zFilename, buf.st_mode | 0111);
 
192 }
193 }else{
194 if( (buf.st_mode & 0111)!=0 ){
195 chmod(zFilename, buf.st_mode & ~0111);
 
196 }
197 }
198 #endif /* _WIN32 */
 
199 }
200
201 /*
202 ** Create the directory named in the argument, if it does not already
203 ** exist. If forceFlag is 1, delete any prior non-directory object
204
--- src/file.c
+++ src/file.c
@@ -178,26 +178,31 @@
178 fclose(in);
179 fclose(out);
180 }
181
182 /*
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.
185 */
186 int file_setexe(const char *zFilename, int onoff){
187 int rc = 0;
188 #if !defined(_WIN32)
189 struct stat buf;
190 if( stat(zFilename, &buf)!=0 ) return 0;
191 if( onoff ){
192 if( (buf.st_mode & 0111)!=0111 ){
193 chmod(zFilename, buf.st_mode | 0111);
194 rc = 1;
195 }
196 }else{
197 if( (buf.st_mode & 0111)!=0 ){
198 chmod(zFilename, buf.st_mode & ~0111);
199 rc = 1;
200 }
201 }
202 #endif /* _WIN32 */
203 return rc;
204 }
205
206 /*
207 ** Create the directory named in the argument, if it does not already
208 ** exist. If forceFlag is 1, delete any prior non-directory object
209
+19 -12
--- src/merge.c
+++ src/merge.c
@@ -158,20 +158,22 @@
158158
" idm INTEGER," /* VFILE entry for version merging in */
159159
" chnged BOOLEAN," /* True if current version has been edited */
160160
" ridv INTEGER," /* Record ID for current version */
161161
" ridp INTEGER," /* Record ID for pivot */
162162
" ridm INTEGER," /* Record ID for merge */
163
+ " isexe BOOLEAN," /* Execute permission enabled */
163164
" fnp TEXT," /* The filename in the pivot */
164165
" fnm TEXT" /* the filename in the merged version */
165166
");"
166167
);
167168
168169
/* Add files found in V
169170
*/
170171
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 "
173175
" FROM vfile WHERE vid=%d",
174176
vid
175177
);
176178
177179
/*
@@ -194,12 +196,13 @@
194196
}
195197
196198
/* Add files found in P but not in V
197199
*/
198200
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 "
201204
" FROM vfile"
202205
" WHERE vid=%d AND pathname NOT IN (SELECT fnp FROM fv)",
203206
pid
204207
);
205208
@@ -220,12 +223,13 @@
220223
}
221224
222225
/* Add files found in M but not in P or V.
223226
*/
224227
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 "
227231
" FROM vfile"
228232
" WHERE vid=%d"
229233
" AND pathname NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)",
230234
mid
231235
);
@@ -242,19 +246,20 @@
242246
pid, pid, mid, mid
243247
);
244248
245249
if( debugFlag ){
246250
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"
248252
);
249253
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",
251255
db_column_int(&q, 0),
252256
db_column_int(&q, 5),
253257
db_column_int(&q, 6),
254258
db_column_int(&q, 7),
255
- db_column_int(&q, 4));
259
+ db_column_int(&q, 4),
260
+ db_column_int(&q, 8));
256261
printf(" fn = [%s]\n", db_column_text(&q, 1));
257262
printf(" fnp = [%s]\n", db_column_text(&q, 2));
258263
printf(" fnm = [%s]\n", db_column_text(&q, 3));
259264
}
260265
db_finalize(&q);
@@ -288,12 +293,12 @@
288293
int idm = db_column_int(&q, 0);
289294
int rowid = db_column_int(&q, 1);
290295
int idv;
291296
const char *zName;
292297
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",
295300
vid, idm
296301
);
297302
idv = db_last_insert_rowid();
298303
db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
299304
zName = db_column_text(&q, 2);
@@ -332,11 +337,11 @@
332337
333338
/*
334339
** Do a three-way merge on files that have changes on both P->M and P->V.
335340
*/
336341
db_prepare(&q,
337
- "SELECT ridm, idv, ridp, ridv, %s, fn FROM fv"
342
+ "SELECT ridm, idv, ridp, ridv, %s, fn, isexe FROM fv"
338343
" WHERE idp>0 AND idv>0 AND idm>0"
339344
" AND ridm!=ridp AND (ridv!=ridp OR chnged)",
340345
glob_expr("fv.fn", zBinGlob)
341346
);
342347
while( db_step(&q)==SQLITE_ROW ){
@@ -344,10 +349,11 @@
344349
int idv = db_column_int(&q, 1);
345350
int ridp = db_column_int(&q, 2);
346351
int ridv = db_column_int(&q, 3);
347352
int isBinary = db_column_int(&q, 4);
348353
const char *zName = db_column_text(&q, 5);
354
+ int isExe = db_column_int(&q, 6);
349355
int rc;
350356
char *zFullPath;
351357
Blob m, p, r;
352358
/* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
353359
if( detailFlag ){
@@ -366,10 +372,11 @@
366372
rc = merge_3way(&p, zFullPath, &m, &r);
367373
}
368374
if( rc>=0 ){
369375
if( !nochangeFlag ){
370376
blob_write_to_file(&r, zFullPath);
377
+ file_setexe(zFullPath, isExe);
371378
}
372379
db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
373380
if( rc>0 ){
374381
printf("***** %d merge conflicts in %s\n", rc, zName);
375382
nConflict++;
376383
--- src/merge.c
+++ src/merge.c
@@ -158,20 +158,22 @@
158 " idm INTEGER," /* VFILE entry for version merging in */
159 " chnged BOOLEAN," /* True if current version has been edited */
160 " ridv INTEGER," /* Record ID for current version */
161 " ridp INTEGER," /* Record ID for pivot */
162 " ridm INTEGER," /* Record ID for merge */
 
163 " fnp TEXT," /* The filename in the pivot */
164 " fnm TEXT" /* the filename in the merged version */
165 ");"
166 );
167
168 /* Add files found in V
169 */
170 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 "
 
173 " FROM vfile WHERE vid=%d",
174 vid
175 );
176
177 /*
@@ -194,12 +196,13 @@
194 }
195
196 /* Add files found in P but not in V
197 */
198 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 " FROM vfile"
202 " WHERE vid=%d AND pathname NOT IN (SELECT fnp FROM fv)",
203 pid
204 );
205
@@ -220,12 +223,13 @@
220 }
221
222 /* Add files found in M but not in P or V.
223 */
224 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 "
 
227 " FROM vfile"
228 " WHERE vid=%d"
229 " AND pathname NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)",
230 mid
231 );
@@ -242,19 +246,20 @@
242 pid, pid, mid, mid
243 );
244
245 if( debugFlag ){
246 db_prepare(&q,
247 "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm FROM fv"
248 );
249 while( db_step(&q)==SQLITE_ROW ){
250 printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d\n",
251 db_column_int(&q, 0),
252 db_column_int(&q, 5),
253 db_column_int(&q, 6),
254 db_column_int(&q, 7),
255 db_column_int(&q, 4));
 
256 printf(" fn = [%s]\n", db_column_text(&q, 1));
257 printf(" fnp = [%s]\n", db_column_text(&q, 2));
258 printf(" fnm = [%s]\n", db_column_text(&q, 3));
259 }
260 db_finalize(&q);
@@ -288,12 +293,12 @@
288 int idm = db_column_int(&q, 0);
289 int rowid = db_column_int(&q, 1);
290 int idv;
291 const char *zName;
292 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",
295 vid, idm
296 );
297 idv = db_last_insert_rowid();
298 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
299 zName = db_column_text(&q, 2);
@@ -332,11 +337,11 @@
332
333 /*
334 ** Do a three-way merge on files that have changes on both P->M and P->V.
335 */
336 db_prepare(&q,
337 "SELECT ridm, idv, ridp, ridv, %s, fn FROM fv"
338 " WHERE idp>0 AND idv>0 AND idm>0"
339 " AND ridm!=ridp AND (ridv!=ridp OR chnged)",
340 glob_expr("fv.fn", zBinGlob)
341 );
342 while( db_step(&q)==SQLITE_ROW ){
@@ -344,10 +349,11 @@
344 int idv = db_column_int(&q, 1);
345 int ridp = db_column_int(&q, 2);
346 int ridv = db_column_int(&q, 3);
347 int isBinary = db_column_int(&q, 4);
348 const char *zName = db_column_text(&q, 5);
 
349 int rc;
350 char *zFullPath;
351 Blob m, p, r;
352 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
353 if( detailFlag ){
@@ -366,10 +372,11 @@
366 rc = merge_3way(&p, zFullPath, &m, &r);
367 }
368 if( rc>=0 ){
369 if( !nochangeFlag ){
370 blob_write_to_file(&r, zFullPath);
 
371 }
372 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
373 if( rc>0 ){
374 printf("***** %d merge conflicts in %s\n", rc, zName);
375 nConflict++;
376
--- src/merge.c
+++ src/merge.c
@@ -158,20 +158,22 @@
158 " idm INTEGER," /* VFILE entry for version merging in */
159 " chnged BOOLEAN," /* True if current version has been edited */
160 " ridv INTEGER," /* Record ID for current version */
161 " ridp INTEGER," /* Record ID for pivot */
162 " ridm INTEGER," /* Record ID for merge */
163 " isexe BOOLEAN," /* Execute permission enabled */
164 " fnp TEXT," /* The filename in the pivot */
165 " fnm TEXT" /* the filename in the merged version */
166 ");"
167 );
168
169 /* Add files found in V
170 */
171 db_multi_exec(
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 "
175 " FROM vfile WHERE vid=%d",
176 vid
177 );
178
179 /*
@@ -194,12 +196,13 @@
196 }
197
198 /* Add files found in P but not in V
199 */
200 db_multi_exec(
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 "
204 " FROM vfile"
205 " WHERE vid=%d AND pathname NOT IN (SELECT fnp FROM fv)",
206 pid
207 );
208
@@ -220,12 +223,13 @@
223 }
224
225 /* Add files found in M but not in P or V.
226 */
227 db_multi_exec(
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 "
231 " FROM vfile"
232 " WHERE vid=%d"
233 " AND pathname NOT IN (SELECT fnp FROM fv UNION SELECT fnm FROM fv)",
234 mid
235 );
@@ -242,19 +246,20 @@
246 pid, pid, mid, mid
247 );
248
249 if( debugFlag ){
250 db_prepare(&q,
251 "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv"
252 );
253 while( db_step(&q)==SQLITE_ROW ){
254 printf("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n",
255 db_column_int(&q, 0),
256 db_column_int(&q, 5),
257 db_column_int(&q, 6),
258 db_column_int(&q, 7),
259 db_column_int(&q, 4),
260 db_column_int(&q, 8));
261 printf(" fn = [%s]\n", db_column_text(&q, 1));
262 printf(" fnp = [%s]\n", db_column_text(&q, 2));
263 printf(" fnm = [%s]\n", db_column_text(&q, 3));
264 }
265 db_finalize(&q);
@@ -288,12 +293,12 @@
293 int idm = db_column_int(&q, 0);
294 int rowid = db_column_int(&q, 1);
295 int idv;
296 const char *zName;
297 db_multi_exec(
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",
300 vid, idm
301 );
302 idv = db_last_insert_rowid();
303 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
304 zName = db_column_text(&q, 2);
@@ -332,11 +337,11 @@
337
338 /*
339 ** Do a three-way merge on files that have changes on both P->M and P->V.
340 */
341 db_prepare(&q,
342 "SELECT ridm, idv, ridp, ridv, %s, fn, isexe FROM fv"
343 " WHERE idp>0 AND idv>0 AND idm>0"
344 " AND ridm!=ridp AND (ridv!=ridp OR chnged)",
345 glob_expr("fv.fn", zBinGlob)
346 );
347 while( db_step(&q)==SQLITE_ROW ){
@@ -344,10 +349,11 @@
349 int idv = db_column_int(&q, 1);
350 int ridp = db_column_int(&q, 2);
351 int ridv = db_column_int(&q, 3);
352 int isBinary = db_column_int(&q, 4);
353 const char *zName = db_column_text(&q, 5);
354 int isExe = db_column_int(&q, 6);
355 int rc;
356 char *zFullPath;
357 Blob m, p, r;
358 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */
359 if( detailFlag ){
@@ -366,10 +372,11 @@
372 rc = merge_3way(&p, zFullPath, &m, &r);
373 }
374 if( rc>=0 ){
375 if( !nochangeFlag ){
376 blob_write_to_file(&r, zFullPath);
377 file_setexe(zFullPath, isExe);
378 }
379 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv);
380 if( rc>0 ){
381 printf("***** %d merge conflicts in %s\n", rc, zName);
382 nConflict++;
383
+4 -2
--- src/stash.c
+++ src/stash.c
@@ -92,13 +92,11 @@
9292
Blob content;
9393
9494
db_bind_int(&ins, ":rid", rid);
9595
db_bind_int(&ins, ":isadd", rid==0);
9696
db_bind_int(&ins, ":isrm", deleted);
97
-#ifdef _WIN32
9897
db_bind_int(&ins, ":isexe", db_column_int(&q, 1));
99
-#endif
10098
db_bind_text(&ins, ":orig", zOrig);
10199
db_bind_text(&ins, ":new", zName);
102100
if( rid==0 ){
103101
/* A new file */
104102
blob_read_from_file(&content, zPath);
@@ -175,10 +173,11 @@
175173
stashid
176174
);
177175
while( db_step(&q)==SQLITE_ROW ){
178176
int rid = db_column_int(&q, 0);
179177
int isRemoved = db_column_int(&q, 1);
178
+ int isExec = db_column_int(&q, 2);
180179
const char *zOrig = db_column_text(&q, 3);
181180
const char *zNew = db_column_text(&q, 4);
182181
char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
183182
char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
184183
Blob delta;
@@ -185,10 +184,11 @@
185184
undo_save(zNew);
186185
blob_zero(&delta);
187186
if( rid==0 ){
188187
db_ephemeral_blob(&q, 5, &delta);
189188
blob_write_to_file(&delta, zNPath);
189
+ file_setexe(zNPath, isExec);
190190
printf("ADD %s\n", zNew);
191191
}else if( isRemoved ){
192192
printf("DELETE %s\n", zOrig);
193193
unlink(zOPath);
194194
}else{
@@ -197,14 +197,16 @@
197197
blob_read_from_file(&disk, zOPath);
198198
content_get(rid, &a);
199199
blob_delta_apply(&a, &delta, &b);
200200
if( blob_compare(&disk, &a)==0 ){
201201
blob_write_to_file(&b, zNPath);
202
+ file_setexe(zNPath, isExec);
202203
printf("UPDATE %s\n", zNew);
203204
}else{
204205
int rc = merge_3way(&a, zOPath, &b, &out);
205206
blob_write_to_file(&out, zNPath);
207
+ file_setexe(zNPath, isExec);
206208
if( rc ){
207209
printf("CONFLICT %s\n", zNew);
208210
nConflict++;
209211
}else{
210212
printf("MERGE %s\n", zNew);
211213
--- src/stash.c
+++ src/stash.c
@@ -92,13 +92,11 @@
92 Blob content;
93
94 db_bind_int(&ins, ":rid", rid);
95 db_bind_int(&ins, ":isadd", rid==0);
96 db_bind_int(&ins, ":isrm", deleted);
97 #ifdef _WIN32
98 db_bind_int(&ins, ":isexe", db_column_int(&q, 1));
99 #endif
100 db_bind_text(&ins, ":orig", zOrig);
101 db_bind_text(&ins, ":new", zName);
102 if( rid==0 ){
103 /* A new file */
104 blob_read_from_file(&content, zPath);
@@ -175,10 +173,11 @@
175 stashid
176 );
177 while( db_step(&q)==SQLITE_ROW ){
178 int rid = db_column_int(&q, 0);
179 int isRemoved = db_column_int(&q, 1);
 
180 const char *zOrig = db_column_text(&q, 3);
181 const char *zNew = db_column_text(&q, 4);
182 char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
183 char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
184 Blob delta;
@@ -185,10 +184,11 @@
185 undo_save(zNew);
186 blob_zero(&delta);
187 if( rid==0 ){
188 db_ephemeral_blob(&q, 5, &delta);
189 blob_write_to_file(&delta, zNPath);
 
190 printf("ADD %s\n", zNew);
191 }else if( isRemoved ){
192 printf("DELETE %s\n", zOrig);
193 unlink(zOPath);
194 }else{
@@ -197,14 +197,16 @@
197 blob_read_from_file(&disk, zOPath);
198 content_get(rid, &a);
199 blob_delta_apply(&a, &delta, &b);
200 if( blob_compare(&disk, &a)==0 ){
201 blob_write_to_file(&b, zNPath);
 
202 printf("UPDATE %s\n", zNew);
203 }else{
204 int rc = merge_3way(&a, zOPath, &b, &out);
205 blob_write_to_file(&out, zNPath);
 
206 if( rc ){
207 printf("CONFLICT %s\n", zNew);
208 nConflict++;
209 }else{
210 printf("MERGE %s\n", zNew);
211
--- src/stash.c
+++ src/stash.c
@@ -92,13 +92,11 @@
92 Blob content;
93
94 db_bind_int(&ins, ":rid", rid);
95 db_bind_int(&ins, ":isadd", rid==0);
96 db_bind_int(&ins, ":isrm", deleted);
 
97 db_bind_int(&ins, ":isexe", db_column_int(&q, 1));
 
98 db_bind_text(&ins, ":orig", zOrig);
99 db_bind_text(&ins, ":new", zName);
100 if( rid==0 ){
101 /* A new file */
102 blob_read_from_file(&content, zPath);
@@ -175,10 +173,11 @@
173 stashid
174 );
175 while( db_step(&q)==SQLITE_ROW ){
176 int rid = db_column_int(&q, 0);
177 int isRemoved = db_column_int(&q, 1);
178 int isExec = db_column_int(&q, 2);
179 const char *zOrig = db_column_text(&q, 3);
180 const char *zNew = db_column_text(&q, 4);
181 char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig);
182 char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
183 Blob delta;
@@ -185,10 +184,11 @@
184 undo_save(zNew);
185 blob_zero(&delta);
186 if( rid==0 ){
187 db_ephemeral_blob(&q, 5, &delta);
188 blob_write_to_file(&delta, zNPath);
189 file_setexe(zNPath, isExec);
190 printf("ADD %s\n", zNew);
191 }else if( isRemoved ){
192 printf("DELETE %s\n", zOrig);
193 unlink(zOPath);
194 }else{
@@ -197,14 +197,16 @@
197 blob_read_from_file(&disk, zOPath);
198 content_get(rid, &a);
199 blob_delta_apply(&a, &delta, &b);
200 if( blob_compare(&disk, &a)==0 ){
201 blob_write_to_file(&b, zNPath);
202 file_setexe(zNPath, isExec);
203 printf("UPDATE %s\n", zNew);
204 }else{
205 int rc = merge_3way(&a, zOPath, &b, &out);
206 blob_write_to_file(&out, zNPath);
207 file_setexe(zNPath, isExec);
208 if( rc ){
209 printf("CONFLICT %s\n", zNew);
210 nConflict++;
211 }else{
212 printf("MERGE %s\n", zNew);
213
+15 -6
--- src/undo.c
+++ src/undo.c
@@ -30,27 +30,33 @@
3030
*/
3131
static void undo_one(const char *zPathname, int redoFlag){
3232
Stmt q;
3333
char *zFullname;
3434
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",
3637
zPathname, redoFlag
3738
);
3839
if( db_step(&q)==SQLITE_ROW ){
3940
int old_exists;
4041
int new_exists;
42
+ int old_exe;
43
+ int new_exe;
4144
Blob current;
4245
Blob new;
4346
zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
4447
new_exists = file_size(zFullname)>=0;
4548
if( new_exists ){
4649
blob_read_from_file(&current, zFullname);
50
+ new_exe = file_isexe(zFullname);
4751
}else{
4852
blob_zero(&current);
53
+ new_exe = 0;
4954
}
5055
blob_zero(&new);
5156
old_exists = db_column_int(&q, 1);
57
+ old_exe = db_column_int(&q, 2);
5258
if( old_exists ){
5359
db_ephemeral_blob(&q, 0, &new);
5460
}
5561
if( old_exists ){
5662
if( new_exists ){
@@ -57,21 +63,23 @@
5763
printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
5864
}else{
5965
printf("NEW %s\n", zPathname);
6066
}
6167
blob_write_to_file(&new, zFullname);
68
+ file_setexe(zFullname, old_exe);
6269
}else{
6370
printf("DELETE %s\n", zPathname);
6471
unlink(zFullname);
6572
}
6673
blob_reset(&new);
6774
free(zFullname);
6875
db_finalize(&q);
6976
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"
7179
" WHERE pathname=%Q",
72
- new_exists, zPathname
80
+ new_exists, new_exe, zPathname
7381
);
7482
if( new_exists ){
7583
db_bind_blob(&q, ":c", &current);
7684
}
7785
db_step(&q);
@@ -200,10 +208,11 @@
200208
static const char zSql[] =
201209
@ CREATE TABLE %s.undo(
202210
@ pathname TEXT UNIQUE, -- Name of the file
203211
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
204212
@ existsflag BOOLEAN, -- True if the file exists
213
+ @ isExe BOOLEAN, -- True if the file is executable
205214
@ content BLOB -- Saved content
206215
@ );
207216
@ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
208217
@ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
209218
;
@@ -246,13 +255,13 @@
246255
247256
if( !undoActive ) return;
248257
zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
249258
existsFlag = file_size(zFullname)>=0;
250259
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)
254263
);
255264
if( existsFlag ){
256265
blob_read_from_file(&content, zFullname);
257266
db_bind_blob(&q, ":c", &content);
258267
}
259268
--- src/undo.c
+++ src/undo.c
@@ -30,27 +30,33 @@
30 */
31 static void undo_one(const char *zPathname, int redoFlag){
32 Stmt q;
33 char *zFullname;
34 db_prepare(&q,
35 "SELECT content, existsflag FROM undo WHERE pathname=%Q AND redoflag=%d",
 
36 zPathname, redoFlag
37 );
38 if( db_step(&q)==SQLITE_ROW ){
39 int old_exists;
40 int new_exists;
 
 
41 Blob current;
42 Blob new;
43 zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
44 new_exists = file_size(zFullname)>=0;
45 if( new_exists ){
46 blob_read_from_file(&current, zFullname);
 
47 }else{
48 blob_zero(&current);
 
49 }
50 blob_zero(&new);
51 old_exists = db_column_int(&q, 1);
 
52 if( old_exists ){
53 db_ephemeral_blob(&q, 0, &new);
54 }
55 if( old_exists ){
56 if( new_exists ){
@@ -57,21 +63,23 @@
57 printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
58 }else{
59 printf("NEW %s\n", zPathname);
60 }
61 blob_write_to_file(&new, zFullname);
 
62 }else{
63 printf("DELETE %s\n", zPathname);
64 unlink(zFullname);
65 }
66 blob_reset(&new);
67 free(zFullname);
68 db_finalize(&q);
69 db_prepare(&q,
70 "UPDATE undo SET content=:c, existsflag=%d, redoflag=NOT redoflag"
 
71 " WHERE pathname=%Q",
72 new_exists, zPathname
73 );
74 if( new_exists ){
75 db_bind_blob(&q, ":c", &current);
76 }
77 db_step(&q);
@@ -200,10 +208,11 @@
200 static const char zSql[] =
201 @ CREATE TABLE %s.undo(
202 @ pathname TEXT UNIQUE, -- Name of the file
203 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
204 @ existsflag BOOLEAN, -- True if the file exists
 
205 @ content BLOB -- Saved content
206 @ );
207 @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
208 @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
209 ;
@@ -246,13 +255,13 @@
246
247 if( !undoActive ) return;
248 zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
249 existsFlag = file_size(zFullname)>=0;
250 db_prepare(&q,
251 "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,content)"
252 " VALUES(%Q,0,%d,:c)",
253 zPathname, existsFlag
254 );
255 if( existsFlag ){
256 blob_read_from_file(&content, zFullname);
257 db_bind_blob(&q, ":c", &content);
258 }
259
--- src/undo.c
+++ src/undo.c
@@ -30,27 +30,33 @@
30 */
31 static void undo_one(const char *zPathname, int redoFlag){
32 Stmt q;
33 char *zFullname;
34 db_prepare(&q,
35 "SELECT content, existsflag, isExe FROM undo"
36 " WHERE pathname=%Q AND redoflag=%d",
37 zPathname, redoFlag
38 );
39 if( db_step(&q)==SQLITE_ROW ){
40 int old_exists;
41 int new_exists;
42 int old_exe;
43 int new_exe;
44 Blob current;
45 Blob new;
46 zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname);
47 new_exists = file_size(zFullname)>=0;
48 if( new_exists ){
49 blob_read_from_file(&current, zFullname);
50 new_exe = file_isexe(zFullname);
51 }else{
52 blob_zero(&current);
53 new_exe = 0;
54 }
55 blob_zero(&new);
56 old_exists = db_column_int(&q, 1);
57 old_exe = db_column_int(&q, 2);
58 if( old_exists ){
59 db_ephemeral_blob(&q, 0, &new);
60 }
61 if( old_exists ){
62 if( new_exists ){
@@ -57,21 +63,23 @@
63 printf("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname);
64 }else{
65 printf("NEW %s\n", zPathname);
66 }
67 blob_write_to_file(&new, zFullname);
68 file_setexe(zFullname, old_exe);
69 }else{
70 printf("DELETE %s\n", zPathname);
71 unlink(zFullname);
72 }
73 blob_reset(&new);
74 free(zFullname);
75 db_finalize(&q);
76 db_prepare(&q,
77 "UPDATE undo SET content=:c, existsflag=%d, isExe=%d,"
78 " redoflag=NOT redoflag"
79 " WHERE pathname=%Q",
80 new_exists, new_exe, zPathname
81 );
82 if( new_exists ){
83 db_bind_blob(&q, ":c", &current);
84 }
85 db_step(&q);
@@ -200,10 +208,11 @@
208 static const char zSql[] =
209 @ CREATE TABLE %s.undo(
210 @ pathname TEXT UNIQUE, -- Name of the file
211 @ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
212 @ existsflag BOOLEAN, -- True if the file exists
213 @ isExe BOOLEAN, -- True if the file is executable
214 @ content BLOB -- Saved content
215 @ );
216 @ CREATE TABLE %s.undo_vfile AS SELECT * FROM vfile;
217 @ CREATE TABLE %s.undo_vmerge AS SELECT * FROM vmerge;
218 ;
@@ -246,13 +255,13 @@
255
256 if( !undoActive ) return;
257 zFullname = mprintf("%s%s", g.zLocalRoot, zPathname);
258 existsFlag = file_size(zFullname)>=0;
259 db_prepare(&q,
260 "INSERT OR IGNORE INTO undo(pathname,redoflag,existsflag,isExe,content)"
261 " VALUES(%Q,0,%d,%d,:c)",
262 zPathname, existsFlag, file_isexe(zFullname)
263 );
264 if( existsFlag ){
265 blob_read_from_file(&content, zFullname);
266 db_bind_blob(&q, ":c", &content);
267 }
268
+40 -23
--- src/update.c
+++ src/update.c
@@ -197,19 +197,21 @@
197197
" idv INTEGER," /* VFILE entry for current version */
198198
" idt INTEGER," /* VFILE entry for target version */
199199
" chnged BOOLEAN," /* True if current version has been edited */
200200
" ridv INTEGER," /* Record ID for current version */
201201
" ridt INTEGER," /* Record ID for target */
202
+ " isexe BOOLEAN," /* Does target have execute permission? */
202203
" fnt TEXT" /* Filename of same file on target version */
203204
");"
204205
);
205206
206207
/* Add files found in the current version
207208
*/
208209
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",
211213
vid
212214
);
213215
214216
/* Compute file name changes on V->T. Record name changes in files that
215217
** have changed locally.
@@ -229,12 +231,12 @@
229231
230232
/* Add files found in the target version T but missing from the current
231233
** version V.
232234
*/
233235
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"
236238
" WHERE vid=%d"
237239
" AND pathname NOT IN (SELECT fnt FROM fv)",
238240
tid
239241
);
240242
@@ -248,18 +250,19 @@
248250
tid, tid
249251
);
250252
251253
if( debugFlag ){
252254
db_prepare(&q,
253
- "SELECT rowid, fn, fnt, chnged, ridv, ridt FROM fv"
255
+ "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv"
254256
);
255257
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",
257259
db_column_int(&q, 0),
258260
db_column_int(&q, 4),
259261
db_column_int(&q, 5),
260
- db_column_int(&q, 3));
262
+ db_column_int(&q, 3),
263
+ db_column_int(&q, 6));
261264
printf(" fnv = [%s]\n", db_column_text(&q, 1));
262265
printf(" fnt = [%s]\n", db_column_text(&q, 2));
263266
}
264267
db_finalize(&q);
265268
}
@@ -299,11 +302,11 @@
299302
/*
300303
** Alter the content of the checkout so that it conforms with the
301304
** target
302305
*/
303306
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"
305308
);
306309
db_prepare(&mtimeXfer,
307310
"UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
308311
" WHERE id=:idt"
309312
);
@@ -316,10 +319,11 @@
316319
int ridv = db_column_int(&q, 2); /* RecordID for current */
317320
int idt = db_column_int(&q, 3); /* VFILE entry for target */
318321
int ridt = db_column_int(&q, 4); /* RecordID for target */
319322
int chnged = db_column_int(&q, 5); /* Current is edited */
320323
const char *zNewName = db_column_text(&q,6);/* New filename */
324
+ int isexe = db_column_int(&q, 6); /* EXE perm for new file */
321325
char *zFullPath; /* Full pathname of the file */
322326
char *zFullNewPath; /* Full pathname of dest */
323327
char nameChng; /* True if the name changed */
324328
325329
zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -374,17 +378,23 @@
374378
undo_save(zName);
375379
content_get(ridt, &t);
376380
content_get(ridv, &v);
377381
rc = merge_3way(&v, zFullPath, &t, &r);
378382
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
+ }
380387
if( rc>0 ){
381388
printf("***** %d merge conflicts in %s\n", rc, zNewName);
382389
nConflict++;
383390
}
384391
}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
+ }
386396
printf("***** Cannot merge binary file %s\n", zNewName);
387397
nConflict++;
388398
}
389399
if( nameChng && !nochangeFlag ) unlink(zFullPath);
390400
blob_reset(&v);
@@ -554,33 +564,40 @@
554564
int vid = db_lget_int("checkout", 0);
555565
zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
556566
}
557567
while( db_step(&q)==SQLITE_ROW ){
558568
int isExe = 0;
569
+ char *zFull;
559570
zFile = db_column_text(&q, 0);
571
+ zFull = mprintf("%/%/", g.zLocalRoot, zFile);
560572
errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2);
561573
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);
563582
}else{
564
- char *zFull = mprintf("%/%/", g.zLocalRoot, zFile);
583
+ sqlite3_int64 mtime;
565584
undo_save(zFile);
566585
blob_write_to_file(&record, zFull);
567586
file_setexe(zFull, isExe);
568587
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
+ );
580596
}
581597
blob_reset(&record);
598
+ free(zFull);
582599
}
583600
db_finalize(&q);
584601
undo_finish();
585602
db_end_transaction(0);
586603
}
587604
--- src/update.c
+++ src/update.c
@@ -197,19 +197,21 @@
197 " idv INTEGER," /* VFILE entry for current version */
198 " idt INTEGER," /* VFILE entry for target version */
199 " chnged BOOLEAN," /* True if current version has been edited */
200 " ridv INTEGER," /* Record ID for current version */
201 " ridt INTEGER," /* Record ID for target */
 
202 " fnt TEXT" /* Filename of same file on target version */
203 ");"
204 );
205
206 /* Add files found in the current version
207 */
208 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",
 
211 vid
212 );
213
214 /* Compute file name changes on V->T. Record name changes in files that
215 ** have changed locally.
@@ -229,12 +231,12 @@
229
230 /* Add files found in the target version T but missing from the current
231 ** version V.
232 */
233 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 " WHERE vid=%d"
237 " AND pathname NOT IN (SELECT fnt FROM fv)",
238 tid
239 );
240
@@ -248,18 +250,19 @@
248 tid, tid
249 );
250
251 if( debugFlag ){
252 db_prepare(&q,
253 "SELECT rowid, fn, fnt, chnged, ridv, ridt FROM fv"
254 );
255 while( db_step(&q)==SQLITE_ROW ){
256 printf("%3d: ridv=%-4d ridt=%-4d chnged=%d\n",
257 db_column_int(&q, 0),
258 db_column_int(&q, 4),
259 db_column_int(&q, 5),
260 db_column_int(&q, 3));
 
261 printf(" fnv = [%s]\n", db_column_text(&q, 1));
262 printf(" fnt = [%s]\n", db_column_text(&q, 2));
263 }
264 db_finalize(&q);
265 }
@@ -299,11 +302,11 @@
299 /*
300 ** Alter the content of the checkout so that it conforms with the
301 ** target
302 */
303 db_prepare(&q,
304 "SELECT fn, idv, ridv, idt, ridt, chnged, fnt FROM fv ORDER BY 1"
305 );
306 db_prepare(&mtimeXfer,
307 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
308 " WHERE id=:idt"
309 );
@@ -316,10 +319,11 @@
316 int ridv = db_column_int(&q, 2); /* RecordID for current */
317 int idt = db_column_int(&q, 3); /* VFILE entry for target */
318 int ridt = db_column_int(&q, 4); /* RecordID for target */
319 int chnged = db_column_int(&q, 5); /* Current is edited */
320 const char *zNewName = db_column_text(&q,6);/* New filename */
 
321 char *zFullPath; /* Full pathname of the file */
322 char *zFullNewPath; /* Full pathname of dest */
323 char nameChng; /* True if the name changed */
324
325 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -374,17 +378,23 @@
374 undo_save(zName);
375 content_get(ridt, &t);
376 content_get(ridv, &v);
377 rc = merge_3way(&v, zFullPath, &t, &r);
378 if( rc>=0 ){
379 if( !nochangeFlag ) blob_write_to_file(&r, zFullNewPath);
 
 
 
380 if( rc>0 ){
381 printf("***** %d merge conflicts in %s\n", rc, zNewName);
382 nConflict++;
383 }
384 }else{
385 if( !nochangeFlag ) blob_write_to_file(&t, zFullNewPath);
 
 
 
386 printf("***** Cannot merge binary file %s\n", zNewName);
387 nConflict++;
388 }
389 if( nameChng && !nochangeFlag ) unlink(zFullPath);
390 blob_reset(&v);
@@ -554,33 +564,40 @@
554 int vid = db_lget_int("checkout", 0);
555 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
556 }
557 while( db_step(&q)==SQLITE_ROW ){
558 int isExe = 0;
 
559 zFile = db_column_text(&q, 0);
 
560 errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2);
561 if( errCode==2 ){
562 fossil_warning("file not in repository: %s", zFile);
 
 
 
 
 
 
 
563 }else{
564 char *zFull = mprintf("%/%/", g.zLocalRoot, zFile);
565 undo_save(zFile);
566 blob_write_to_file(&record, zFull);
567 file_setexe(zFull, isExe);
568 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);
580 }
581 blob_reset(&record);
 
582 }
583 db_finalize(&q);
584 undo_finish();
585 db_end_transaction(0);
586 }
587
--- src/update.c
+++ src/update.c
@@ -197,19 +197,21 @@
197 " idv INTEGER," /* VFILE entry for current version */
198 " idt INTEGER," /* VFILE entry for target version */
199 " chnged BOOLEAN," /* True if current version has been edited */
200 " ridv INTEGER," /* Record ID for current version */
201 " ridt INTEGER," /* Record ID for target */
202 " isexe BOOLEAN," /* Does target have execute permission? */
203 " fnt TEXT" /* Filename of same file on target version */
204 ");"
205 );
206
207 /* Add files found in the current version
208 */
209 db_multi_exec(
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",
213 vid
214 );
215
216 /* Compute file name changes on V->T. Record name changes in files that
217 ** have changed locally.
@@ -229,12 +231,12 @@
231
232 /* Add files found in the target version T but missing from the current
233 ** version V.
234 */
235 db_multi_exec(
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"
238 " WHERE vid=%d"
239 " AND pathname NOT IN (SELECT fnt FROM fv)",
240 tid
241 );
242
@@ -248,18 +250,19 @@
250 tid, tid
251 );
252
253 if( debugFlag ){
254 db_prepare(&q,
255 "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv"
256 );
257 while( db_step(&q)==SQLITE_ROW ){
258 printf("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n",
259 db_column_int(&q, 0),
260 db_column_int(&q, 4),
261 db_column_int(&q, 5),
262 db_column_int(&q, 3),
263 db_column_int(&q, 6));
264 printf(" fnv = [%s]\n", db_column_text(&q, 1));
265 printf(" fnt = [%s]\n", db_column_text(&q, 2));
266 }
267 db_finalize(&q);
268 }
@@ -299,11 +302,11 @@
302 /*
303 ** Alter the content of the checkout so that it conforms with the
304 ** target
305 */
306 db_prepare(&q,
307 "SELECT fn, idv, ridv, idt, ridt, chnged, fnt, isexe FROM fv ORDER BY 1"
308 );
309 db_prepare(&mtimeXfer,
310 "UPDATE vfile SET mtime=(SELECT mtime FROM vfile WHERE id=:idv)"
311 " WHERE id=:idt"
312 );
@@ -316,10 +319,11 @@
319 int ridv = db_column_int(&q, 2); /* RecordID for current */
320 int idt = db_column_int(&q, 3); /* VFILE entry for target */
321 int ridt = db_column_int(&q, 4); /* RecordID for target */
322 int chnged = db_column_int(&q, 5); /* Current is edited */
323 const char *zNewName = db_column_text(&q,6);/* New filename */
324 int isexe = db_column_int(&q, 6); /* EXE perm for new file */
325 char *zFullPath; /* Full pathname of the file */
326 char *zFullNewPath; /* Full pathname of dest */
327 char nameChng; /* True if the name changed */
328
329 zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
@@ -374,17 +378,23 @@
378 undo_save(zName);
379 content_get(ridt, &t);
380 content_get(ridv, &v);
381 rc = merge_3way(&v, zFullPath, &t, &r);
382 if( rc>=0 ){
383 if( !nochangeFlag ){
384 blob_write_to_file(&r, zFullNewPath);
385 file_setexe(zFullNewPath, isexe);
386 }
387 if( rc>0 ){
388 printf("***** %d merge conflicts in %s\n", rc, zNewName);
389 nConflict++;
390 }
391 }else{
392 if( !nochangeFlag ){
393 blob_write_to_file(&t, zFullNewPath);
394 file_setexe(zFullNewPath, isexe);
395 }
396 printf("***** Cannot merge binary file %s\n", zNewName);
397 nConflict++;
398 }
399 if( nameChng && !nochangeFlag ) unlink(zFullPath);
400 blob_reset(&v);
@@ -554,33 +564,40 @@
564 int vid = db_lget_int("checkout", 0);
565 zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
566 }
567 while( db_step(&q)==SQLITE_ROW ){
568 int isExe = 0;
569 char *zFull;
570 zFile = db_column_text(&q, 0);
571 zFull = mprintf("%/%/", g.zLocalRoot, zFile);
572 errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2);
573 if( errCode==2 ){
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);
582 }else{
583 sqlite3_int64 mtime;
584 undo_save(zFile);
585 blob_write_to_file(&record, zFull);
586 file_setexe(zFull, isExe);
587 printf("REVERTED: %s\n", zFile);
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 );
 
 
 
596 }
597 blob_reset(&record);
598 free(zFull);
599 }
600 db_finalize(&q);
601 undo_finish();
602 db_end_transaction(0);
603 }
604
+12 -5
--- src/vfile.c
+++ src/vfile.c
@@ -85,21 +85,22 @@
8585
db_begin_transaction();
8686
p = manifest_get(vid, CFTYPE_MANIFEST);
8787
if( p==0 ) return;
8888
db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
8989
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)");
9292
db_bind_int(&ins, ":vid", vid);
9393
manifest_file_rewind(p);
9494
while( (pFile = manifest_file_next(p,0))!=0 ){
9595
if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue;
9696
rid = uuid_to_rid(pFile->zUuid, 0);
9797
if( rid==0 || content_size(rid, -1)<0 ){
9898
fossil_warning("content missing for %s", pFile->zName);
9999
continue;
100100
}
101
+ db_bind_int(&ins, ":isexe", manifest_file_mperm(pFile));
101102
db_bind_int(&ins, ":id", rid);
102103
db_bind_text(&ins, ":name", pFile->zName);
103104
db_step(&ins);
104105
db_reset(&ins);
105106
}
@@ -207,31 +208,36 @@
207208
Stmt q;
208209
Blob content;
209210
int nRepos = strlen(g.zLocalRoot);
210211
211212
if( vid>0 && id==0 ){
212
- db_prepare(&q, "SELECT id, %Q || pathname, mrid"
213
+ db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe"
213214
" FROM vfile"
214215
" WHERE vid=%d AND mrid>0",
215216
g.zLocalRoot, vid);
216217
}else{
217218
assert( vid==0 && id>0 );
218
- db_prepare(&q, "SELECT id, %Q || pathname, mrid"
219
+ db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe"
219220
" FROM vfile"
220221
" WHERE id=%d AND mrid>0",
221222
g.zLocalRoot, id);
222223
}
223224
while( db_step(&q)==SQLITE_ROW ){
224
- int id, rid;
225
+ int id, rid, isExe;
225226
const char *zName;
226227
227228
id = db_column_int(&q, 0);
228229
zName = db_column_text(&q, 1);
229230
rid = db_column_int(&q, 2);
231
+ isExe = db_column_int(&q, 3);
230232
content_get(rid, &content);
231233
if( file_is_the_same(&content, zName) ){
232234
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
+ }
233239
continue;
234240
}
235241
if( promptFlag && file_size(zName)>=0 ){
236242
Blob ans;
237243
char *zMsg;
@@ -250,10 +256,11 @@
250256
continue;
251257
}
252258
}
253259
if( verbose ) printf("%s\n", &zName[nRepos]);
254260
blob_write_to_file(&content, zName);
261
+ file_setexe(zName, isExe);
255262
blob_reset(&content);
256263
db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
257264
file_mtime(zName), id);
258265
}
259266
db_finalize(&q);
260267
--- src/vfile.c
+++ src/vfile.c
@@ -85,21 +85,22 @@
85 db_begin_transaction();
86 p = manifest_get(vid, CFTYPE_MANIFEST);
87 if( p==0 ) return;
88 db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
89 db_prepare(&ins,
90 "INSERT INTO vfile(vid,rid,mrid,pathname) "
91 " VALUES(:vid,:id,:id,:name)");
92 db_bind_int(&ins, ":vid", vid);
93 manifest_file_rewind(p);
94 while( (pFile = manifest_file_next(p,0))!=0 ){
95 if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue;
96 rid = uuid_to_rid(pFile->zUuid, 0);
97 if( rid==0 || content_size(rid, -1)<0 ){
98 fossil_warning("content missing for %s", pFile->zName);
99 continue;
100 }
 
101 db_bind_int(&ins, ":id", rid);
102 db_bind_text(&ins, ":name", pFile->zName);
103 db_step(&ins);
104 db_reset(&ins);
105 }
@@ -207,31 +208,36 @@
207 Stmt q;
208 Blob content;
209 int nRepos = strlen(g.zLocalRoot);
210
211 if( vid>0 && id==0 ){
212 db_prepare(&q, "SELECT id, %Q || pathname, mrid"
213 " FROM vfile"
214 " WHERE vid=%d AND mrid>0",
215 g.zLocalRoot, vid);
216 }else{
217 assert( vid==0 && id>0 );
218 db_prepare(&q, "SELECT id, %Q || pathname, mrid"
219 " FROM vfile"
220 " WHERE id=%d AND mrid>0",
221 g.zLocalRoot, id);
222 }
223 while( db_step(&q)==SQLITE_ROW ){
224 int id, rid;
225 const char *zName;
226
227 id = db_column_int(&q, 0);
228 zName = db_column_text(&q, 1);
229 rid = db_column_int(&q, 2);
 
230 content_get(rid, &content);
231 if( file_is_the_same(&content, zName) ){
232 blob_reset(&content);
 
 
 
 
233 continue;
234 }
235 if( promptFlag && file_size(zName)>=0 ){
236 Blob ans;
237 char *zMsg;
@@ -250,10 +256,11 @@
250 continue;
251 }
252 }
253 if( verbose ) printf("%s\n", &zName[nRepos]);
254 blob_write_to_file(&content, zName);
 
255 blob_reset(&content);
256 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
257 file_mtime(zName), id);
258 }
259 db_finalize(&q);
260
--- src/vfile.c
+++ src/vfile.c
@@ -85,21 +85,22 @@
85 db_begin_transaction();
86 p = manifest_get(vid, CFTYPE_MANIFEST);
87 if( p==0 ) return;
88 db_multi_exec("DELETE FROM vfile WHERE vid=%d", vid);
89 db_prepare(&ins,
90 "INSERT INTO vfile(vid,isexe,rid,mrid,pathname) "
91 " VALUES(:vid,:isexe,:id,:id,:name)");
92 db_bind_int(&ins, ":vid", vid);
93 manifest_file_rewind(p);
94 while( (pFile = manifest_file_next(p,0))!=0 ){
95 if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue;
96 rid = uuid_to_rid(pFile->zUuid, 0);
97 if( rid==0 || content_size(rid, -1)<0 ){
98 fossil_warning("content missing for %s", pFile->zName);
99 continue;
100 }
101 db_bind_int(&ins, ":isexe", manifest_file_mperm(pFile));
102 db_bind_int(&ins, ":id", rid);
103 db_bind_text(&ins, ":name", pFile->zName);
104 db_step(&ins);
105 db_reset(&ins);
106 }
@@ -207,31 +208,36 @@
208 Stmt q;
209 Blob content;
210 int nRepos = strlen(g.zLocalRoot);
211
212 if( vid>0 && id==0 ){
213 db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe"
214 " FROM vfile"
215 " WHERE vid=%d AND mrid>0",
216 g.zLocalRoot, vid);
217 }else{
218 assert( vid==0 && id>0 );
219 db_prepare(&q, "SELECT id, %Q || pathname, mrid, isexe"
220 " FROM vfile"
221 " WHERE id=%d AND mrid>0",
222 g.zLocalRoot, id);
223 }
224 while( db_step(&q)==SQLITE_ROW ){
225 int id, rid, isExe;
226 const char *zName;
227
228 id = db_column_int(&q, 0);
229 zName = db_column_text(&q, 1);
230 rid = db_column_int(&q, 2);
231 isExe = db_column_int(&q, 3);
232 content_get(rid, &content);
233 if( file_is_the_same(&content, zName) ){
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 }
239 continue;
240 }
241 if( promptFlag && file_size(zName)>=0 ){
242 Blob ans;
243 char *zMsg;
@@ -250,10 +256,11 @@
256 continue;
257 }
258 }
259 if( verbose ) printf("%s\n", &zName[nRepos]);
260 blob_write_to_file(&content, zName);
261 file_setexe(zName, isExe);
262 blob_reset(&content);
263 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
264 file_mtime(zName), id);
265 }
266 db_finalize(&q);
267

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button