Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch branch-1.19 Excluding Merge-Ins
This is equivalent to a diff from 6517b5c857 to 285eeba64f
2012-11-17
| ||
19:22 | Prevent delta loops on sync operations that might otherwise occur if a sequence of file changes ends with a file back to its original state after a sequence of two or more intermediate states. The is a backport/cherrypick of check-in [141b990722ea81e10e5] Leaf check-in: 285eeba64f user: drh tags: branch-1.19 | |
2012-11-14
| ||
20:28 | Detect infinite loops in the DELTA table and abort out of content_get() when they are found. Fix an off-by-one error in the version-3 clone protocol. This error might cause an incomplete and corrupt clone if a transfer block fills up just before sending the very last blob. Backport of fixes from 2012-08-23 21:15:36 check-in: 99053ab141 user: drh tags: branch-1.19 | |
2012-10-11
| ||
19:45 | Cherrypick changes [0c37874941c8972], [9ba8a393fcc569b], and [ae092ec605eed11] in order to backport the --setmtime option of "fossil update" and the --age and -t options of "fossil ls" to version 1.19. check-in: 773c6c5f2c user: drh tags: branch-1.19 | |
2011-09-01
| ||
20:23 | Stop publishing x64 binaries for linux. x86 binaries are sufficient. check-in: bd04a48925 user: drh tags: trunk | |
18:25 | Version 1.19. check-in: 6517b5c857 user: drh tags: trunk, release, version-1.19 | |
17:45 | Merging the unwanted two trunk leaves. check-in: a22c381757 user: viriketo tags: trunk | |
Changes to src/checkin.c.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
...
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
int vid; int useSha1sum = find_option("sha1sum", 0, 0)!=0; int cwdRelative = 0; db_must_be_within_tree(); cwdRelative = determine_cwd_relative_option(); blob_zero(&report); vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 0, useSha1sum); status_report(&report, "", 0, cwdRelative); blob_write_to_file(&report, "-"); } /* ** COMMAND: status ** ................................................................................ fossil_print("server-code: %s\n", db_get("server-code", "")); vid = db_lget_int("checkout", 0); if( vid ){ show_common_info(vid, "checkout:", 1, 1); } changes_cmd(); } /* ** COMMAND: ls ** ** Usage: %fossil ls [-l] ** ** Show the names of all files in the current checkout. The -l provides ** extra information about each file. */ void ls_cmd(void){ int vid; Stmt q; int isBrief; isBrief = find_option("l","l", 0)==0; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 0, 0); db_prepare(&q, "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)" " FROM vfile" " ORDER BY 1" ); while( db_step(&q)==SQLITE_ROW ){ const char *zPathname = db_column_text(&q,0); int isDeleted = db_column_int(&q, 1); int isNew = db_column_int(&q,2)==0; int chnged = db_column_int(&q,3); int renamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); if( isBrief ){ fossil_print("%s\n", zPathname); }else if( isNew ){ fossil_print("ADDED %s\n", zPathname); }else if( isDeleted ){ fossil_print("DELETED %s\n", zPathname); }else if( !file_isfile(zFullName) ){ if( file_access(zFullName, 0)==0 ){ |
|
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
|
|
|
|
>
>
>
|
|
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
...
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
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
int vid; int useSha1sum = find_option("sha1sum", 0, 0)!=0; int cwdRelative = 0; db_must_be_within_tree(); cwdRelative = determine_cwd_relative_option(); blob_zero(&report); vid = db_lget_int("checkout", 0); vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0); status_report(&report, "", 0, cwdRelative); blob_write_to_file(&report, "-"); } /* ** COMMAND: status ** ................................................................................ fossil_print("server-code: %s\n", db_get("server-code", "")); vid = db_lget_int("checkout", 0); if( vid ){ show_common_info(vid, "checkout:", 1, 1); } changes_cmd(); } /* ** Implementation of the checkin_mtime SQL function */ /* ** COMMAND: ls ** ** Usage: %fossil ls ?OPTIONS? ?VERSION? ** ** Show the names of all files in the current checkout. The -l provides ** extra information about each file. ** ** Options: ** -l Provide extra information about each file. ** --age Show when each file was committed ** ** See also: changes, extra, status */ void ls_cmd(void){ int vid; Stmt q; int isBrief; int showAge; char *zOrderBy = "pathname"; isBrief = find_option("l","l", 0)==0; showAge = find_option("age",0,0)!=0; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( find_option("t","t",0)!=0 ){ if( showAge ){ zOrderBy = mprintf("checkin_mtime(%d,rid) DESC", vid); }else{ zOrderBy = "mtime DESC"; } } verify_all_options(); vfile_check_signature(vid, 0); if( showAge ){ db_prepare(&q, "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)," " datetime(checkin_mtime(%d,rid),'unixepoch','localtime')" " FROM vfile" " ORDER BY %s", vid, zOrderBy ); }else{ db_prepare(&q, "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)" " FROM vfile" " ORDER BY %s", zOrderBy ); } while( db_step(&q)==SQLITE_ROW ){ const char *zPathname = db_column_text(&q,0); int isDeleted = db_column_int(&q, 1); int isNew = db_column_int(&q,2)==0; int chnged = db_column_int(&q,3); int renamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); if( showAge ){ fossil_print("%s %s\n", db_column_text(&q, 5), zPathname); }else if( isBrief ){ fossil_print("%s\n", zPathname); }else if( isNew ){ fossil_print("ADDED %s\n", zPathname); }else if( isDeleted ){ fossil_print("DELETED %s\n", zPathname); }else if( !file_isfile(zFullName) ){ if( file_access(zFullName, 0)==0 ){ |
Changes to src/checkout.c.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
** 2: There is no existing checkout
*/
int unsaved_changes(void){
int vid;
db_must_be_within_tree();
vid = db_lget_int("checkout",0);
if( vid==0 ) return 2;
vfile_check_signature(vid, 1, 0);
return db_exists("SELECT 1 FROM vfile WHERE chnged"
" OR coalesce(origname!=pathname,0)");
}
/*
** Undo the current check-out. Unlink all files from the disk.
** Clear the VFILE table.
|
| |
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
** 2: There is no existing checkout
*/
int unsaved_changes(void){
int vid;
db_must_be_within_tree();
vid = db_lget_int("checkout",0);
if( vid==0 ) return 2;
vfile_check_signature(vid, CKSIG_ENOTFILE);
return db_exists("SELECT 1 FROM vfile WHERE chnged"
" OR coalesce(origname!=pathname,0)");
}
/*
** Undo the current check-out. Unlink all files from the disk.
** Clear the VFILE table.
|
Changes to src/content.c.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
a[0] = rid; a[1] = nextRid; n = 1; while( !bag_find(&contentCache.inCache, nextRid) && (nextRid = findSrcid(nextRid))>0 ){ n++; if( n>=nAlloc ){ nAlloc = nAlloc*2 + 10; a = fossil_realloc(a, nAlloc*sizeof(a[0])); } a[n] = nextRid; } mx = n; rc = content_get(a[n], pBlob); |
> > > |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 |
a[0] = rid; a[1] = nextRid; n = 1; while( !bag_find(&contentCache.inCache, nextRid) && (nextRid = findSrcid(nextRid))>0 ){ n++; if( n>=nAlloc ){ if( n>db_int(0, "SELECT max(rid) FROM blob") ){ fossil_panic("infinite loop in DELTA table"); } nAlloc = nAlloc*2 + 10; a = fossil_realloc(a, nAlloc*sizeof(a[0])); } a[n] = nextRid; } mx = n; rc = content_get(a[n], pBlob); |
Changes to src/db.c.
625
626
627
628
629
630
631
632
633
634
635
636
637
638
...
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_int64(context, time(0)); } /* ** Open a database file. Return a pointer to the new database ** connection. An error results in process abort. */ static sqlite3 *openDatabase(const char *zDbName){ int rc; ................................................................................ ); if( rc!=SQLITE_OK ){ db_err(sqlite3_errmsg(db)); } sqlite3_busy_timeout(db, 5000); sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0); return db; } /* ** zDbName is the name of a database file. If no other database ** file is open, then open this one. If another database file is ** already open, then attach zDbName using the name zLabel. */ static void db_open_or_attach(const char *zDbName, const char *zLabel){ if( !g.db ){ g.db = openDatabase(zDbName); g.zMainDbType = zLabel; db_connection_init(); }else{ db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); } |
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
...
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
|
sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_int64(context, time(0)); } /* ** Function to return the check-in time for a file. */ void db_checkin_mtime_function( sqlite3_context *context, int argc, sqlite3_value **argv ){ i64 mtime; int rc = mtime_of_manifest_file(sqlite3_value_int(argv[0]), sqlite3_value_int(argv[1]), &mtime); if( rc==0 ){ sqlite3_result_int64(context, mtime); } } /* ** Open a database file. Return a pointer to the new database ** connection. An error results in process abort. */ static sqlite3 *openDatabase(const char *zDbName){ int rc; ................................................................................ ); if( rc!=SQLITE_OK ){ db_err(sqlite3_errmsg(db)); } sqlite3_busy_timeout(db, 5000); sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0); sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_ANY, 0, db_checkin_mtime_function, 0, 0); return db; } /* ** zDbName is the name of a database file. If no other database ** file is open, then open this one. If another database file is ** already open, then attach zDbName using the name zLabel. */ void db_open_or_attach(const char *zDbName, const char *zLabel){ if( !g.db ){ g.db = openDatabase(zDbName); g.zMainDbType = zLabel; db_connection_init(); }else{ db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); } |
Changes to src/descendants.c.
154 155 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 ... 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 ... 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
} } /* ** Load the record ID rid and up to N-1 closest ancestors into ** the "ok" table. */ void compute_ancestors(int rid, int N){ Bag seen; PQueue queue; Stmt ins; Stmt q; bag_init(&seen); pqueue_init(&queue); bag_insert(&seen, rid); pqueue_insert(&queue, rid, 0.0, 0); db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)"); db_prepare(&q, "SELECT a.pid, b.mtime FROM plink a LEFT JOIN plink b ON b.cid=a.pid" " WHERE a.cid=:rid" ); while( (N--)>0 && (rid = pqueue_extract(&queue, 0))!=0 ){ db_bind_int(&ins, ":rid", rid); db_step(&ins); db_reset(&ins); db_bind_int(&q, ":rid", rid); while( db_step(&q)==SQLITE_ROW ){ ................................................................................ ** direct ancestor as the largest generation number. */ void compute_direct_ancestors(int rid, int N){ Stmt ins; Stmt q; int gen = 0; db_multi_exec( "CREATE TEMP TABLE ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);" "INSERT INTO ancestor VALUES(%d, 0);", rid ); db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)"); db_prepare(&q, "SELECT pid FROM plink" " WHERE cid=:rid AND isprim" ); ................................................................................ db_bind_int(&ins, ":gen", gen); db_step(&ins); db_reset(&ins); } db_finalize(&ins); db_finalize(&q); } /* ** Load the record ID rid and up to N-1 closest descendants into ** the "ok" table. */ void compute_descendants(int rid, int N){ Bag seen; |
| | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
154 155 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 ... 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 ... 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
} } /* ** Load the record ID rid and up to N-1 closest ancestors into ** the "ok" table. */ void compute_ancestors(int rid, int N, int directOnly){ Bag seen; PQueue queue; Stmt ins; Stmt q; bag_init(&seen); pqueue_init(&queue); bag_insert(&seen, rid); pqueue_insert(&queue, rid, 0.0, 0); db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)"); db_prepare(&q, "SELECT a.pid, b.mtime FROM plink a LEFT JOIN plink b ON b.cid=a.pid" " WHERE a.cid=:rid %s", directOnly ? " AND a.isprim" : "" ); while( (N--)>0 && (rid = pqueue_extract(&queue, 0))!=0 ){ db_bind_int(&ins, ":rid", rid); db_step(&ins); db_reset(&ins); db_bind_int(&q, ":rid", rid); while( db_step(&q)==SQLITE_ROW ){ ................................................................................ ** direct ancestor as the largest generation number. */ void compute_direct_ancestors(int rid, int N){ Stmt ins; Stmt q; int gen = 0; db_multi_exec( "CREATE TEMP TABLE IF NOT EXISTS ancestor(rid INTEGER," " generation INTEGER PRIMARY KEY);" "DELETE FROM ancestor;" "INSERT INTO ancestor VALUES(%d, 0);", rid ); db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)"); db_prepare(&q, "SELECT pid FROM plink" " WHERE cid=:rid AND isprim" ); ................................................................................ db_bind_int(&ins, ":gen", gen); db_step(&ins); db_reset(&ins); } db_finalize(&ins); db_finalize(&q); } /* ** Compute the "mtime" of the file given whose blob.rid is "fid" that ** is part of check-in "vid". The mtime will be the mtime on vid or ** some ancestor of vid where fid first appears. */ int mtime_of_manifest_file( int vid, /* The check-in that contains fid */ int fid, /* The id of the file whose check-in time is sought */ i64 *pMTime /* Write result here */ ){ static int prevVid = -1; static Stmt q; if( prevVid!=vid ){ prevVid = vid; db_multi_exec("DROP TABLE IF EXISTS temp.ok;" "CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);"); compute_ancestors(vid, 100000000, 1); } db_static_prepare(&q, "SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event" " WHERE mlink.mid=event.objid" " AND +mlink.mid IN ok" " AND mlink.fid=:fid"); db_bind_int(&q, ":fid", fid); if( db_step(&q)!=SQLITE_ROW ){ db_reset(&q); return 1; } *pMTime = db_column_int64(&q, 0); db_reset(&q); return 0; } /* ** Load the record ID rid and up to N-1 closest descendants into ** the "ok" table. */ void compute_descendants(int rid, int N){ Bag seen; |
Changes to src/diffcmd.c.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
Stmt q;
int ignoreEolWs; /* Ignore end-of-line whitespace */
int asNewFile; /* Treat non-existant files as empty files */
ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 1, 0);
blob_zero(&sql);
db_begin_transaction();
if( zFrom ){
int rid = name_to_typed_rid(zFrom, "ci");
if( !is_a_version(rid) ){
fossil_fatal("no such check-in: %s", zFrom);
}
|
| |
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
Stmt q;
int ignoreEolWs; /* Ignore end-of-line whitespace */
int asNewFile; /* Treat non-existant files as empty files */
ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0;
asNewFile = (diffFlags & DIFF_NEWFILE)!=0;
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, CKSIG_ENOTFILE);
blob_zero(&sql);
db_begin_transaction();
if( zFrom ){
int rid = name_to_typed_rid(zFrom, "ci");
if( !is_a_version(rid) ){
fossil_fatal("no such check-in: %s", zFrom);
}
|
Changes to src/file.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "file.h"
/*
** The file status information from the most recent stat() call.
**
** Use _stati64 rather than stat on windows, in order to handle files
** larger than 2GB.
*/
#if defined(_WIN32) && defined(__MSVCRT__)
................................................................................
chmod(zFilename, buf.st_mode & ~0111);
rc = 1;
}
}
#endif /* _WIN32 */
return rc;
}
/*
** Delete a file.
*/
void file_delete(const char *zFilename){
char *z = fossil_utf8_to_mbcs(zFilename);
unlink(z);
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
|
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include <errno.h> #include "file.h" #ifdef _WIN32 # include <sys/utime.h> #else # include <sys/time.h> #endif /* ** The file status information from the most recent stat() call. ** ** Use _stati64 rather than stat on windows, in order to handle files ** larger than 2GB. */ #if defined(_WIN32) && defined(__MSVCRT__) ................................................................................ chmod(zFilename, buf.st_mode & ~0111); rc = 1; } } #endif /* _WIN32 */ return rc; } /* ** Set the mtime for a file. */ void file_set_mtime(const char *zFilename, i64 newMTime){ #if !defined(_WIN32) struct timeval tv[2]; memset(tv, 0, sizeof(tv[0])*2); tv[0].tv_sec = newMTime; tv[1].tv_sec = newMTime; utimes(zFilename, tv); #else struct utimbuf tb; char *zMbcs = fossil_utf8_to_mbcs(zFilename); tb.actime = newMTime; tb.modtime = newMTime; _utime(zMbcs, &tb); fossil_mbcs_free(zMbcs); #endif } /* ** COMMAND: test-set-mtime ** ** Usage: %fossil test-set-mtime FILENAME DATE/TIME ** ** Sets the mtime of the named file to the date/time shown. */ void test_set_mtime(void){ const char *zFile; char *zDate; i64 iMTime; if( g.argc!=4 ){ usage("test-set-mtime FILENAME DATE/TIME"); } db_open_or_attach(":memory:", "mem"); iMTime = db_int64(0, "SELECT strftime('%%s',%Q)", g.argv[3]); zFile = g.argv[2]; file_set_mtime(zFile, iMTime); iMTime = file_mtime(zFile); zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMTime); fossil_print("Set mtime of \"%s\" to %s (%lld)\n", zFile, zDate, iMTime); } /* ** Delete a file. */ void file_delete(const char *zFilename){ char *z = fossil_utf8_to_mbcs(zFilename); unlink(z); |
Changes to src/finfo.c.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
int vid;
if( g.argc!=3 ) usage("-s|--status FILENAME");
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_panic("no checkout to finfo files in");
}
vfile_check_signature(vid, 1, 0);
file_tree_name(g.argv[2], &fname, 1);
db_prepare(&q,
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
" FROM vfile WHERE vfile.pathname=%B", &fname);
blob_zero(&line);
if ( db_step(&q)==SQLITE_ROW ) {
Blob uuid;
|
| |
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
int vid;
if( g.argc!=3 ) usage("-s|--status FILENAME");
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_panic("no checkout to finfo files in");
}
vfile_check_signature(vid, CKSIG_ENOTFILE);
file_tree_name(g.argv[2], &fname, 1);
db_prepare(&q,
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
" FROM vfile WHERE vfile.pathname=%B", &fname);
blob_zero(&line);
if ( db_step(&q)==SQLITE_ROW ) {
Blob uuid;
|
Changes to src/merge.c.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
int t = pid;
pid = mid;
mid = t;
}
if( !is_a_version(pid) ){
fossil_fatal("not a version: record #%d", pid);
}
vfile_check_signature(vid, 1, 0);
db_begin_transaction();
if( !nochangeFlag ) undo_begin();
load_vfile_from_rid(mid);
load_vfile_from_rid(pid);
/*
** The vfile.pathname field is used to match files against each other. The
|
| |
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
int t = pid;
pid = mid;
mid = t;
}
if( !is_a_version(pid) ){
fossil_fatal("not a version: record #%d", pid);
}
vfile_check_signature(vid, CKSIG_ENOTFILE);
db_begin_transaction();
if( !nochangeFlag ) undo_begin();
load_vfile_from_rid(mid);
load_vfile_from_rid(pid);
/*
** The vfile.pathname field is used to match files against each other. The
|
Changes to src/stash.c.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
int vid; /* Current checkout */
zComment = find_option("comment", "m", 1);
verify_all_options();
stashid = db_lget_int("stash-next", 1);
db_lset_int("stash-next", stashid+1);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0, 0);
db_multi_exec(
"INSERT INTO stash(stashid,vid,comment,ctime)"
"VALUES(%d,%d,%Q,julianday('now'))",
stashid, vid, zComment
);
if( g.argc>3 ){
int i;
|
| |
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
int vid; /* Current checkout */ zComment = find_option("comment", "m", 1); verify_all_options(); stashid = db_lget_int("stash-next", 1); db_lset_int("stash-next", stashid+1); vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 0); db_multi_exec( "INSERT INTO stash(stashid,vid,comment,ctime)" "VALUES(%d,%d,%Q,julianday('now'))", stashid, vid, zComment ); if( g.argc>3 ){ int i; |
Changes to src/timeline.c.
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
....
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
|
db_multi_exec("%s", blob_str(&sql));
blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
}
if( useDividers ) timeline_add_dividers(0, d_rid);
db_multi_exec("DELETE FROM ok");
}
if( p_rid ){
compute_ancestors(p_rid, nEntry+1);
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
................................................................................
);
if( mode==3 || mode==4 ){
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
if( mode==3 ){
compute_descendants(objid, n);
}else{
compute_ancestors(objid, n);
}
blob_appendf(&sql, " AND blob.rid IN ok");
}
if( zType && (zType[0]!='a') ){
blob_appendf(&sql, " AND event.type=%Q ", zType);
}
|
|
|
|
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
....
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
|
db_multi_exec("%s", blob_str(&sql)); blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s"); } if( useDividers ) timeline_add_dividers(0, d_rid); db_multi_exec("DELETE FROM ok"); } if( p_rid ){ compute_ancestors(p_rid, nEntry+1, 0); np = db_int(0, "SELECT count(*)-1 FROM ok"); if( np>0 ){ if( nd>0 ) blob_appendf(&desc, " and "); blob_appendf(&desc, "%d ancestors", np); db_multi_exec("%s", blob_str(&sql)); } if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid); ................................................................................ ); if( mode==3 || mode==4 ){ db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); if( mode==3 ){ compute_descendants(objid, n); }else{ compute_ancestors(objid, n, 0); } blob_appendf(&sql, " AND blob.rid IN ok"); } if( zType && (zType[0]!='a') ){ blob_appendf(&sql, " AND event.type=%Q ", zType); } |
Changes to src/update.c.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 ... 104 105 106 107 108 109 110 111 112 113 114 115 116 117 ... 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 ... 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 ... 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 ... 325 326 327 328 329 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 356 357 358 359 360 361 362 363 364 365 ... 454 455 456 457 458 459 460 461 462 463 464 465 466 467 ... 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
int vid; /* Current version */ int tid=0; /* Target version - version we are changing to */ Stmt q; int latestFlag; /* --latest. Pick the latest version if true */ int nochangeFlag; /* -n or --nochange. Do a dry run */ int verboseFlag; /* -v or --verbose. Output extra information */ int debugFlag; /* --debug option */ int nChng; /* Number of file renames */ int *aChng; /* Array of file renames */ int i; /* Loop counter */ int nConflict = 0; /* Number of merge conflicts */ Stmt mtimeXfer; /* Statment to transfer mtimes */ if( !internalUpdate ){ ................................................................................ undo_capture_command_line(); url_proxy_options(); } latestFlag = find_option("latest",0, 0)!=0; nochangeFlag = find_option("nochange","n",0)!=0; verboseFlag = find_option("verbose","v",0)!=0; debugFlag = find_option("debug",0,0)!=0; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("cannot find current version"); } if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ fossil_fatal("cannot update an uncommitted merge"); ................................................................................ } if( tid==0 ){ fossil_panic("Internal Error: unable to find a version to update to."); } db_begin_transaction(); vfile_check_signature(vid, 1, 0); if( !nochangeFlag && !internalUpdate ) undo_begin(); load_vfile_from_rid(tid); /* ** The record.fn field is used to match files against each other. The ** FV table contains one row for each each unique filename in ** in the current checkout, the pivot, and the version being merged. ................................................................................ " 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. */ ................................................................................ } /* ** 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 ); ................................................................................ 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, 7); /* 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); if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ /* Conflict. This file has been added to the current checkout ** but also exists in the target checkout. Use the current version. */ fossil_print("CONFLICT %s\n", zName); nConflict++; }else if( idt>0 && idv==0 ){ /* File added in the target. */ fossil_print("ADD %s\n", zName); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ /* The file is unedited. Change it to the target version */ undo_save(zName); fossil_print("UPDATE %s\n", zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ /* The file missing from the local check-out. Restore it to the ** version that appears in the target. */ fossil_print("UPDATE %s\n", zName); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt==0 && idv>0 ){ if( ridv==0 ){ /* Added in current checkout. Continue to hold the file as ** as an addition */ db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); ................................................................................ db_lset_int("checkout", tid); }else{ /* A subset of files have been checked out. Keep the current ** checkout unchanged. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); } if( !internalUpdate ) undo_finish(); db_end_transaction(0); } } /* ** Make sure empty directories are created */ ................................................................................ file_tree_name(zFile, &fname, 1); db_multi_exec("REPLACE INTO torevert VALUES(%B)", &fname); blob_reset(&fname); } }else{ int vid; vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 0, 0); db_multi_exec( "DELETE FROM vmerge;" "INSERT INTO torevert " "SELECT pathname" " FROM vfile " " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;" ); |
> > | > | | | > > > > > | > > > | > | > > | |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 ... 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ... 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 ... 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 ... 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 ... 329 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 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 ... 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 ... 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
int vid; /* Current version */ int tid=0; /* Target version - version we are changing to */ Stmt q; int latestFlag; /* --latest. Pick the latest version if true */ int nochangeFlag; /* -n or --nochange. Do a dry run */ int verboseFlag; /* -v or --verbose. Output extra information */ int debugFlag; /* --debug option */ int setmtimeFlag; /* --setmtime. Set mtimes on files */ int nChng; /* Number of file renames */ int *aChng; /* Array of file renames */ int i; /* Loop counter */ int nConflict = 0; /* Number of merge conflicts */ Stmt mtimeXfer; /* Statment to transfer mtimes */ if( !internalUpdate ){ ................................................................................ undo_capture_command_line(); url_proxy_options(); } latestFlag = find_option("latest",0, 0)!=0; nochangeFlag = find_option("nochange","n",0)!=0; verboseFlag = find_option("verbose","v",0)!=0; debugFlag = find_option("debug",0,0)!=0; setmtimeFlag = find_option("setmtime",0,0)!=0; db_must_be_within_tree(); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("cannot find current version"); } if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ fossil_fatal("cannot update an uncommitted merge"); ................................................................................ } if( tid==0 ){ fossil_panic("Internal Error: unable to find a version to update to."); } db_begin_transaction(); vfile_check_signature(vid, CKSIG_ENOTFILE); if( !nochangeFlag && !internalUpdate ) undo_begin(); load_vfile_from_rid(tid); /* ** The record.fn field is used to match files against each other. The ** FV table contains one row for each each unique filename in ** in the current checkout, the pivot, and the version being merged. ................................................................................ " 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? */ " deleted BOOLEAN DEFAULT 0,"/* File marke by "rm" to become unmanaged */ " 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,deleted)" " SELECT pathname, pathname, id, 0, rid, 0, isexe, chnged, deleted" " FROM vfile WHERE vid=%d", vid ); /* Compute file name changes on V->T. Record name changes in files that ** have changed locally. */ ................................................................................ } /* ** 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, deleted 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 ); ................................................................................ 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, 7); /* EXE perm for new file */ int deleted = db_column_int(&q, 8); /* Marked for deletion */ 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); if( deleted ){ db_multi_exec("UPDATE vfile SET deleted=1 WHERE id=%d", idt); } if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ /* Conflict. This file has been added to the current checkout ** but also exists in the target checkout. Use the current version. */ fossil_print("CONFLICT %s\n", zName); nConflict++; }else if( idt>0 && idv==0 ){ /* File added in the target. */ fossil_print("ADD %s\n", zName); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && ridt!=ridv && (chnged==0 || deleted) ){ /* The file is unedited. Change it to the target version */ undo_save(zName); if( deleted ){ fossil_print("UPDATE %s - change to unmanged file\n", zName); }else{ fossil_print("UPDATE %s\n", zName); } if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ /* The file missing from the local check-out. Restore it to the ** version that appears in the target. */ fossil_print("UPDATE %s%s\n", zName, deleted?" - change to unmanaged file":""); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt==0 && idv>0 ){ if( ridv==0 ){ /* Added in current checkout. Continue to hold the file as ** as an addition */ db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); ................................................................................ db_lset_int("checkout", tid); }else{ /* A subset of files have been checked out. Keep the current ** checkout unchanged. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); } if( !internalUpdate ) undo_finish(); if( setmtimeFlag ) vfile_check_signature(tid, CKSIG_SETMTIME); db_end_transaction(0); } } /* ** Make sure empty directories are created */ ................................................................................ file_tree_name(zFile, &fname, 1); db_multi_exec("REPLACE INTO torevert VALUES(%B)", &fname); blob_reset(&fname); } }else{ int vid; vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 0); db_multi_exec( "DELETE FROM vmerge;" "INSERT INTO torevert " "SELECT pathname" " FROM vfile " " WHERE chnged OR deleted OR rid=0 OR pathname!=origname;" ); |
Changes to src/vfile.c.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 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 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 |
} db_finalize(&ridq); db_finalize(&ins); manifest_destroy(p); db_end_transaction(0); } /* ** Check the file signature of the disk image for every VFILE of vid. ** ** Set the VFILE.CHNGED field on every file that has changed. Also ** set VFILE.CHNGED on every folder that contains a file or folder ** that has changed. ** ** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume ** the file has changed without having the check the on-disk image. ** ** If the size of the file has changed, then we assume that it has ** changed. If the mtime of the file has not changed and useSha1sum is false ** and the mtime-changes setting is true (the default) then we assume that ** the file has not changed. If the mtime has changed, we go ahead and ** double-check that the file has changed by looking at its SHA1 sum. */ void vfile_check_signature(int vid, int notFileIsFatal, int useSha1sum){ int nErr = 0; Stmt q; Blob fileCksum, origCksum; int checkMtime = useSha1sum==0 && db_get_boolean("mtime-changes", 1); db_begin_transaction(); db_prepare(&q, "SELECT id, %Q || pathname," " vfile.mrid, deleted, chnged, uuid, size, mtime" " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid" " WHERE vid=%d ", g.zLocalRoot, vid); while( db_step(&q)==SQLITE_ROW ){ int id, rid, isDeleted; const char *zName; int chnged = 0; int oldChnged; i64 oldMtime; i64 currentMtime; id = db_column_int(&q, 0); zName = db_column_text(&q, 1); rid = db_column_int(&q, 2); isDeleted = db_column_int(&q, 3); oldChnged = db_column_int(&q, 4); oldMtime = db_column_int64(&q, 7); if( isDeleted ){ chnged = 1; }else if( !file_isfile(zName) && file_size(0)>=0 ){ if( notFileIsFatal ){ fossil_warning("not an ordinary file: %s", zName); nErr++; } chnged = 1; }else if( oldChnged>=2 ){ chnged = oldChnged; }else if( rid==0 ){ chnged = 1; } if( chnged!=1 ){ i64 origSize = db_column_int64(&q, 6); currentMtime = file_mtime(0); if( origSize!=file_size(0) ){ /* A file size change is definitive - the file has changed. No ** need to check the sha1sum */ chnged = 1; } } if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){ db_ephemeral_blob(&q, 5, &origCksum); if( sha1sum_file(zName, &fileCksum) ){ blob_zero(&fileCksum); } if( blob_compare(&fileCksum, &origCksum) ){ chnged = 1; }else if( currentMtime!=oldMtime ){ db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", currentMtime, id); } blob_reset(&origCksum); blob_reset(&fileCksum); } if( chnged!=oldChnged && (chnged || !checkMtime) ){ db_multi_exec("UPDATE vfile SET chnged=%d WHERE id=%d", chnged, id); } } db_finalize(&q); if( nErr ) fossil_fatal("abort due to prior errors"); db_end_transaction(0); } |
> < > > | < < | > > > > > > > > > > > | > > | > | < < < < > > > > > > > > > > > | > | > > | | > > > > | < > < < < < > | < < < | > > > > > > > | > > > > | > > > > > < < < | > > > > > > > > > | > |
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 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 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 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 246 247 248 249 250 251 252 253 254 255 256 257 |
} db_finalize(&ridq); db_finalize(&ins); manifest_destroy(p); db_end_transaction(0); } #if INTERFACE /* ** The cksigFlags parameter to vfile_check_signature() is an OR-ed ** combination of the following bits: */ #define CKSIG_ENOTFILE 0x001 /* non-file FS objects throw an error */ #define CKSIG_SHA1 0x002 /* Verify file content using sha1sum */ #define CKSIG_SETMTIME 0x004 /* Set mtime to last check-out time */ #endif /* INTERFACE */ /* ** Look at every VFILE entry with the given vid and update ** VFILE.CHNGED field according to whether or not ** the file has changed. 0 means no change. 1 means edited. 2 means ** the file has changed due to a merge. 3 means the file was added ** by a merge. ** ** If VFILE.DELETED is true or if VFILE.RID is zero, then the file was either ** removed from configuration management via "fossil rm" or added via ** "fossil add", respectively, and in both cases we always know that ** the file has changed without having the check the size, mtime, ** or on-disk content. ** ** If the size of the file has changed, then we always know that the file ** changed without having to look at the mtime or on-disk content. ** ** The mtime of the file is only a factor if the mtime-changes setting ** is false and the useSha1sum flag is false. If the mtime-changes ** setting is true (or undefined - it defaults to true) or if useSha1sum ** is true, then we do not trust the mtime and will examine the on-disk ** content to determine if a file really is the same. ** ** If the mtime is used, it is used only to determine if files are the same. ** If the mtime of a file has changed, we still examine the on-disk content ** to see whether or not the edit was a null-edit. */ void vfile_check_signature(int vid, unsigned int cksigFlags){ int nErr = 0; Stmt q; Blob fileCksum, origCksum; int useMtime = (cksigFlags & CKSIG_SHA1)==0 && db_get_boolean("mtime-changes", 1); db_begin_transaction(); db_prepare(&q, "SELECT id, %Q || pathname," " vfile.mrid, deleted, chnged, uuid, size, mtime" " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid" " WHERE vid=%d ", g.zLocalRoot, vid); while( db_step(&q)==SQLITE_ROW ){ int id, rid, isDeleted; const char *zName; int chnged = 0; int oldChnged; i64 oldMtime; i64 currentMtime; i64 origSize; i64 currentSize; id = db_column_int(&q, 0); zName = db_column_text(&q, 1); rid = db_column_int(&q, 2); isDeleted = db_column_int(&q, 3); oldChnged = chnged = db_column_int(&q, 4); oldMtime = db_column_int64(&q, 7); currentSize = file_size(zName); origSize = db_column_int64(&q, 6); currentMtime = file_mtime(0); if( chnged==0 && (isDeleted || rid==0) ){ /* "fossil rm" or "fossil add" always change the file */ chnged = 1; }else if( !file_isfile(0) && currentSize>=0 ){ if( cksigFlags & CKSIG_ENOTFILE ){ fossil_warning("not an ordinary file: %s", zName); nErr++; } chnged = 1; } if( origSize!=currentSize ){ if( chnged!=1 ){ /* A file size change is definitive - the file has changed. No ** need to check the mtime or sha1sum */ chnged = 1; } }else if( chnged==1 && rid!=0 && !isDeleted ){ /* File is believed to have changed but it is the same size. ** Double check that it really has changed by looking at content. */ assert( origSize==currentSize ); db_ephemeral_blob(&q, 5, &origCksum); if( sha1sum_file(zName, &fileCksum) ){ blob_zero(&fileCksum); } if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0; blob_reset(&origCksum); blob_reset(&fileCksum); }else if( (chnged==0 || chnged==2) && (useMtime==0 || currentMtime!=oldMtime) ){ /* For files that were formerly believed to be unchanged or that were ** changed by merging, if their mtime changes, or unconditionally ** if --sha1sum is used, check to see if they have been edited by ** looking at their SHA1 sum */ assert( origSize==currentSize ); db_ephemeral_blob(&q, 5, &origCksum); if( sha1sum_file(zName, &fileCksum) ){ blob_zero(&fileCksum); } if( blob_compare(&fileCksum, &origCksum) ){ chnged = 1; } blob_reset(&origCksum); blob_reset(&fileCksum); } if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2) ){ i64 desiredMtime; if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){ if( currentMtime!=desiredMtime ){ file_set_mtime(zName, desiredMtime); currentMtime = file_mtime(zName); } } } if( currentMtime!=oldMtime || chnged!=oldChnged ){ db_multi_exec("UPDATE vfile SET mtime=%lld, chnged=%d WHERE id=%d", currentMtime, chnged, id); } } db_finalize(&q); if( nErr ) fossil_fatal("abort due to prior errors"); db_end_transaction(0); } |
Changes to src/xfer.c.
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
|
int isPrivate, /* True if rid is a private artifact */ Blob *pContent, /* The content of the file to send */ Blob *pUuid /* The UUID of the file to send */ ){ static const char *azQuery[] = { "SELECT pid FROM plink x" " WHERE cid=%d" " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" " AND NOT EXISTS(SELECT 1 FROM plink y" " WHERE y.pid=x.cid AND y.cid=x.pid)", "SELECT pid FROM mlink x" " WHERE fid=%d" " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" " AND NOT EXISTS(SELECT 1 FROM mlink y" " WHERE y.pid=x.fid AND y.fid=x.pid)" }; int i; Blob src, delta; int size = 0; int srcId = 0; for(i=0; srcId==0 && i<count(azQuery); i++){ ................................................................................ if( iVers>=3 ){ send_compressed_file(&xfer, seqno); }else{ send_file(&xfer, seqno, 0, 1); } seqno++; } if( seqno>=max ) seqno = 0; @ clone_seqno %d(seqno) }else{ isClone = 1; isPull = 1; deltaFlag = 1; } @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x")) |
|
<
<
|
<
>
<
<
|
|
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
|
int isPrivate, /* True if rid is a private artifact */ Blob *pContent, /* The content of the file to send */ Blob *pUuid /* The UUID of the file to send */ ){ static const char *azQuery[] = { "SELECT pid FROM plink x" " WHERE cid=%d" " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)", "SELECT pid, min(mtime) FROM mlink, event ON mlink.mid=event.objid" " WHERE fid=%d" " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" }; int i; Blob src, delta; int size = 0; int srcId = 0; for(i=0; srcId==0 && i<count(azQuery); i++){ ................................................................................ if( iVers>=3 ){ send_compressed_file(&xfer, seqno); }else{ send_file(&xfer, seqno, 0, 1); } seqno++; } if( seqno>max ) seqno = 0; @ clone_seqno %d(seqno) }else{ isClone = 1; isPull = 1; deltaFlag = 1; } @ push %s(db_get("server-code", "x")) %s(db_get("project-code", "x")) |
Added test/update-test-1.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/bin/sh # # Run this script in an empty directory. A single argument is the full # pathname of the fossil binary. Example: # # sh update-test-1.sh /home/drh/fossil/m1/fossil # export FOSSIL=$1 rm -rf aaa bbb update-test-1.fossil # Create a test repository $FOSSIL new update-test-1.fossil # In checkout aaa, add file one.txt mkdir aaa cd aaa $FOSSIL open ../update-test-1.fossil echo one >one.txt $FOSSIL add one.txt $FOSSIL commit -m add-one --tag add-one # Open checkout bbb. mkdir ../bbb cd ../bbb $FOSSIL open ../update-test-1.fossil # Back in aaa, add file two.txt cd ../aaa echo two >two.txt $FOSSIL add two.txt $FOSSIL commit -m add-two --tag add-two # In bbb, delete file one.txt. Then update the change from aaa that # adds file two. Verify that one.txt says deleted. cd ../bbb $FOSSIL rm one.txt $FOSSIL changes echo '========================================================================' $FOSSIL update echo '======== The previous should show "ADD two.txt" ========================' $FOSSIL changes echo '======== The previous should show "DELETE one.txt" =====================' $FOSSIL commit --test -m check-in echo '======== Only file two.txt is checked in ===============================' |
Added test/update-test-2.sh.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/bin/sh # # Run this script in an empty directory. A single argument is the full # pathname of the fossil binary. Example: # # sh update-test-2.sh /home/drh/fossil/m1/fossil # export FOSSIL=$1 rm -rf aaa bbb update-test-2.fossil # Create a test repository $FOSSIL new update-test-2.fossil # In checkout aaa, add file one.txt. mkdir aaa cd aaa $FOSSIL open ../update-test-2.fossil echo one >one.txt $FOSSIL add one.txt $FOSSIL commit -m add-one --tag add-one # Create checkout bbb. mkdir ../bbb cd ../bbb $FOSSIL open ../update-test-2.fossil # Back in aaa, make changes to one.txt. Add file two.txt. cd ../aaa echo change >>one.txt echo two >two.txt $FOSSIL add two.txt $FOSSIL commit -m 'chng one and add two' --tag add-two # In bbb, remove one.txt, then update. cd ../bbb $FOSSIL rm one.txt $FOSSIL changes echo '========================================================================' $FOSSIL update echo '======== Previous should show "ADD two.txt" and conflict on one.txt ====' $FOSSIL changes echo '======== The previous should show "DELETE one.txt" =====================' $FOSSIL commit --test -m 'check-in' echo '======== Only file two.txt is checked in ===============================' |