Fossil SCM

Immediately backout [7c8cc2adab]. Turns out it has a problem with showing added files.

andygoth 2016-11-06 23:47 trunk
Commit d87c85c1c7f34c8abb0bfb57d3af9f76354bdabe
A file

No diff available

+6 -6
--- src/add.c
+++ src/add.c
@@ -226,11 +226,11 @@
226226
if( filenames_are_case_sensitive() ){
227227
xCmp = fossil_strcmp;
228228
}else{
229229
xCmp = fossil_stricmp;
230230
}
231
- db_prepare(&loop, "SELECT pathname FROM sfile ORDER BY pathname");
231
+ db_prepare(&loop, "SELECT x FROM sfile ORDER BY x");
232232
while( db_step(&loop)==SQLITE_ROW ){
233233
const char *zToAdd = db_column_text(&loop, 0);
234234
if( fossil_strcmp(zToAdd, zRepo)==0 ) continue;
235235
for(i=0; (zReserved = fossil_reserved_name(i, 0))!=0; i++){
236236
if( xCmp(zToAdd, zReserved)==0 ) break;
@@ -307,11 +307,11 @@
307307
zIgnoreFlag = db_get("ignore-glob", 0);
308308
}
309309
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
310310
vid = db_lget_int("checkout",0);
311311
db_begin_transaction();
312
- db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
312
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
313313
filename_collation());
314314
pClean = glob_create(zCleanFlag);
315315
pIgnore = glob_create(zIgnoreFlag);
316316
nRoot = strlen(g.zLocalRoot);
317317
@@ -349,11 +349,11 @@
349349
blob_reset(&fullName);
350350
continue;
351351
}
352352
}
353353
db_multi_exec(
354
- "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
354
+ "INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
355355
zTreeName
356356
);
357357
}
358358
blob_reset(&fullName);
359359
}
@@ -474,11 +474,11 @@
474474
removeFiles = db_get_boolean("mv-rm-files",0);
475475
#else
476476
removeFiles = FOSSIL_MV_RM_FILE;
477477
#endif
478478
}
479
- db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
479
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
480480
filename_collation());
481481
for(i=2; i<g.argc; i++){
482482
Blob treeName;
483483
char *zTreeName;
484484
@@ -494,11 +494,11 @@
494494
filename_collation(), zTreeName, filename_collation()
495495
);
496496
blob_reset(&treeName);
497497
}
498498
499
- db_prepare(&loop, "SELECT pathname FROM sfile");
499
+ db_prepare(&loop, "SELECT x FROM sfile");
500500
while( db_step(&loop)==SQLITE_ROW ){
501501
fossil_print("DELETED %s\n", db_column_text(&loop, 0));
502502
if( removeFiles ) add_file_to_remove(db_column_text(&loop, 0));
503503
}
504504
db_finalize(&loop);
@@ -670,11 +670,11 @@
670670
** Populate the temp table "sfile" with the names of all unmanaged
671671
** files currently in the check-out, except for files that match the
672672
** --ignore or ignore-glob patterns and dot-files. Then add all of
673673
** the files in the sfile temp table to the set of managed files.
674674
*/
675
- db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
675
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
676676
filename_collation());
677677
n = strlen(g.zLocalRoot);
678678
blob_init(&path, g.zLocalRoot, n-1);
679679
/* now we read the complete file structure into a temp table */
680680
pClean = glob_create(zCleanFlag);
681681
--- src/add.c
+++ src/add.c
@@ -226,11 +226,11 @@
226 if( filenames_are_case_sensitive() ){
227 xCmp = fossil_strcmp;
228 }else{
229 xCmp = fossil_stricmp;
230 }
231 db_prepare(&loop, "SELECT pathname FROM sfile ORDER BY pathname");
232 while( db_step(&loop)==SQLITE_ROW ){
233 const char *zToAdd = db_column_text(&loop, 0);
234 if( fossil_strcmp(zToAdd, zRepo)==0 ) continue;
235 for(i=0; (zReserved = fossil_reserved_name(i, 0))!=0; i++){
236 if( xCmp(zToAdd, zReserved)==0 ) break;
@@ -307,11 +307,11 @@
307 zIgnoreFlag = db_get("ignore-glob", 0);
308 }
309 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
310 vid = db_lget_int("checkout",0);
311 db_begin_transaction();
312 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
313 filename_collation());
314 pClean = glob_create(zCleanFlag);
315 pIgnore = glob_create(zIgnoreFlag);
316 nRoot = strlen(g.zLocalRoot);
317
@@ -349,11 +349,11 @@
349 blob_reset(&fullName);
350 continue;
351 }
352 }
353 db_multi_exec(
354 "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
355 zTreeName
356 );
357 }
358 blob_reset(&fullName);
359 }
@@ -474,11 +474,11 @@
474 removeFiles = db_get_boolean("mv-rm-files",0);
475 #else
476 removeFiles = FOSSIL_MV_RM_FILE;
477 #endif
478 }
479 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
480 filename_collation());
481 for(i=2; i<g.argc; i++){
482 Blob treeName;
483 char *zTreeName;
484
@@ -494,11 +494,11 @@
494 filename_collation(), zTreeName, filename_collation()
495 );
496 blob_reset(&treeName);
497 }
498
499 db_prepare(&loop, "SELECT pathname FROM sfile");
500 while( db_step(&loop)==SQLITE_ROW ){
501 fossil_print("DELETED %s\n", db_column_text(&loop, 0));
502 if( removeFiles ) add_file_to_remove(db_column_text(&loop, 0));
503 }
504 db_finalize(&loop);
@@ -670,11 +670,11 @@
670 ** Populate the temp table "sfile" with the names of all unmanaged
671 ** files currently in the check-out, except for files that match the
672 ** --ignore or ignore-glob patterns and dot-files. Then add all of
673 ** the files in the sfile temp table to the set of managed files.
674 */
675 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
676 filename_collation());
677 n = strlen(g.zLocalRoot);
678 blob_init(&path, g.zLocalRoot, n-1);
679 /* now we read the complete file structure into a temp table */
680 pClean = glob_create(zCleanFlag);
681
--- src/add.c
+++ src/add.c
@@ -226,11 +226,11 @@
226 if( filenames_are_case_sensitive() ){
227 xCmp = fossil_strcmp;
228 }else{
229 xCmp = fossil_stricmp;
230 }
231 db_prepare(&loop, "SELECT x FROM sfile ORDER BY x");
232 while( db_step(&loop)==SQLITE_ROW ){
233 const char *zToAdd = db_column_text(&loop, 0);
234 if( fossil_strcmp(zToAdd, zRepo)==0 ) continue;
235 for(i=0; (zReserved = fossil_reserved_name(i, 0))!=0; i++){
236 if( xCmp(zToAdd, zReserved)==0 ) break;
@@ -307,11 +307,11 @@
307 zIgnoreFlag = db_get("ignore-glob", 0);
308 }
309 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
310 vid = db_lget_int("checkout",0);
311 db_begin_transaction();
312 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
313 filename_collation());
314 pClean = glob_create(zCleanFlag);
315 pIgnore = glob_create(zIgnoreFlag);
316 nRoot = strlen(g.zLocalRoot);
317
@@ -349,11 +349,11 @@
349 blob_reset(&fullName);
350 continue;
351 }
352 }
353 db_multi_exec(
354 "INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
355 zTreeName
356 );
357 }
358 blob_reset(&fullName);
359 }
@@ -474,11 +474,11 @@
474 removeFiles = db_get_boolean("mv-rm-files",0);
475 #else
476 removeFiles = FOSSIL_MV_RM_FILE;
477 #endif
478 }
479 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
480 filename_collation());
481 for(i=2; i<g.argc; i++){
482 Blob treeName;
483 char *zTreeName;
484
@@ -494,11 +494,11 @@
494 filename_collation(), zTreeName, filename_collation()
495 );
496 blob_reset(&treeName);
497 }
498
499 db_prepare(&loop, "SELECT x FROM sfile");
500 while( db_step(&loop)==SQLITE_ROW ){
501 fossil_print("DELETED %s\n", db_column_text(&loop, 0));
502 if( removeFiles ) add_file_to_remove(db_column_text(&loop, 0));
503 }
504 db_finalize(&loop);
@@ -670,11 +670,11 @@
670 ** Populate the temp table "sfile" with the names of all unmanaged
671 ** files currently in the check-out, except for files that match the
672 ** --ignore or ignore-glob patterns and dot-files. Then add all of
673 ** the files in the sfile temp table to the set of managed files.
674 */
675 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
676 filename_collation());
677 n = strlen(g.zLocalRoot);
678 blob_init(&path, g.zLocalRoot, n-1);
679 /* now we read the complete file structure into a temp table */
680 pClean = glob_create(zCleanFlag);
681
+270 -490
--- src/checkin.c
+++ src/checkin.c
@@ -21,115 +21,32 @@
2121
#include "config.h"
2222
#include "checkin.h"
2323
#include <assert.h>
2424
2525
/*
26
-** Change filter options.
27
-*/
28
-enum {
29
- /* Zero-based bit indexes. */
30
- CB_EDITED , CB_UPDATED , CB_CHANGED, CB_MISSING , CB_ADDED, CB_DELETED,
31
- CB_RENAMED, CB_CONFLICT, CB_META , CB_UNCHANGED, CB_EXTRA, CB_MERGE ,
32
- CB_RELPATH, CB_CLASSIFY, CB_MTIME , CB_SIZE , CB_FATAL, CB_COMMENT,
33
-
34
- /* Bitmask values. */
35
- C_EDITED = 1 << CB_EDITED, /* Edited, merged, and conflicted files. */
36
- C_UPDATED = 1 << CB_UPDATED, /* Files updated by merge/integrate. */
37
- C_CHANGED = 1 << CB_CHANGED, /* Treated the same as the above two. */
38
- C_MISSING = 1 << CB_MISSING, /* Missing and non- files. */
39
- C_ADDED = 1 << CB_ADDED, /* Added files. */
40
- C_DELETED = 1 << CB_DELETED, /* Deleted files. */
41
- C_RENAMED = 1 << CB_RENAMED, /* Renamed files. */
42
- C_CONFLICT = 1 << CB_CONFLICT, /* Files having merge conflicts. */
43
- C_META = 1 << CB_META, /* Files with metadata changes. */
44
- C_UNCHANGED = 1 << CB_UNCHANGED, /* Unchanged files. */
45
- C_EXTRA = 1 << CB_EXTRA, /* Unmanaged files. */
46
- C_MERGE = 1 << CB_MERGE, /* Merge contributors. */
47
- C_FILTER = C_EDITED | C_UPDATED | C_CHANGED | C_MISSING | C_ADDED
48
- | C_DELETED | C_RENAMED | C_CONFLICT | C_META | C_UNCHANGED
49
- | C_EXTRA | C_MERGE, /* All filter bits. */
50
- C_ALL = C_FILTER & ~(C_EXTRA | C_MERGE),/* All managed files. */
51
- C_DIFFER = C_FILTER & ~(C_UNCHANGED | C_MERGE),/* All differences. */
52
- C_RELPATH = 1 << CB_RELPATH, /* Show relative paths. */
53
- C_CLASSIFY = 1 << CB_CLASSIFY, /* Show file change types. */
54
- C_DEFAULT = (C_ALL & ~C_UNCHANGED) | C_MERGE | C_CLASSIFY,
55
- C_MTIME = 1 << CB_MTIME, /* Show file modification time. */
56
- C_SIZE = 1 << CB_SIZE, /* Show file size in bytes. */
57
- C_FATAL = (1 << CB_FATAL) | C_MISSING, /* Fail on MISSING/NOT_A_FILE. */
58
- C_COMMENT = 1 << CB_COMMENT, /* Precede each line with "# ". */
59
-};
60
-
61
-/*
62
-** Create a TEMP table named SFILE and add all unmanaged files named on
63
-** the command-line to that table. If directories are named, then add
64
-** all unmanaged files contained underneath those directories. If there
65
-** are no files or directories named on the command-line, then add all
66
-** unmanaged files anywhere in the checkout.
67
-*/
68
-static void locate_unmanaged_files(
69
- int argc, /* Number of command-line arguments to examine */
70
- char **argv, /* values of command-line arguments */
71
- unsigned scanFlags, /* Zero or more SCAN_xxx flags */
72
- Glob *pIgnore /* Do not add files that match this GLOB */
73
-){
74
- Blob name; /* Name of a candidate file or directory */
75
- char *zName; /* Name of a candidate file or directory */
76
- int isDir; /* 1 for a directory, 0 if doesn't exist, 2 for anything else */
77
- int i; /* Loop counter */
78
- int nRoot; /* length of g.zLocalRoot */
79
-
80
- db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s,"
81
- " mtime INTEGER, size INTEGER)", filename_collation());
82
- nRoot = (int)strlen(g.zLocalRoot);
83
- if( argc==0 ){
84
- blob_init(&name, g.zLocalRoot, nRoot - 1);
85
- vfile_scan(&name, blob_size(&name), scanFlags, pIgnore, 0);
86
- blob_reset(&name);
87
- }else{
88
- for(i=0; i<argc; i++){
89
- file_canonical_name(argv[i], &name, 0);
90
- zName = blob_str(&name);
91
- isDir = file_wd_isdir(zName);
92
- if( isDir==1 ){
93
- vfile_scan(&name, nRoot-1, scanFlags, pIgnore, 0);
94
- }else if( isDir==0 ){
95
- fossil_warning("not found: %s", &zName[nRoot]);
96
- }else if( file_access(zName, R_OK) ){
97
- fossil_fatal("cannot open %s", &zName[nRoot]);
98
- }else{
99
- db_multi_exec(
100
- "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
101
- &zName[nRoot]
102
- );
103
- }
104
- blob_reset(&name);
105
- }
106
- }
107
-}
108
-
109
-/*
110
-** Generate text describing all changes.
26
+** Generate text describing all changes. Prepend zPrefix to each line
27
+** of output.
11128
**
11229
** We assume that vfile_check_signature has been run.
30
+**
31
+** If missingIsFatal is true, then any files that are missing or which
32
+** are not true files results in a fatal error.
11333
*/
11434
static void status_report(
11535
Blob *report, /* Append the status report here */
116
- unsigned flags /* Filter and other configuration flags */
36
+ const char *zPrefix, /* Prefix on each line of the report */
37
+ int missingIsFatal, /* MISSING and NOT_A_FILE are fatal errors */
38
+ int cwdRelative /* Report relative to the current working dir */
11739
){
11840
Stmt q;
41
+ int nPrefix = strlen(zPrefix);
11942
int nErr = 0;
12043
Blob rewrittenPathname;
121
- Blob sql = BLOB_INITIALIZER, where = BLOB_INITIALIZER;
44
+ Blob where;
12245
const char *zName;
12346
int i;
12447
125
- /* Skip the file report if no files are requested at all. */
126
- if( !(flags & (C_ALL | C_EXTRA)) ){
127
- goto skipFiles;
128
- }
129
-
130
- /* Assemble the path-limiting WHERE clause, if any. */
13148
blob_zero(&where);
13249
for(i=2; i<g.argc; i++){
13350
Blob fname;
13451
file_tree_name(g.argv[i], &fname, 0, 1);
13552
zName = blob_str(&fname);
@@ -144,187 +61,99 @@
14461
filename_collation(), zName, filename_collation(),
14562
zName, filename_collation()
14663
);
14764
}
14865
149
- /* Obtain the list of managed files if appropriate. */
150
- blob_zero(&sql);
151
- if( flags & C_ALL ){
152
- /* Start with a list of all managed files. */
153
- blob_append_sql(&sql,
154
- "SELECT pathname, %s as mtime, %s as size, deleted, chnged, rid,"
155
- " coalesce(origname!=pathname,0) AS renamed, islink, 1 AS managed"
156
- " FROM vfile, blob USING (rid)"
157
- " WHERE is_selected(id)%s",
158
- flags & C_MTIME ? "datetime(checkin_mtime(:vid, rid), "
159
- "'unixepoch', toLocal())" : "''" /*safe-for-%s*/,
160
- flags & C_SIZE ? "blob.size" : "0" /*safe-for-%s*/,
161
- blob_sql_text(&where));
162
-
163
- /* Exclude unchanged files unless requested. */
164
- if( !(flags & C_UNCHANGED) ){
165
- blob_append_sql(&sql,
166
- " AND (chnged OR deleted OR rid=0 OR pathname!=origname)");
167
- }
168
- }
169
-
170
- /* If C_EXTRA, add unmanaged files to the query result too. */
171
- if( flags & C_EXTRA ){
172
- if( blob_size(&sql) ){
173
- blob_append_sql(&sql, " UNION ALL");
174
- }
175
- blob_append_sql(&sql,
176
- " SELECT pathname, %s, %s, 0, 0, 0, 0, 0, 0"
177
- " FROM sfile WHERE pathname NOT IN (%s)%s",
178
- flags & C_MTIME ? "datetime(mtime, 'unixepoch', toLocal())" : "''",
179
- flags & C_SIZE ? "size" : "0",
180
- fossil_all_reserved_names(0), blob_sql_text(&where));
181
- }
182
- blob_reset(&where);
183
-
184
- /* Pre-create the "ok" temporary table so the checkin_mtime() SQL function
185
- * does not lead to SQLITE_ABORT_ROLLBACK during execution of the OP_OpenRead
186
- * SQLite opcode. checkin_mtime() calls mtime_of_manifest_file() which
187
- * creates a temporary table if it doesn't already exist, thus invalidating
188
- * the prepared statement in the middle of its execution. */
189
- db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)");
190
-
191
- /* Append an ORDER BY clause then compile the query. */
192
- blob_append_sql(&sql, " ORDER BY pathname");
193
- db_prepare(&q, "%s", blob_sql_text(&sql));
194
- blob_reset(&sql);
195
-
196
- /* Bind the checkout version ID to the query if needed. */
197
- if( (flags & C_ALL) && (flags & C_MTIME) ){
198
- db_bind_int(&q, ":vid", db_lget_int("checkout", 0));
199
- }
200
-
201
- /* Execute the query and assemble the report. */
202
- blob_zero(&rewrittenPathname);
203
- while( db_step(&q)==SQLITE_ROW ){
204
- const char *zPathname = db_column_text(&q, 0);
205
- const char *zClass = 0;
206
- int isManaged = db_column_int(&q, 8);
207
- const char *zMtime = db_column_text(&q, 1);
208
- int size = db_column_int(&q, 2);
209
- int isDeleted = db_column_int(&q, 3);
210
- int isChnged = db_column_int(&q, 4);
211
- int isNew = isManaged && !db_column_int(&q, 5);
212
- int isRenamed = db_column_int(&q, 6);
213
- int isLink = db_column_int(&q, 7);
214
- char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
215
- int isMissing = !file_wd_isfile_or_link(zFullName);
216
-
217
- /* Determine the file change classification, if any. */
218
- if( (flags & C_DELETED) && isDeleted ){
219
- zClass = "DELETED";
220
- }else if( (flags & C_MISSING) && isMissing ){
221
- if( file_access(zFullName, F_OK)==0 ){
222
- zClass = "NOT_A_FILE";
223
- if( flags & C_FATAL ){
224
- fossil_warning("not a file: %s", zFullName);
225
- nErr++;
226
- }
227
- }else{
228
- zClass = "MISSING";
229
- if( flags & C_FATAL ){
230
- fossil_warning("missing file: %s", zFullName);
231
- nErr++;
232
- }
233
- }
234
- }else if( (flags & C_ADDED) && isNew ){
235
- zClass = "ADDED";
236
- }else if( (flags & (C_UPDATED | C_CHANGED)) && isChnged==2 ){
237
- zClass = "UPDATED_BY_MERGE";
238
- }else if( (flags & C_ADDED) && isChnged==3 ){
239
- zClass = "ADDED_BY_MERGE";
240
- }else if( (flags & (C_UPDATED | C_CHANGED)) && isChnged==4 ){
241
- zClass = "UPDATED_BY_INTEGRATE";
242
- }else if( (flags & C_ADDED) && isChnged==5 ){
243
- zClass = "ADDED_BY_INTEGRATE";
244
- }else if( (flags & C_META) && isChnged==6 ){
245
- zClass = "EXECUTABLE";
246
- }else if( (flags & C_META) && isChnged==7 ){
247
- zClass = "SYMLINK";
248
- }else if( (flags & C_META) && isChnged==8 ){
249
- zClass = "UNEXEC";
250
- }else if( (flags & C_META) && isChnged==9 ){
251
- zClass = "UNLINK";
252
- }else if( (flags & C_CONFLICT) && isChnged && !isLink
253
- && file_contains_merge_marker(zFullName) ){
254
- zClass = "CONFLICT";
255
- }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged
256
- && (isChnged<2 || isChnged>9) ){
257
- zClass = "EDITED";
258
- }else if( (flags & C_RENAMED) && isRenamed ){
259
- zClass = "RENAMED";
260
- }else if( (flags & C_UNCHANGED) && isManaged && !isDeleted && !isMissing
261
- && !isNew && !isChnged && !isRenamed ){
262
- zClass = "UNCHANGED";
263
- }else if( (flags & C_EXTRA) && !isManaged ){
264
- zClass = "EXTRA";
265
- }
266
-
267
- /* Only report files for which a change classification was determined. */
268
- if( zClass ){
269
- if( flags & C_COMMENT ){
270
- blob_append(report, "# ", 2);
271
- }
272
- if( flags & C_CLASSIFY ){
273
- blob_appendf(report, "%-10s ", zClass);
274
- }
275
- if( flags & C_MTIME ){
276
- blob_append(report, zMtime, -1);
277
- blob_append(report, " ", 2);
278
- }
279
- if( flags & C_SIZE ){
280
- blob_appendf(report, "%7d ", size);
281
- }
282
- if( flags & C_RELPATH ){
283
- /* If C_RELPATH, display paths relative to current directory. */
284
- const char *zDisplayName;
285
- file_relative_name(zFullName, &rewrittenPathname, 0);
286
- zDisplayName = blob_str(&rewrittenPathname);
287
- if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
288
- zDisplayName += 2; /* no unnecessary ./ prefix */
289
- }
290
- blob_append(report, zDisplayName, -1);
291
- }else{
292
- /* If not C_RELPATH, display paths relative to project root. */
293
- blob_append(report, zPathname, -1);
294
- }
295
- blob_append(report, "\n", 1);
66
+ db_prepare(&q,
67
+ "SELECT pathname, deleted, chnged,"
68
+ " rid, coalesce(origname!=pathname,0), islink"
69
+ " FROM vfile "
70
+ " WHERE is_selected(id) %s"
71
+ " AND (chnged OR deleted OR rid=0 OR pathname!=origname)"
72
+ " ORDER BY 1 /*scan*/",
73
+ blob_sql_text(&where)
74
+ );
75
+ blob_zero(&rewrittenPathname);
76
+ while( db_step(&q)==SQLITE_ROW ){
77
+ const char *zPathname = db_column_text(&q,0);
78
+ const char *zDisplayName = zPathname;
79
+ int isDeleted = db_column_int(&q, 1);
80
+ int isChnged = db_column_int(&q,2);
81
+ int isNew = db_column_int(&q,3)==0;
82
+ int isRenamed = db_column_int(&q,4);
83
+ int isLink = db_column_int(&q,5);
84
+ char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
85
+ if( cwdRelative ){
86
+ file_relative_name(zFullName, &rewrittenPathname, 0);
87
+ zDisplayName = blob_str(&rewrittenPathname);
88
+ if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
89
+ zDisplayName += 2; /* no unnecessary ./ prefix */
90
+ }
91
+ }
92
+ blob_append(report, zPrefix, nPrefix);
93
+ if( isDeleted ){
94
+ blob_appendf(report, "DELETED %s\n", zDisplayName);
95
+ }else if( !file_wd_isfile_or_link(zFullName) ){
96
+ if( file_access(zFullName, F_OK)==0 ){
97
+ blob_appendf(report, "NOT_A_FILE %s\n", zDisplayName);
98
+ if( missingIsFatal ){
99
+ fossil_warning("not a file: %s", zDisplayName);
100
+ nErr++;
101
+ }
102
+ }else{
103
+ blob_appendf(report, "MISSING %s\n", zDisplayName);
104
+ if( missingIsFatal ){
105
+ fossil_warning("missing file: %s", zDisplayName);
106
+ nErr++;
107
+ }
108
+ }
109
+ }else if( isNew ){
110
+ blob_appendf(report, "ADDED %s\n", zDisplayName);
111
+ }else if( isChnged ){
112
+ if( isChnged==2 ){
113
+ blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
114
+ }else if( isChnged==3 ){
115
+ blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
116
+ }else if( isChnged==4 ){
117
+ blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
118
+ }else if( isChnged==5 ){
119
+ blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
120
+ }else if( isChnged==6 ){
121
+ blob_appendf(report, "EXECUTABLE %s\n", zDisplayName);
122
+ }else if( isChnged==7 ){
123
+ blob_appendf(report, "SYMLINK %s\n", zDisplayName);
124
+ }else if( isChnged==8 ){
125
+ blob_appendf(report, "UNEXEC %s\n", zDisplayName);
126
+ }else if( isChnged==9 ){
127
+ blob_appendf(report, "UNLINK %s\n", zDisplayName);
128
+ }else if( !isLink && file_contains_merge_marker(zFullName) ){
129
+ blob_appendf(report, "CONFLICT %s\n", zDisplayName);
130
+ }else{
131
+ blob_appendf(report, "EDITED %s\n", zDisplayName);
132
+ }
133
+ }else if( isRenamed ){
134
+ blob_appendf(report, "RENAMED %s\n", zDisplayName);
135
+ }else{
136
+ report->nUsed -= nPrefix;
296137
}
297138
free(zFullName);
298139
}
299140
blob_reset(&rewrittenPathname);
300141
db_finalize(&q);
301
-
302
- /* If C_MERGE, put merge contributors at the end of the report. */
303
-skipFiles:
304
- if( flags & C_MERGE ){
305
- db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
306
- " WHERE id<=0");
307
- while( db_step(&q)==SQLITE_ROW ){
308
- if( flags & C_COMMENT ){
309
- blob_append(report, "# ", 2);
310
- }
311
- if( flags & C_CLASSIFY ){
312
- const char *zClass;
313
- switch( db_column_int(&q, 1) ){
314
- case -1: zClass = "CHERRYPICK" ; break;
315
- case -2: zClass = "BACKOUT" ; break;
316
- case -4: zClass = "INTEGRATE" ; break;
317
- default: zClass = "MERGED_WITH"; break;
318
- }
319
- blob_appendf(report, "%-10s ", zClass);
320
- }
321
- blob_append(report, db_column_text(&q, 0), -1);
322
- blob_append(report, "\n", 1);
323
- }
324
- db_finalize(&q);
325
- }
142
+ db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
143
+ " WHERE id<=0");
144
+ while( db_step(&q)==SQLITE_ROW ){
145
+ const char *zLabel = "MERGED_WITH ";
146
+ switch( db_column_int(&q, 1) ){
147
+ case -1: zLabel = "CHERRYPICK "; break;
148
+ case -2: zLabel = "BACKOUT "; break;
149
+ case -4: zLabel = "INTEGRATE "; break;
150
+ }
151
+ blob_append(report, zPrefix, nPrefix);
152
+ blob_appendf(report, "%s%s\n", zLabel, db_column_text(&q, 0));
153
+ }
154
+ db_finalize(&q);
326155
if( nErr ){
327156
fossil_fatal("aborting due to prior errors");
328157
}
329158
}
330159
@@ -341,229 +170,116 @@
341170
int relPathOption = find_option("rel-paths", 0, 0)!=0;
342171
if( absPathOption ){ relativePaths = 0; }
343172
if( relPathOption ){ relativePaths = 1; }
344173
return relativePaths;
345174
}
175
+
176
+void print_changes(
177
+ int useSha1sum, /* Verify file status using SHA1 hashing rather
178
+ than relying on file mtimes. */
179
+ int showHdr, /* Identify the repository if there are changes */
180
+ int verboseFlag, /* Say "(none)" if there are no changes */
181
+ int cwdRelative /* Report relative to the current working dir */
182
+){
183
+ Blob report;
184
+ int vid;
185
+ blob_zero(&report);
186
+
187
+ vid = db_lget_int("checkout", 0);
188
+ vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0);
189
+ status_report(&report, "", 0, cwdRelative);
190
+ if( verboseFlag && blob_size(&report)==0 ){
191
+ blob_append(&report, " (none)\n", -1);
192
+ }
193
+ if( showHdr && blob_size(&report)>0 ){
194
+ fossil_print("Changes for %s at %s:\n", db_get("project-name","???"),
195
+ g.zLocalRoot);
196
+ }
197
+ blob_write_to_file(&report, "-");
198
+ blob_reset(&report);
199
+}
346200
347201
/*
348202
** COMMAND: changes
203
+**
204
+** Usage: %fossil changes ?OPTIONS?
205
+**
206
+** Report on the edit status of all files in the current checkout.
207
+**
208
+** Pathnames are displayed according to the "relative-paths" setting,
209
+** unless overridden by the --abs-paths or --rel-paths options.
210
+**
211
+** Options:
212
+** --abs-paths Display absolute pathnames.
213
+** --rel-paths Display pathnames relative to the current working
214
+** directory.
215
+** --sha1sum Verify file status using SHA1 hashing rather
216
+** than relying on file mtimes.
217
+** --header Identify the repository if there are changes
218
+** -v|--verbose Say "(none)" if there are no changes
219
+**
220
+** See also: extras, ls, status
221
+*/
222
+void changes_cmd(void){
223
+ int useSha1sum = find_option("sha1sum", 0, 0)!=0;
224
+ int showHdr = find_option("header",0,0)!=0;
225
+ int verboseFlag = find_option("verbose","v",0)!=0;
226
+ int cwdRelative = 0;
227
+ db_must_be_within_tree();
228
+ cwdRelative = determine_cwd_relative_option();
229
+
230
+ /* We should be done with options.. */
231
+ verify_all_options();
232
+
233
+ print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
234
+}
235
+
236
+/*
349237
** COMMAND: status
350238
**
351
-** Usage: %fossil changes|status ?OPTIONS? ?PATHS ...?
352
-**
353
-** Report the change status of files in the current checkout. If one or
354
-** more PATHS are specified, only changes among the named files and
355
-** directories are reported. Directories are searched recursively.
356
-**
357
-** The status command is similar to the changes command, except it lacks
358
-** several of the options supported by changes and it has its own header
359
-** and footer information. The header information is a subset of that
360
-** shown by the info command, and the footer shows if there are any forks.
361
-** Change type classification is always enabled for the status command.
362
-**
363
-** Each line of output is the name of a changed file, with paths shown
364
-** according to the "relative-paths" setting, unless overridden by the
365
-** --abs-paths or --rel-paths options.
366
-**
367
-** By default, all changed files are selected for display. This behavior
368
-** can be overridden by using one or more filter options (listed below),
369
-** in which case only files with the specified change type(s) are shown.
370
-** As a special case, the --no-merge option does not inhibit this default.
371
-** This default shows exactly the set of changes that would be checked
372
-** in by the commit command.
373
-**
374
-** If no filter options are used, or if the --merge option is used, the
375
-** SHA1 hash of each merge contributor check-in version is displayed at
376
-** the end of the report. The --no-merge option is useful to display the
377
-** default set of changed files without the merge contributors.
378
-**
379
-** If change type classification is enabled, each output line starts with
380
-** a code describing the file's change type, e.g. EDITED or RENAMED. It
381
-** is enabled by default unless exactly one change type is selected. For
382
-** the purposes of determining the default, --changed counts as selecting
383
-** one change type. The default can be overridden by the --classify or
384
-** --no-classify options.
385
-**
386
-** If both --merge and --no-merge are used, --no-merge has priority. The
387
-** same is true of --classify and --no-classify.
388
-**
389
-** The "fossil changes --extra" command is equivalent to "fossil extras".
390
-**
391
-** --edited and --updated produce disjoint sets. --updated shows a file
392
-** only when it is identical to that of its merge contributor, and the
393
-** change type classification is UPDATED_BY_MERGE or UPDATED_BY_INTEGRATE.
394
-** If the file had to be merged with any other changes, it is considered
395
-** to be merged or conflicted and therefore will be shown by --edited, not
396
-** --updated, with types EDITED or CONFLICT. The --changed option can be
397
-** used to display the union of --edited and --updated.
398
-**
399
-** --differ is so named because it lists all the differences between the
400
-** checked-out version and the checkout directory. In addition to the
401
-** default changes (besides --merge), it lists extra files which (assuming
402
-** ignore-glob is set correctly) may be worth adding. Prior to doing a
403
-** commit, it is good practice to check --differ to see not only which
404
-** changes would be committed but also if any files need to be added.
405
-**
406
-** General options:
239
+** Usage: %fossil status ?OPTIONS?
240
+**
241
+** Report on the status of the current checkout.
242
+**
243
+** Pathnames are displayed according to the "relative-paths" setting,
244
+** unless overridden by the --abs-paths or --rel-paths options.
245
+**
246
+** Options:
247
+**
407248
** --abs-paths Display absolute pathnames.
408249
** --rel-paths Display pathnames relative to the current working
409250
** directory.
410
-** --sha1sum Verify file status using SHA1 hashing rather than
411
-** relying on file mtimes.
412
-** --case-sensitive <BOOL> Override case-sensitive setting.
413
-** --dotfiles Include unmanaged files beginning with a dot.
414
-** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns.
415
-**
416
-** Options specific to the changes command:
417
-** --header Identify the repository if report is non-empty.
418
-** -v|--verbose Say "(none)" if the change report is empty.
419
-** --classify Start each line with the file's change type.
420
-** --no-classify Do not print file change types.
421
-**
422
-** Filter options:
423
-** --edited Display edited, merged, and conflicted files.
424
-** --updated Display files updated by merge/integrate.
425
-** --changed Combination of the above two options.
426
-** --missing Display missing files.
427
-** --added Display added files.
428
-** --deleted Display deleted files.
429
-** --renamed Display renamed files.
430
-** --conflict Display files having merge conflicts.
431
-** --meta Display files with metadata changes.
432
-** --unchanged Display unchanged files.
433
-** --all Display all managed files, i.e. all of the above.
434
-** --extra Display unmanaged files.
435
-** --differ Display modified and extra files.
436
-** --merge Display merge contributors.
437
-** --no-merge Do not display merge contributors.
438
-**
439
-** See also: extras, ls
251
+** --sha1sum Verify file status using SHA1 hashing rather
252
+** than relying on file mtimes.
253
+**
254
+** See also: changes, extras, ls
440255
*/
441256
void status_cmd(void){
442
- /* Affirmative and negative flag option tables. */
443
- static const struct {
444
- const char *option; /* Flag name. */
445
- unsigned mask; /* Flag bits. */
446
- } flagDefs[] = {
447
- {"edited" , C_EDITED }, {"updated" , C_UPDATED },
448
- {"changed" , C_CHANGED }, {"missing" , C_MISSING },
449
- {"added" , C_ADDED }, {"deleted" , C_DELETED },
450
- {"renamed" , C_RENAMED }, {"conflict" , C_CONFLICT },
451
- {"meta" , C_META }, {"unchanged" , C_UNCHANGED},
452
- {"all" , C_ALL }, {"extra" , C_EXTRA },
453
- {"differ" , C_DIFFER }, {"merge" , C_MERGE },
454
- {"classify", C_CLASSIFY},
455
- }, noFlagDefs[] = {
456
- {"no-merge", C_MERGE }, {"no-classify", C_CLASSIFY },
457
- };
458
-
459
- Blob report = BLOB_INITIALIZER;
460
- enum {CHANGES, STATUS} command = *g.argv[1]=='s' ? STATUS : CHANGES;
257
+ int vid;
461258
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
462
- int showHdr = command==CHANGES && find_option("header", 0, 0);
463
- int verboseFlag = command==CHANGES && find_option("verbose", "v", 0);
464
- const char *zIgnoreFlag = find_option("ignore", 0, 1);
465
- unsigned scanFlags = 0;
466
- unsigned flags = 0;
467
- int vid, i;
468
-
469
- /* Load affirmative flag options. */
470
- for( i=0; i<count(flagDefs); ++i ){
471
- if( (command==CHANGES || !(flagDefs[i].mask & C_CLASSIFY))
472
- && find_option(flagDefs[i].option, 0, 0) ){
473
- flags |= flagDefs[i].mask;
474
- }
475
- }
476
-
477
- /* If no filter options are specified, enable defaults. */
478
- if( !(flags & C_FILTER) ){
479
- flags |= C_DEFAULT;
480
- }
481
-
482
- /* If more than one filter is enabled, enable classification. This is tricky.
483
- * Having one filter means flags masked by C_FILTER is a power of two. If a
484
- * number masked by one less than itself is zero, it's either zero or a power
485
- * of two. It's already known to not be zero because of the above defaults.
486
- * Unlike --all, --changed is a single filter, i.e. it sets only one bit.
487
- * Also force classification for the status command. */
488
- if( command==STATUS || (flags & (flags-1) & C_FILTER) ){
489
- flags |= C_CLASSIFY;
490
- }
491
-
492
- /* Negative flag options override defaults applied above. */
493
- for( i=0; i<count(noFlagDefs); ++i ){
494
- if( (command==CHANGES || !(noFlagDefs[i].mask & C_CLASSIFY))
495
- && find_option(noFlagDefs[i].option, 0, 0) ){
496
- flags &= ~noFlagDefs[i].mask;
497
- }
498
- }
499
-
500
- /* Confirm current working directory is within checkout. */
259
+ int showHdr = find_option("header",0,0)!=0;
260
+ int verboseFlag = find_option("verbose","v",0)!=0;
261
+ int cwdRelative = 0;
501262
db_must_be_within_tree();
263
+ /* 012345678901234 */
264
+ cwdRelative = determine_cwd_relative_option();
502265
503
- /* Get checkout version. l*/
266
+ /* We should be done with options.. */
267
+ verify_all_options();
268
+
269
+ fossil_print("repository: %s\n", db_repository_filename());
270
+ fossil_print("local-root: %s\n", g.zLocalRoot);
271
+ if( g.zConfigDbName ){
272
+ fossil_print("config-db: %s\n", g.zConfigDbName);
273
+ }
504274
vid = db_lget_int("checkout", 0);
505
-
506
- /* Relative path flag determination is done by a shared function. */
507
- if( determine_cwd_relative_option() ){
508
- flags |= C_RELPATH;
509
- }
510
-
511
- /* If --ignore is not specified, use the ignore-glob setting. */
512
- if( !zIgnoreFlag ){
513
- zIgnoreFlag = db_get("ignore-glob", 0);
514
- }
515
-
516
- /* Get the --dotfiles argument, or read it from the dotfiles setting. */
517
- if( find_option("dotfiles", 0, 0) || db_get_boolean("dotfiles", 0) ){
518
- scanFlags = SCAN_ALL;
519
- }
520
-
521
- /* We should be done with options. */
522
- verify_all_options();
523
-
524
- /* Check for changed files. */
525
- vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0);
526
-
527
- /* Search for unmanaged files if requested. */
528
- if( flags & C_EXTRA ){
529
- Glob *pIgnore = glob_create(zIgnoreFlag);
530
- locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
531
- glob_free(pIgnore);
532
- }
533
-
534
- /* The status command prints general information before the change list. */
535
- if( command==STATUS ){
536
- fossil_print("repository: %s\n", db_repository_filename());
537
- fossil_print("local-root: %s\n", g.zLocalRoot);
538
- if( g.zConfigDbName ){
539
- fossil_print("config-db: %s\n", g.zConfigDbName);
540
- }
541
- if( vid ){
542
- show_common_info(vid, "checkout:", 1, 1);
543
- }
544
- db_record_repository_filename(0);
545
- }
546
-
547
- /* Find and print all requested changes. */
548
- blob_zero(&report);
549
- status_report(&report, flags);
550
- if( blob_size(&report) ){
551
- if( showHdr ){
552
- fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
553
- g.zLocalRoot);
554
- }
555
- blob_write_to_file(&report, "-");
556
- }else if( verboseFlag ){
557
- fossil_print(" (none)\n");
558
- }
559
- blob_reset(&report);
560
-
561
- /* The status command ends with warnings about ambiguous leaves (forks). */
562
- if( command==STATUS ){
563
- leaf_ambiguity_warning(vid, vid);
564
- }
275
+ if( vid ){
276
+ show_common_info(vid, "checkout:", 1, 1);
277
+ }
278
+ db_record_repository_filename(0);
279
+ print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
280
+ leaf_ambiguity_warning(vid, vid);
565281
}
566282
567283
/*
568284
** Take care of -r version of ls command
569285
*/
@@ -791,10 +507,59 @@
791507
}
792508
free(zFullName);
793509
}
794510
db_finalize(&q);
795511
}
512
+
513
+/*
514
+** Create a TEMP table named SFILE and add all unmanaged files named on
515
+** the command-line to that table. If directories are named, then add
516
+** all unmanaged files contained underneath those directories. If there
517
+** are no files or directories named on the command-line, then add all
518
+** unmanaged files anywhere in the checkout.
519
+*/
520
+static void locate_unmanaged_files(
521
+ int argc, /* Number of command-line arguments to examine */
522
+ char **argv, /* values of command-line arguments */
523
+ unsigned scanFlags, /* Zero or more SCAN_xxx flags */
524
+ Glob *pIgnore1, /* Do not add files that match this GLOB */
525
+ Glob *pIgnore2 /* Omit files matching this GLOB too */
526
+){
527
+ Blob name; /* Name of a candidate file or directory */
528
+ char *zName; /* Name of a candidate file or directory */
529
+ int isDir; /* 1 for a directory, 0 if doesn't exist, 2 for anything else */
530
+ int i; /* Loop counter */
531
+ int nRoot; /* length of g.zLocalRoot */
532
+
533
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
534
+ filename_collation());
535
+ nRoot = (int)strlen(g.zLocalRoot);
536
+ if( argc==0 ){
537
+ blob_init(&name, g.zLocalRoot, nRoot - 1);
538
+ vfile_scan(&name, blob_size(&name), scanFlags, pIgnore1, pIgnore2);
539
+ blob_reset(&name);
540
+ }else{
541
+ for(i=0; i<argc; i++){
542
+ file_canonical_name(argv[i], &name, 0);
543
+ zName = blob_str(&name);
544
+ isDir = file_wd_isdir(zName);
545
+ if( isDir==1 ){
546
+ vfile_scan(&name, nRoot-1, scanFlags, pIgnore1, pIgnore2);
547
+ }else if( isDir==0 ){
548
+ fossil_warning("not found: %s", &zName[nRoot]);
549
+ }else if( file_access(zName, R_OK) ){
550
+ fossil_fatal("cannot open %s", &zName[nRoot]);
551
+ }else{
552
+ db_multi_exec(
553
+ "INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
554
+ &zName[nRoot]
555
+ );
556
+ }
557
+ blob_reset(&name);
558
+ }
559
+ }
560
+}
796561
797562
/*
798563
** COMMAND: extras
799564
**
800565
** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -823,23 +588,22 @@
823588
** directory.
824589
**
825590
** See also: changes, clean, status
826591
*/
827592
void extras_cmd(void){
828
- Blob report = BLOB_INITIALIZER;
593
+ Stmt q;
829594
const char *zIgnoreFlag = find_option("ignore",0,1);
830595
unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
831
- unsigned flags = C_EXTRA;
832596
int showHdr = find_option("header",0,0)!=0;
597
+ int cwdRelative = 0;
833598
Glob *pIgnore;
599
+ Blob rewrittenPathname;
600
+ const char *zPathname, *zDisplayName;
834601
835602
if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
836603
db_must_be_within_tree();
837
-
838
- if( determine_cwd_relative_option() ){
839
- flags |= C_RELPATH;
840
- }
604
+ cwdRelative = determine_cwd_relative_option();
841605
842606
if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
843607
844608
/* We should be done with options.. */
845609
verify_all_options();
@@ -846,24 +610,41 @@
846610
847611
if( zIgnoreFlag==0 ){
848612
zIgnoreFlag = db_get("ignore-glob", 0);
849613
}
850614
pIgnore = glob_create(zIgnoreFlag);
851
- locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
615
+ locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0);
852616
glob_free(pIgnore);
617
+ db_prepare(&q,
618
+ "SELECT x FROM sfile"
619
+ " WHERE x NOT IN (%s)"
620
+ " ORDER BY 1",
621
+ fossil_all_reserved_names(0)
622
+ );
623
+ db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
624
+ blob_zero(&rewrittenPathname);
853625
g.allowSymlinks = 1; /* Report on symbolic links */
854
-
855
- blob_zero(&report);
856
- status_report(&report, flags);
857
- if( blob_size(&report) ){
626
+ while( db_step(&q)==SQLITE_ROW ){
627
+ zDisplayName = zPathname = db_column_text(&q, 0);
628
+ if( cwdRelative ){
629
+ char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
630
+ file_relative_name(zFullName, &rewrittenPathname, 0);
631
+ free(zFullName);
632
+ zDisplayName = blob_str(&rewrittenPathname);
633
+ if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
634
+ zDisplayName += 2; /* no unnecessary ./ prefix */
635
+ }
636
+ }
858637
if( showHdr ){
638
+ showHdr = 0;
859639
fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
860640
g.zLocalRoot);
861641
}
862
- blob_write_to_file(&report, "-");
642
+ fossil_print("%s\n", zDisplayName);
863643
}
864
- blob_reset(&report);
644
+ blob_reset(&rewrittenPathname);
645
+ db_finalize(&q);
865646
}
866647
867648
/*
868649
** COMMAND: clean
869650
**
@@ -1009,22 +790,21 @@
1009790
g.allowSymlinks = 1; /* Find symlinks too */
1010791
if( !dirsOnlyFlag ){
1011792
Stmt q;
1012793
Blob repo;
1013794
if( !dryRunFlag && !disableUndo ) undo_begin();
1014
- locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
795
+ locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0);
1015796
db_prepare(&q,
1016
- "SELECT %Q || pathname FROM sfile"
1017
- " WHERE pathname NOT IN (%s)"
797
+ "SELECT %Q || x FROM sfile"
798
+ " WHERE x NOT IN (%s)"
1018799
" ORDER BY 1",
1019800
g.zLocalRoot, fossil_all_reserved_names(0)
1020801
);
1021802
if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
1022
- db_multi_exec("DELETE FROM sfile WHERE pathname=%B", &repo);
803
+ db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
1023804
}
1024
- db_multi_exec("DELETE FROM sfile WHERE pathname IN"
1025
- " (SELECT pathname FROM vfile)");
805
+ db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
1026806
while( db_step(&q)==SQLITE_ROW ){
1027807
const char *zName = db_column_text(&q, 0);
1028808
if( glob_match(pKeep, zName+nRoot) ){
1029809
if( verboseFlag ){
1030810
fossil_print("KEPT file \"%s\" not removed (due to --keep"
@@ -1301,11 +1081,11 @@
13011081
}
13021082
}
13031083
blob_appendf(&prompt, "\n#\n");
13041084
}
13051085
}
1306
- status_report(&prompt, C_DEFAULT | C_FATAL | C_COMMENT);
1086
+ status_report(&prompt, "# ", 1, 0);
13071087
if( g.markPrivate ){
13081088
blob_append(&prompt,
13091089
"# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
13101090
"# repositories.\n"
13111091
"#\n", -1
13121092
--- src/checkin.c
+++ src/checkin.c
@@ -21,115 +21,32 @@
21 #include "config.h"
22 #include "checkin.h"
23 #include <assert.h>
24
25 /*
26 ** Change filter options.
27 */
28 enum {
29 /* Zero-based bit indexes. */
30 CB_EDITED , CB_UPDATED , CB_CHANGED, CB_MISSING , CB_ADDED, CB_DELETED,
31 CB_RENAMED, CB_CONFLICT, CB_META , CB_UNCHANGED, CB_EXTRA, CB_MERGE ,
32 CB_RELPATH, CB_CLASSIFY, CB_MTIME , CB_SIZE , CB_FATAL, CB_COMMENT,
33
34 /* Bitmask values. */
35 C_EDITED = 1 << CB_EDITED, /* Edited, merged, and conflicted files. */
36 C_UPDATED = 1 << CB_UPDATED, /* Files updated by merge/integrate. */
37 C_CHANGED = 1 << CB_CHANGED, /* Treated the same as the above two. */
38 C_MISSING = 1 << CB_MISSING, /* Missing and non- files. */
39 C_ADDED = 1 << CB_ADDED, /* Added files. */
40 C_DELETED = 1 << CB_DELETED, /* Deleted files. */
41 C_RENAMED = 1 << CB_RENAMED, /* Renamed files. */
42 C_CONFLICT = 1 << CB_CONFLICT, /* Files having merge conflicts. */
43 C_META = 1 << CB_META, /* Files with metadata changes. */
44 C_UNCHANGED = 1 << CB_UNCHANGED, /* Unchanged files. */
45 C_EXTRA = 1 << CB_EXTRA, /* Unmanaged files. */
46 C_MERGE = 1 << CB_MERGE, /* Merge contributors. */
47 C_FILTER = C_EDITED | C_UPDATED | C_CHANGED | C_MISSING | C_ADDED
48 | C_DELETED | C_RENAMED | C_CONFLICT | C_META | C_UNCHANGED
49 | C_EXTRA | C_MERGE, /* All filter bits. */
50 C_ALL = C_FILTER & ~(C_EXTRA | C_MERGE),/* All managed files. */
51 C_DIFFER = C_FILTER & ~(C_UNCHANGED | C_MERGE),/* All differences. */
52 C_RELPATH = 1 << CB_RELPATH, /* Show relative paths. */
53 C_CLASSIFY = 1 << CB_CLASSIFY, /* Show file change types. */
54 C_DEFAULT = (C_ALL & ~C_UNCHANGED) | C_MERGE | C_CLASSIFY,
55 C_MTIME = 1 << CB_MTIME, /* Show file modification time. */
56 C_SIZE = 1 << CB_SIZE, /* Show file size in bytes. */
57 C_FATAL = (1 << CB_FATAL) | C_MISSING, /* Fail on MISSING/NOT_A_FILE. */
58 C_COMMENT = 1 << CB_COMMENT, /* Precede each line with "# ". */
59 };
60
61 /*
62 ** Create a TEMP table named SFILE and add all unmanaged files named on
63 ** the command-line to that table. If directories are named, then add
64 ** all unmanaged files contained underneath those directories. If there
65 ** are no files or directories named on the command-line, then add all
66 ** unmanaged files anywhere in the checkout.
67 */
68 static void locate_unmanaged_files(
69 int argc, /* Number of command-line arguments to examine */
70 char **argv, /* values of command-line arguments */
71 unsigned scanFlags, /* Zero or more SCAN_xxx flags */
72 Glob *pIgnore /* Do not add files that match this GLOB */
73 ){
74 Blob name; /* Name of a candidate file or directory */
75 char *zName; /* Name of a candidate file or directory */
76 int isDir; /* 1 for a directory, 0 if doesn't exist, 2 for anything else */
77 int i; /* Loop counter */
78 int nRoot; /* length of g.zLocalRoot */
79
80 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s,"
81 " mtime INTEGER, size INTEGER)", filename_collation());
82 nRoot = (int)strlen(g.zLocalRoot);
83 if( argc==0 ){
84 blob_init(&name, g.zLocalRoot, nRoot - 1);
85 vfile_scan(&name, blob_size(&name), scanFlags, pIgnore, 0);
86 blob_reset(&name);
87 }else{
88 for(i=0; i<argc; i++){
89 file_canonical_name(argv[i], &name, 0);
90 zName = blob_str(&name);
91 isDir = file_wd_isdir(zName);
92 if( isDir==1 ){
93 vfile_scan(&name, nRoot-1, scanFlags, pIgnore, 0);
94 }else if( isDir==0 ){
95 fossil_warning("not found: %s", &zName[nRoot]);
96 }else if( file_access(zName, R_OK) ){
97 fossil_fatal("cannot open %s", &zName[nRoot]);
98 }else{
99 db_multi_exec(
100 "INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)",
101 &zName[nRoot]
102 );
103 }
104 blob_reset(&name);
105 }
106 }
107 }
108
109 /*
110 ** Generate text describing all changes.
111 **
112 ** We assume that vfile_check_signature has been run.
 
 
 
113 */
114 static void status_report(
115 Blob *report, /* Append the status report here */
116 unsigned flags /* Filter and other configuration flags */
 
 
117 ){
118 Stmt q;
 
119 int nErr = 0;
120 Blob rewrittenPathname;
121 Blob sql = BLOB_INITIALIZER, where = BLOB_INITIALIZER;
122 const char *zName;
123 int i;
124
125 /* Skip the file report if no files are requested at all. */
126 if( !(flags & (C_ALL | C_EXTRA)) ){
127 goto skipFiles;
128 }
129
130 /* Assemble the path-limiting WHERE clause, if any. */
131 blob_zero(&where);
132 for(i=2; i<g.argc; i++){
133 Blob fname;
134 file_tree_name(g.argv[i], &fname, 0, 1);
135 zName = blob_str(&fname);
@@ -144,187 +61,99 @@
144 filename_collation(), zName, filename_collation(),
145 zName, filename_collation()
146 );
147 }
148
149 /* Obtain the list of managed files if appropriate. */
150 blob_zero(&sql);
151 if( flags & C_ALL ){
152 /* Start with a list of all managed files. */
153 blob_append_sql(&sql,
154 "SELECT pathname, %s as mtime, %s as size, deleted, chnged, rid,"
155 " coalesce(origname!=pathname,0) AS renamed, islink, 1 AS managed"
156 " FROM vfile, blob USING (rid)"
157 " WHERE is_selected(id)%s",
158 flags & C_MTIME ? "datetime(checkin_mtime(:vid, rid), "
159 "'unixepoch', toLocal())" : "''" /*safe-for-%s*/,
160 flags & C_SIZE ? "blob.size" : "0" /*safe-for-%s*/,
161 blob_sql_text(&where));
162
163 /* Exclude unchanged files unless requested. */
164 if( !(flags & C_UNCHANGED) ){
165 blob_append_sql(&sql,
166 " AND (chnged OR deleted OR rid=0 OR pathname!=origname)");
167 }
168 }
169
170 /* If C_EXTRA, add unmanaged files to the query result too. */
171 if( flags & C_EXTRA ){
172 if( blob_size(&sql) ){
173 blob_append_sql(&sql, " UNION ALL");
174 }
175 blob_append_sql(&sql,
176 " SELECT pathname, %s, %s, 0, 0, 0, 0, 0, 0"
177 " FROM sfile WHERE pathname NOT IN (%s)%s",
178 flags & C_MTIME ? "datetime(mtime, 'unixepoch', toLocal())" : "''",
179 flags & C_SIZE ? "size" : "0",
180 fossil_all_reserved_names(0), blob_sql_text(&where));
181 }
182 blob_reset(&where);
183
184 /* Pre-create the "ok" temporary table so the checkin_mtime() SQL function
185 * does not lead to SQLITE_ABORT_ROLLBACK during execution of the OP_OpenRead
186 * SQLite opcode. checkin_mtime() calls mtime_of_manifest_file() which
187 * creates a temporary table if it doesn't already exist, thus invalidating
188 * the prepared statement in the middle of its execution. */
189 db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)");
190
191 /* Append an ORDER BY clause then compile the query. */
192 blob_append_sql(&sql, " ORDER BY pathname");
193 db_prepare(&q, "%s", blob_sql_text(&sql));
194 blob_reset(&sql);
195
196 /* Bind the checkout version ID to the query if needed. */
197 if( (flags & C_ALL) && (flags & C_MTIME) ){
198 db_bind_int(&q, ":vid", db_lget_int("checkout", 0));
199 }
200
201 /* Execute the query and assemble the report. */
202 blob_zero(&rewrittenPathname);
203 while( db_step(&q)==SQLITE_ROW ){
204 const char *zPathname = db_column_text(&q, 0);
205 const char *zClass = 0;
206 int isManaged = db_column_int(&q, 8);
207 const char *zMtime = db_column_text(&q, 1);
208 int size = db_column_int(&q, 2);
209 int isDeleted = db_column_int(&q, 3);
210 int isChnged = db_column_int(&q, 4);
211 int isNew = isManaged && !db_column_int(&q, 5);
212 int isRenamed = db_column_int(&q, 6);
213 int isLink = db_column_int(&q, 7);
214 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
215 int isMissing = !file_wd_isfile_or_link(zFullName);
216
217 /* Determine the file change classification, if any. */
218 if( (flags & C_DELETED) && isDeleted ){
219 zClass = "DELETED";
220 }else if( (flags & C_MISSING) && isMissing ){
221 if( file_access(zFullName, F_OK)==0 ){
222 zClass = "NOT_A_FILE";
223 if( flags & C_FATAL ){
224 fossil_warning("not a file: %s", zFullName);
225 nErr++;
226 }
227 }else{
228 zClass = "MISSING";
229 if( flags & C_FATAL ){
230 fossil_warning("missing file: %s", zFullName);
231 nErr++;
232 }
233 }
234 }else if( (flags & C_ADDED) && isNew ){
235 zClass = "ADDED";
236 }else if( (flags & (C_UPDATED | C_CHANGED)) && isChnged==2 ){
237 zClass = "UPDATED_BY_MERGE";
238 }else if( (flags & C_ADDED) && isChnged==3 ){
239 zClass = "ADDED_BY_MERGE";
240 }else if( (flags & (C_UPDATED | C_CHANGED)) && isChnged==4 ){
241 zClass = "UPDATED_BY_INTEGRATE";
242 }else if( (flags & C_ADDED) && isChnged==5 ){
243 zClass = "ADDED_BY_INTEGRATE";
244 }else if( (flags & C_META) && isChnged==6 ){
245 zClass = "EXECUTABLE";
246 }else if( (flags & C_META) && isChnged==7 ){
247 zClass = "SYMLINK";
248 }else if( (flags & C_META) && isChnged==8 ){
249 zClass = "UNEXEC";
250 }else if( (flags & C_META) && isChnged==9 ){
251 zClass = "UNLINK";
252 }else if( (flags & C_CONFLICT) && isChnged && !isLink
253 && file_contains_merge_marker(zFullName) ){
254 zClass = "CONFLICT";
255 }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged
256 && (isChnged<2 || isChnged>9) ){
257 zClass = "EDITED";
258 }else if( (flags & C_RENAMED) && isRenamed ){
259 zClass = "RENAMED";
260 }else if( (flags & C_UNCHANGED) && isManaged && !isDeleted && !isMissing
261 && !isNew && !isChnged && !isRenamed ){
262 zClass = "UNCHANGED";
263 }else if( (flags & C_EXTRA) && !isManaged ){
264 zClass = "EXTRA";
265 }
266
267 /* Only report files for which a change classification was determined. */
268 if( zClass ){
269 if( flags & C_COMMENT ){
270 blob_append(report, "# ", 2);
271 }
272 if( flags & C_CLASSIFY ){
273 blob_appendf(report, "%-10s ", zClass);
274 }
275 if( flags & C_MTIME ){
276 blob_append(report, zMtime, -1);
277 blob_append(report, " ", 2);
278 }
279 if( flags & C_SIZE ){
280 blob_appendf(report, "%7d ", size);
281 }
282 if( flags & C_RELPATH ){
283 /* If C_RELPATH, display paths relative to current directory. */
284 const char *zDisplayName;
285 file_relative_name(zFullName, &rewrittenPathname, 0);
286 zDisplayName = blob_str(&rewrittenPathname);
287 if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
288 zDisplayName += 2; /* no unnecessary ./ prefix */
289 }
290 blob_append(report, zDisplayName, -1);
291 }else{
292 /* If not C_RELPATH, display paths relative to project root. */
293 blob_append(report, zPathname, -1);
294 }
295 blob_append(report, "\n", 1);
296 }
297 free(zFullName);
298 }
299 blob_reset(&rewrittenPathname);
300 db_finalize(&q);
301
302 /* If C_MERGE, put merge contributors at the end of the report. */
303 skipFiles:
304 if( flags & C_MERGE ){
305 db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
306 " WHERE id<=0");
307 while( db_step(&q)==SQLITE_ROW ){
308 if( flags & C_COMMENT ){
309 blob_append(report, "# ", 2);
310 }
311 if( flags & C_CLASSIFY ){
312 const char *zClass;
313 switch( db_column_int(&q, 1) ){
314 case -1: zClass = "CHERRYPICK" ; break;
315 case -2: zClass = "BACKOUT" ; break;
316 case -4: zClass = "INTEGRATE" ; break;
317 default: zClass = "MERGED_WITH"; break;
318 }
319 blob_appendf(report, "%-10s ", zClass);
320 }
321 blob_append(report, db_column_text(&q, 0), -1);
322 blob_append(report, "\n", 1);
323 }
324 db_finalize(&q);
325 }
326 if( nErr ){
327 fossil_fatal("aborting due to prior errors");
328 }
329 }
330
@@ -341,229 +170,116 @@
341 int relPathOption = find_option("rel-paths", 0, 0)!=0;
342 if( absPathOption ){ relativePaths = 0; }
343 if( relPathOption ){ relativePaths = 1; }
344 return relativePaths;
345 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
347 /*
348 ** COMMAND: changes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349 ** COMMAND: status
350 **
351 ** Usage: %fossil changes|status ?OPTIONS? ?PATHS ...?
352 **
353 ** Report the change status of files in the current checkout. If one or
354 ** more PATHS are specified, only changes among the named files and
355 ** directories are reported. Directories are searched recursively.
356 **
357 ** The status command is similar to the changes command, except it lacks
358 ** several of the options supported by changes and it has its own header
359 ** and footer information. The header information is a subset of that
360 ** shown by the info command, and the footer shows if there are any forks.
361 ** Change type classification is always enabled for the status command.
362 **
363 ** Each line of output is the name of a changed file, with paths shown
364 ** according to the "relative-paths" setting, unless overridden by the
365 ** --abs-paths or --rel-paths options.
366 **
367 ** By default, all changed files are selected for display. This behavior
368 ** can be overridden by using one or more filter options (listed below),
369 ** in which case only files with the specified change type(s) are shown.
370 ** As a special case, the --no-merge option does not inhibit this default.
371 ** This default shows exactly the set of changes that would be checked
372 ** in by the commit command.
373 **
374 ** If no filter options are used, or if the --merge option is used, the
375 ** SHA1 hash of each merge contributor check-in version is displayed at
376 ** the end of the report. The --no-merge option is useful to display the
377 ** default set of changed files without the merge contributors.
378 **
379 ** If change type classification is enabled, each output line starts with
380 ** a code describing the file's change type, e.g. EDITED or RENAMED. It
381 ** is enabled by default unless exactly one change type is selected. For
382 ** the purposes of determining the default, --changed counts as selecting
383 ** one change type. The default can be overridden by the --classify or
384 ** --no-classify options.
385 **
386 ** If both --merge and --no-merge are used, --no-merge has priority. The
387 ** same is true of --classify and --no-classify.
388 **
389 ** The "fossil changes --extra" command is equivalent to "fossil extras".
390 **
391 ** --edited and --updated produce disjoint sets. --updated shows a file
392 ** only when it is identical to that of its merge contributor, and the
393 ** change type classification is UPDATED_BY_MERGE or UPDATED_BY_INTEGRATE.
394 ** If the file had to be merged with any other changes, it is considered
395 ** to be merged or conflicted and therefore will be shown by --edited, not
396 ** --updated, with types EDITED or CONFLICT. The --changed option can be
397 ** used to display the union of --edited and --updated.
398 **
399 ** --differ is so named because it lists all the differences between the
400 ** checked-out version and the checkout directory. In addition to the
401 ** default changes (besides --merge), it lists extra files which (assuming
402 ** ignore-glob is set correctly) may be worth adding. Prior to doing a
403 ** commit, it is good practice to check --differ to see not only which
404 ** changes would be committed but also if any files need to be added.
405 **
406 ** General options:
407 ** --abs-paths Display absolute pathnames.
408 ** --rel-paths Display pathnames relative to the current working
409 ** directory.
410 ** --sha1sum Verify file status using SHA1 hashing rather than
411 ** relying on file mtimes.
412 ** --case-sensitive <BOOL> Override case-sensitive setting.
413 ** --dotfiles Include unmanaged files beginning with a dot.
414 ** --ignore <CSG> Ignore unmanaged files matching CSG glob patterns.
415 **
416 ** Options specific to the changes command:
417 ** --header Identify the repository if report is non-empty.
418 ** -v|--verbose Say "(none)" if the change report is empty.
419 ** --classify Start each line with the file's change type.
420 ** --no-classify Do not print file change types.
421 **
422 ** Filter options:
423 ** --edited Display edited, merged, and conflicted files.
424 ** --updated Display files updated by merge/integrate.
425 ** --changed Combination of the above two options.
426 ** --missing Display missing files.
427 ** --added Display added files.
428 ** --deleted Display deleted files.
429 ** --renamed Display renamed files.
430 ** --conflict Display files having merge conflicts.
431 ** --meta Display files with metadata changes.
432 ** --unchanged Display unchanged files.
433 ** --all Display all managed files, i.e. all of the above.
434 ** --extra Display unmanaged files.
435 ** --differ Display modified and extra files.
436 ** --merge Display merge contributors.
437 ** --no-merge Do not display merge contributors.
438 **
439 ** See also: extras, ls
440 */
441 void status_cmd(void){
442 /* Affirmative and negative flag option tables. */
443 static const struct {
444 const char *option; /* Flag name. */
445 unsigned mask; /* Flag bits. */
446 } flagDefs[] = {
447 {"edited" , C_EDITED }, {"updated" , C_UPDATED },
448 {"changed" , C_CHANGED }, {"missing" , C_MISSING },
449 {"added" , C_ADDED }, {"deleted" , C_DELETED },
450 {"renamed" , C_RENAMED }, {"conflict" , C_CONFLICT },
451 {"meta" , C_META }, {"unchanged" , C_UNCHANGED},
452 {"all" , C_ALL }, {"extra" , C_EXTRA },
453 {"differ" , C_DIFFER }, {"merge" , C_MERGE },
454 {"classify", C_CLASSIFY},
455 }, noFlagDefs[] = {
456 {"no-merge", C_MERGE }, {"no-classify", C_CLASSIFY },
457 };
458
459 Blob report = BLOB_INITIALIZER;
460 enum {CHANGES, STATUS} command = *g.argv[1]=='s' ? STATUS : CHANGES;
461 int useSha1sum = find_option("sha1sum", 0, 0)!=0;
462 int showHdr = command==CHANGES && find_option("header", 0, 0);
463 int verboseFlag = command==CHANGES && find_option("verbose", "v", 0);
464 const char *zIgnoreFlag = find_option("ignore", 0, 1);
465 unsigned scanFlags = 0;
466 unsigned flags = 0;
467 int vid, i;
468
469 /* Load affirmative flag options. */
470 for( i=0; i<count(flagDefs); ++i ){
471 if( (command==CHANGES || !(flagDefs[i].mask & C_CLASSIFY))
472 && find_option(flagDefs[i].option, 0, 0) ){
473 flags |= flagDefs[i].mask;
474 }
475 }
476
477 /* If no filter options are specified, enable defaults. */
478 if( !(flags & C_FILTER) ){
479 flags |= C_DEFAULT;
480 }
481
482 /* If more than one filter is enabled, enable classification. This is tricky.
483 * Having one filter means flags masked by C_FILTER is a power of two. If a
484 * number masked by one less than itself is zero, it's either zero or a power
485 * of two. It's already known to not be zero because of the above defaults.
486 * Unlike --all, --changed is a single filter, i.e. it sets only one bit.
487 * Also force classification for the status command. */
488 if( command==STATUS || (flags & (flags-1) & C_FILTER) ){
489 flags |= C_CLASSIFY;
490 }
491
492 /* Negative flag options override defaults applied above. */
493 for( i=0; i<count(noFlagDefs); ++i ){
494 if( (command==CHANGES || !(noFlagDefs[i].mask & C_CLASSIFY))
495 && find_option(noFlagDefs[i].option, 0, 0) ){
496 flags &= ~noFlagDefs[i].mask;
497 }
498 }
499
500 /* Confirm current working directory is within checkout. */
501 db_must_be_within_tree();
 
 
502
503 /* Get checkout version. l*/
 
 
 
 
 
 
 
504 vid = db_lget_int("checkout", 0);
505
506 /* Relative path flag determination is done by a shared function. */
507 if( determine_cwd_relative_option() ){
508 flags |= C_RELPATH;
509 }
510
511 /* If --ignore is not specified, use the ignore-glob setting. */
512 if( !zIgnoreFlag ){
513 zIgnoreFlag = db_get("ignore-glob", 0);
514 }
515
516 /* Get the --dotfiles argument, or read it from the dotfiles setting. */
517 if( find_option("dotfiles", 0, 0) || db_get_boolean("dotfiles", 0) ){
518 scanFlags = SCAN_ALL;
519 }
520
521 /* We should be done with options. */
522 verify_all_options();
523
524 /* Check for changed files. */
525 vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0);
526
527 /* Search for unmanaged files if requested. */
528 if( flags & C_EXTRA ){
529 Glob *pIgnore = glob_create(zIgnoreFlag);
530 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
531 glob_free(pIgnore);
532 }
533
534 /* The status command prints general information before the change list. */
535 if( command==STATUS ){
536 fossil_print("repository: %s\n", db_repository_filename());
537 fossil_print("local-root: %s\n", g.zLocalRoot);
538 if( g.zConfigDbName ){
539 fossil_print("config-db: %s\n", g.zConfigDbName);
540 }
541 if( vid ){
542 show_common_info(vid, "checkout:", 1, 1);
543 }
544 db_record_repository_filename(0);
545 }
546
547 /* Find and print all requested changes. */
548 blob_zero(&report);
549 status_report(&report, flags);
550 if( blob_size(&report) ){
551 if( showHdr ){
552 fossil_print("Changes for %s at %s:\n", db_get("project-name", "???"),
553 g.zLocalRoot);
554 }
555 blob_write_to_file(&report, "-");
556 }else if( verboseFlag ){
557 fossil_print(" (none)\n");
558 }
559 blob_reset(&report);
560
561 /* The status command ends with warnings about ambiguous leaves (forks). */
562 if( command==STATUS ){
563 leaf_ambiguity_warning(vid, vid);
564 }
565 }
566
567 /*
568 ** Take care of -r version of ls command
569 */
@@ -791,10 +507,59 @@
791 }
792 free(zFullName);
793 }
794 db_finalize(&q);
795 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
797 /*
798 ** COMMAND: extras
799 **
800 ** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -823,23 +588,22 @@
823 ** directory.
824 **
825 ** See also: changes, clean, status
826 */
827 void extras_cmd(void){
828 Blob report = BLOB_INITIALIZER;
829 const char *zIgnoreFlag = find_option("ignore",0,1);
830 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
831 unsigned flags = C_EXTRA;
832 int showHdr = find_option("header",0,0)!=0;
 
833 Glob *pIgnore;
 
 
834
835 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
836 db_must_be_within_tree();
837
838 if( determine_cwd_relative_option() ){
839 flags |= C_RELPATH;
840 }
841
842 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
843
844 /* We should be done with options.. */
845 verify_all_options();
@@ -846,24 +610,41 @@
846
847 if( zIgnoreFlag==0 ){
848 zIgnoreFlag = db_get("ignore-glob", 0);
849 }
850 pIgnore = glob_create(zIgnoreFlag);
851 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
852 glob_free(pIgnore);
 
 
 
 
 
 
 
 
853 g.allowSymlinks = 1; /* Report on symbolic links */
854
855 blob_zero(&report);
856 status_report(&report, flags);
857 if( blob_size(&report) ){
 
 
 
 
 
 
 
858 if( showHdr ){
 
859 fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
860 g.zLocalRoot);
861 }
862 blob_write_to_file(&report, "-");
863 }
864 blob_reset(&report);
 
865 }
866
867 /*
868 ** COMMAND: clean
869 **
@@ -1009,22 +790,21 @@
1009 g.allowSymlinks = 1; /* Find symlinks too */
1010 if( !dirsOnlyFlag ){
1011 Stmt q;
1012 Blob repo;
1013 if( !dryRunFlag && !disableUndo ) undo_begin();
1014 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
1015 db_prepare(&q,
1016 "SELECT %Q || pathname FROM sfile"
1017 " WHERE pathname NOT IN (%s)"
1018 " ORDER BY 1",
1019 g.zLocalRoot, fossil_all_reserved_names(0)
1020 );
1021 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
1022 db_multi_exec("DELETE FROM sfile WHERE pathname=%B", &repo);
1023 }
1024 db_multi_exec("DELETE FROM sfile WHERE pathname IN"
1025 " (SELECT pathname FROM vfile)");
1026 while( db_step(&q)==SQLITE_ROW ){
1027 const char *zName = db_column_text(&q, 0);
1028 if( glob_match(pKeep, zName+nRoot) ){
1029 if( verboseFlag ){
1030 fossil_print("KEPT file \"%s\" not removed (due to --keep"
@@ -1301,11 +1081,11 @@
1301 }
1302 }
1303 blob_appendf(&prompt, "\n#\n");
1304 }
1305 }
1306 status_report(&prompt, C_DEFAULT | C_FATAL | C_COMMENT);
1307 if( g.markPrivate ){
1308 blob_append(&prompt,
1309 "# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
1310 "# repositories.\n"
1311 "#\n", -1
1312
--- src/checkin.c
+++ src/checkin.c
@@ -21,115 +21,32 @@
21 #include "config.h"
22 #include "checkin.h"
23 #include <assert.h>
24
25 /*
26 ** Generate text describing all changes. Prepend zPrefix to each line
27 ** of output.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28 **
29 ** We assume that vfile_check_signature has been run.
30 **
31 ** If missingIsFatal is true, then any files that are missing or which
32 ** are not true files results in a fatal error.
33 */
34 static void status_report(
35 Blob *report, /* Append the status report here */
36 const char *zPrefix, /* Prefix on each line of the report */
37 int missingIsFatal, /* MISSING and NOT_A_FILE are fatal errors */
38 int cwdRelative /* Report relative to the current working dir */
39 ){
40 Stmt q;
41 int nPrefix = strlen(zPrefix);
42 int nErr = 0;
43 Blob rewrittenPathname;
44 Blob where;
45 const char *zName;
46 int i;
47
 
 
 
 
 
 
48 blob_zero(&where);
49 for(i=2; i<g.argc; i++){
50 Blob fname;
51 file_tree_name(g.argv[i], &fname, 0, 1);
52 zName = blob_str(&fname);
@@ -144,187 +61,99 @@
61 filename_collation(), zName, filename_collation(),
62 zName, filename_collation()
63 );
64 }
65
66 db_prepare(&q,
67 "SELECT pathname, deleted, chnged,"
68 " rid, coalesce(origname!=pathname,0), islink"
69 " FROM vfile "
70 " WHERE is_selected(id) %s"
71 " AND (chnged OR deleted OR rid=0 OR pathname!=origname)"
72 " ORDER BY 1 /*scan*/",
73 blob_sql_text(&where)
74 );
75 blob_zero(&rewrittenPathname);
76 while( db_step(&q)==SQLITE_ROW ){
77 const char *zPathname = db_column_text(&q,0);
78 const char *zDisplayName = zPathname;
79 int isDeleted = db_column_int(&q, 1);
80 int isChnged = db_column_int(&q,2);
81 int isNew = db_column_int(&q,3)==0;
82 int isRenamed = db_column_int(&q,4);
83 int isLink = db_column_int(&q,5);
84 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
85 if( cwdRelative ){
86 file_relative_name(zFullName, &rewrittenPathname, 0);
87 zDisplayName = blob_str(&rewrittenPathname);
88 if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
89 zDisplayName += 2; /* no unnecessary ./ prefix */
90 }
91 }
92 blob_append(report, zPrefix, nPrefix);
93 if( isDeleted ){
94 blob_appendf(report, "DELETED %s\n", zDisplayName);
95 }else if( !file_wd_isfile_or_link(zFullName) ){
96 if( file_access(zFullName, F_OK)==0 ){
97 blob_appendf(report, "NOT_A_FILE %s\n", zDisplayName);
98 if( missingIsFatal ){
99 fossil_warning("not a file: %s", zDisplayName);
100 nErr++;
101 }
102 }else{
103 blob_appendf(report, "MISSING %s\n", zDisplayName);
104 if( missingIsFatal ){
105 fossil_warning("missing file: %s", zDisplayName);
106 nErr++;
107 }
108 }
109 }else if( isNew ){
110 blob_appendf(report, "ADDED %s\n", zDisplayName);
111 }else if( isChnged ){
112 if( isChnged==2 ){
113 blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
114 }else if( isChnged==3 ){
115 blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
116 }else if( isChnged==4 ){
117 blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
118 }else if( isChnged==5 ){
119 blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
120 }else if( isChnged==6 ){
121 blob_appendf(report, "EXECUTABLE %s\n", zDisplayName);
122 }else if( isChnged==7 ){
123 blob_appendf(report, "SYMLINK %s\n", zDisplayName);
124 }else if( isChnged==8 ){
125 blob_appendf(report, "UNEXEC %s\n", zDisplayName);
126 }else if( isChnged==9 ){
127 blob_appendf(report, "UNLINK %s\n", zDisplayName);
128 }else if( !isLink && file_contains_merge_marker(zFullName) ){
129 blob_appendf(report, "CONFLICT %s\n", zDisplayName);
130 }else{
131 blob_appendf(report, "EDITED %s\n", zDisplayName);
132 }
133 }else if( isRenamed ){
134 blob_appendf(report, "RENAMED %s\n", zDisplayName);
135 }else{
136 report->nUsed -= nPrefix;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137 }
138 free(zFullName);
139 }
140 blob_reset(&rewrittenPathname);
141 db_finalize(&q);
142 db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
143 " WHERE id<=0");
144 while( db_step(&q)==SQLITE_ROW ){
145 const char *zLabel = "MERGED_WITH ";
146 switch( db_column_int(&q, 1) ){
147 case -1: zLabel = "CHERRYPICK "; break;
148 case -2: zLabel = "BACKOUT "; break;
149 case -4: zLabel = "INTEGRATE "; break;
150 }
151 blob_append(report, zPrefix, nPrefix);
152 blob_appendf(report, "%s%s\n", zLabel, db_column_text(&q, 0));
153 }
154 db_finalize(&q);
 
 
 
 
 
 
 
 
 
 
 
 
155 if( nErr ){
156 fossil_fatal("aborting due to prior errors");
157 }
158 }
159
@@ -341,229 +170,116 @@
170 int relPathOption = find_option("rel-paths", 0, 0)!=0;
171 if( absPathOption ){ relativePaths = 0; }
172 if( relPathOption ){ relativePaths = 1; }
173 return relativePaths;
174 }
175
176 void print_changes(
177 int useSha1sum, /* Verify file status using SHA1 hashing rather
178 than relying on file mtimes. */
179 int showHdr, /* Identify the repository if there are changes */
180 int verboseFlag, /* Say "(none)" if there are no changes */
181 int cwdRelative /* Report relative to the current working dir */
182 ){
183 Blob report;
184 int vid;
185 blob_zero(&report);
186
187 vid = db_lget_int("checkout", 0);
188 vfile_check_signature(vid, useSha1sum ? CKSIG_SHA1 : 0);
189 status_report(&report, "", 0, cwdRelative);
190 if( verboseFlag && blob_size(&report)==0 ){
191 blob_append(&report, " (none)\n", -1);
192 }
193 if( showHdr && blob_size(&report)>0 ){
194 fossil_print("Changes for %s at %s:\n", db_get("project-name","???"),
195 g.zLocalRoot);
196 }
197 blob_write_to_file(&report, "-");
198 blob_reset(&report);
199 }
200
201 /*
202 ** COMMAND: changes
203 **
204 ** Usage: %fossil changes ?OPTIONS?
205 **
206 ** Report on the edit status of all files in the current checkout.
207 **
208 ** Pathnames are displayed according to the "relative-paths" setting,
209 ** unless overridden by the --abs-paths or --rel-paths options.
210 **
211 ** Options:
212 ** --abs-paths Display absolute pathnames.
213 ** --rel-paths Display pathnames relative to the current working
214 ** directory.
215 ** --sha1sum Verify file status using SHA1 hashing rather
216 ** than relying on file mtimes.
217 ** --header Identify the repository if there are changes
218 ** -v|--verbose Say "(none)" if there are no changes
219 **
220 ** See also: extras, ls, status
221 */
222 void changes_cmd(void){
223 int useSha1sum = find_option("sha1sum", 0, 0)!=0;
224 int showHdr = find_option("header",0,0)!=0;
225 int verboseFlag = find_option("verbose","v",0)!=0;
226 int cwdRelative = 0;
227 db_must_be_within_tree();
228 cwdRelative = determine_cwd_relative_option();
229
230 /* We should be done with options.. */
231 verify_all_options();
232
233 print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
234 }
235
236 /*
237 ** COMMAND: status
238 **
239 ** Usage: %fossil status ?OPTIONS?
240 **
241 ** Report on the status of the current checkout.
242 **
243 ** Pathnames are displayed according to the "relative-paths" setting,
244 ** unless overridden by the --abs-paths or --rel-paths options.
245 **
246 ** Options:
247 **
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248 ** --abs-paths Display absolute pathnames.
249 ** --rel-paths Display pathnames relative to the current working
250 ** directory.
251 ** --sha1sum Verify file status using SHA1 hashing rather
252 ** than relying on file mtimes.
253 **
254 ** See also: changes, extras, ls
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255 */
256 void status_cmd(void){
257 int vid;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258 int useSha1sum = find_option("sha1sum", 0, 0)!=0;
259 int showHdr = find_option("header",0,0)!=0;
260 int verboseFlag = find_option("verbose","v",0)!=0;
261 int cwdRelative = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262 db_must_be_within_tree();
263 /* 012345678901234 */
264 cwdRelative = determine_cwd_relative_option();
265
266 /* We should be done with options.. */
267 verify_all_options();
268
269 fossil_print("repository: %s\n", db_repository_filename());
270 fossil_print("local-root: %s\n", g.zLocalRoot);
271 if( g.zConfigDbName ){
272 fossil_print("config-db: %s\n", g.zConfigDbName);
273 }
274 vid = db_lget_int("checkout", 0);
275 if( vid ){
276 show_common_info(vid, "checkout:", 1, 1);
277 }
278 db_record_repository_filename(0);
279 print_changes(useSha1sum, showHdr, verboseFlag, cwdRelative);
280 leaf_ambiguity_warning(vid, vid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281 }
282
283 /*
284 ** Take care of -r version of ls command
285 */
@@ -791,10 +507,59 @@
507 }
508 free(zFullName);
509 }
510 db_finalize(&q);
511 }
512
513 /*
514 ** Create a TEMP table named SFILE and add all unmanaged files named on
515 ** the command-line to that table. If directories are named, then add
516 ** all unmanaged files contained underneath those directories. If there
517 ** are no files or directories named on the command-line, then add all
518 ** unmanaged files anywhere in the checkout.
519 */
520 static void locate_unmanaged_files(
521 int argc, /* Number of command-line arguments to examine */
522 char **argv, /* values of command-line arguments */
523 unsigned scanFlags, /* Zero or more SCAN_xxx flags */
524 Glob *pIgnore1, /* Do not add files that match this GLOB */
525 Glob *pIgnore2 /* Omit files matching this GLOB too */
526 ){
527 Blob name; /* Name of a candidate file or directory */
528 char *zName; /* Name of a candidate file or directory */
529 int isDir; /* 1 for a directory, 0 if doesn't exist, 2 for anything else */
530 int i; /* Loop counter */
531 int nRoot; /* length of g.zLocalRoot */
532
533 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
534 filename_collation());
535 nRoot = (int)strlen(g.zLocalRoot);
536 if( argc==0 ){
537 blob_init(&name, g.zLocalRoot, nRoot - 1);
538 vfile_scan(&name, blob_size(&name), scanFlags, pIgnore1, pIgnore2);
539 blob_reset(&name);
540 }else{
541 for(i=0; i<argc; i++){
542 file_canonical_name(argv[i], &name, 0);
543 zName = blob_str(&name);
544 isDir = file_wd_isdir(zName);
545 if( isDir==1 ){
546 vfile_scan(&name, nRoot-1, scanFlags, pIgnore1, pIgnore2);
547 }else if( isDir==0 ){
548 fossil_warning("not found: %s", &zName[nRoot]);
549 }else if( file_access(zName, R_OK) ){
550 fossil_fatal("cannot open %s", &zName[nRoot]);
551 }else{
552 db_multi_exec(
553 "INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
554 &zName[nRoot]
555 );
556 }
557 blob_reset(&name);
558 }
559 }
560 }
561
562 /*
563 ** COMMAND: extras
564 **
565 ** Usage: %fossil extras ?OPTIONS? ?PATH1 ...?
@@ -823,23 +588,22 @@
588 ** directory.
589 **
590 ** See also: changes, clean, status
591 */
592 void extras_cmd(void){
593 Stmt q;
594 const char *zIgnoreFlag = find_option("ignore",0,1);
595 unsigned scanFlags = find_option("dotfiles",0,0)!=0 ? SCAN_ALL : 0;
 
596 int showHdr = find_option("header",0,0)!=0;
597 int cwdRelative = 0;
598 Glob *pIgnore;
599 Blob rewrittenPathname;
600 const char *zPathname, *zDisplayName;
601
602 if( find_option("temp",0,0)!=0 ) scanFlags |= SCAN_TEMP;
603 db_must_be_within_tree();
604 cwdRelative = determine_cwd_relative_option();
 
 
 
605
606 if( db_get_boolean("dotfiles", 0) ) scanFlags |= SCAN_ALL;
607
608 /* We should be done with options.. */
609 verify_all_options();
@@ -846,24 +610,41 @@
610
611 if( zIgnoreFlag==0 ){
612 zIgnoreFlag = db_get("ignore-glob", 0);
613 }
614 pIgnore = glob_create(zIgnoreFlag);
615 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0);
616 glob_free(pIgnore);
617 db_prepare(&q,
618 "SELECT x FROM sfile"
619 " WHERE x NOT IN (%s)"
620 " ORDER BY 1",
621 fossil_all_reserved_names(0)
622 );
623 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
624 blob_zero(&rewrittenPathname);
625 g.allowSymlinks = 1; /* Report on symbolic links */
626 while( db_step(&q)==SQLITE_ROW ){
627 zDisplayName = zPathname = db_column_text(&q, 0);
628 if( cwdRelative ){
629 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
630 file_relative_name(zFullName, &rewrittenPathname, 0);
631 free(zFullName);
632 zDisplayName = blob_str(&rewrittenPathname);
633 if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
634 zDisplayName += 2; /* no unnecessary ./ prefix */
635 }
636 }
637 if( showHdr ){
638 showHdr = 0;
639 fossil_print("Extras for %s at %s:\n", db_get("project-name","???"),
640 g.zLocalRoot);
641 }
642 fossil_print("%s\n", zDisplayName);
643 }
644 blob_reset(&rewrittenPathname);
645 db_finalize(&q);
646 }
647
648 /*
649 ** COMMAND: clean
650 **
@@ -1009,22 +790,21 @@
790 g.allowSymlinks = 1; /* Find symlinks too */
791 if( !dirsOnlyFlag ){
792 Stmt q;
793 Blob repo;
794 if( !dryRunFlag && !disableUndo ) undo_begin();
795 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore, 0);
796 db_prepare(&q,
797 "SELECT %Q || x FROM sfile"
798 " WHERE x NOT IN (%s)"
799 " ORDER BY 1",
800 g.zLocalRoot, fossil_all_reserved_names(0)
801 );
802 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
803 db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
804 }
805 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
 
806 while( db_step(&q)==SQLITE_ROW ){
807 const char *zName = db_column_text(&q, 0);
808 if( glob_match(pKeep, zName+nRoot) ){
809 if( verboseFlag ){
810 fossil_print("KEPT file \"%s\" not removed (due to --keep"
@@ -1301,11 +1081,11 @@
1081 }
1082 }
1083 blob_appendf(&prompt, "\n#\n");
1084 }
1085 }
1086 status_report(&prompt, "# ", 1, 0);
1087 if( g.markPrivate ){
1088 blob_append(&prompt,
1089 "# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
1090 "# repositories.\n"
1091 "#\n", -1
1092
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216216
static int prevVid = -1;
217217
static Stmt q;
218218
219219
if( prevVid!=vid ){
220220
prevVid = vid;
221
- db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
222
- "DELETE FROM ok;");
221
+ db_multi_exec("DROP TABLE IF EXISTS temp.ok;"
222
+ "CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);");
223223
compute_ancestors(vid, 100000000, 1);
224224
}
225225
db_static_prepare(&q,
226226
"SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227227
" WHERE mlink.mid=event.objid"
228228
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216 static int prevVid = -1;
217 static Stmt q;
218
219 if( prevVid!=vid ){
220 prevVid = vid;
221 db_multi_exec("CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
222 "DELETE FROM ok;");
223 compute_ancestors(vid, 100000000, 1);
224 }
225 db_static_prepare(&q,
226 "SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227 " WHERE mlink.mid=event.objid"
228
--- src/descendants.c
+++ src/descendants.c
@@ -216,12 +216,12 @@
216 static int prevVid = -1;
217 static Stmt q;
218
219 if( prevVid!=vid ){
220 prevVid = vid;
221 db_multi_exec("DROP TABLE IF EXISTS temp.ok;"
222 "CREATE TEMP TABLE ok(x INTEGER PRIMARY KEY);");
223 compute_ancestors(vid, 100000000, 1);
224 }
225 db_static_prepare(&q,
226 "SELECT (max(event.mtime)-2440587.5)*86400 FROM mlink, event"
227 " WHERE mlink.mid=event.objid"
228
+4 -4
--- src/main.c
+++ src/main.c
@@ -1192,14 +1192,14 @@
11921192
int n = 0;
11931193
11941194
assert( g.db==0 );
11951195
blob_init(&base, g.zRepositoryName, -1);
11961196
sqlite3_open(":memory:", &g.db);
1197
- db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
1197
+ db_multi_exec("CREATE TABLE sfile(x TEXT);");
11981198
db_multi_exec("CREATE TABLE vfile(pathname);");
11991199
vfile_scan(&base, blob_size(&base), 0, 0, 0);
1200
- db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
1200
+ db_multi_exec("DELETE FROM sfile WHERE x NOT GLOB '*[^/].fossil'");
12011201
n = db_int(0, "SELECT count(*) FROM sfile");
12021202
if( n>0 ){
12031203
Stmt q;
12041204
@ <html>
12051205
@ <head>
@@ -1207,12 +1207,12 @@
12071207
@ <title>Repository List</title>
12081208
@ </head>
12091209
@ <body>
12101210
@ <h1>Available Repositories:</h1>
12111211
@ <ol>
1212
- db_prepare(&q, "SELECT pathname, substr(pathname,-7,-100000)||'/home'"
1213
- " FROM sfile ORDER BY pathname COLLATE nocase;");
1212
+ db_prepare(&q, "SELECT x, substr(x,-7,-100000)||'/home'"
1213
+ " FROM sfile ORDER BY x COLLATE nocase;");
12141214
while( db_step(&q)==SQLITE_ROW ){
12151215
const char *zName = db_column_text(&q, 0);
12161216
const char *zUrl = db_column_text(&q, 1);
12171217
@ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li>
12181218
}
12191219
--- src/main.c
+++ src/main.c
@@ -1192,14 +1192,14 @@
1192 int n = 0;
1193
1194 assert( g.db==0 );
1195 blob_init(&base, g.zRepositoryName, -1);
1196 sqlite3_open(":memory:", &g.db);
1197 db_multi_exec("CREATE TABLE sfile(pathname TEXT);");
1198 db_multi_exec("CREATE TABLE vfile(pathname);");
1199 vfile_scan(&base, blob_size(&base), 0, 0, 0);
1200 db_multi_exec("DELETE FROM sfile WHERE pathname NOT GLOB '*[^/].fossil'");
1201 n = db_int(0, "SELECT count(*) FROM sfile");
1202 if( n>0 ){
1203 Stmt q;
1204 @ <html>
1205 @ <head>
@@ -1207,12 +1207,12 @@
1207 @ <title>Repository List</title>
1208 @ </head>
1209 @ <body>
1210 @ <h1>Available Repositories:</h1>
1211 @ <ol>
1212 db_prepare(&q, "SELECT pathname, substr(pathname,-7,-100000)||'/home'"
1213 " FROM sfile ORDER BY pathname COLLATE nocase;");
1214 while( db_step(&q)==SQLITE_ROW ){
1215 const char *zName = db_column_text(&q, 0);
1216 const char *zUrl = db_column_text(&q, 1);
1217 @ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li>
1218 }
1219
--- src/main.c
+++ src/main.c
@@ -1192,14 +1192,14 @@
1192 int n = 0;
1193
1194 assert( g.db==0 );
1195 blob_init(&base, g.zRepositoryName, -1);
1196 sqlite3_open(":memory:", &g.db);
1197 db_multi_exec("CREATE TABLE sfile(x TEXT);");
1198 db_multi_exec("CREATE TABLE vfile(pathname);");
1199 vfile_scan(&base, blob_size(&base), 0, 0, 0);
1200 db_multi_exec("DELETE FROM sfile WHERE x NOT GLOB '*[^/].fossil'");
1201 n = db_int(0, "SELECT count(*) FROM sfile");
1202 if( n>0 ){
1203 Stmt q;
1204 @ <html>
1205 @ <head>
@@ -1207,12 +1207,12 @@
1207 @ <title>Repository List</title>
1208 @ </head>
1209 @ <body>
1210 @ <h1>Available Repositories:</h1>
1211 @ <ol>
1212 db_prepare(&q, "SELECT x, substr(x,-7,-100000)||'/home'"
1213 " FROM sfile ORDER BY x COLLATE nocase;");
1214 while( db_step(&q)==SQLITE_ROW ){
1215 const char *zName = db_column_text(&q, 0);
1216 const char *zUrl = db_column_text(&q, 1);
1217 @ <li><a href="%R/%h(zUrl)" target="_blank">%h(zName)</a></li>
1218 }
1219
+2 -2
--- src/stash.c
+++ src/stash.c
@@ -207,11 +207,11 @@
207207
"SELECT rid, isRemoved, isExec, isLink, origname, newname, delta"
208208
" FROM stashfile WHERE stashid=%d",
209209
stashid
210210
);
211211
vid = db_lget_int("checkout",0);
212
- db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
212
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
213213
filename_collation());
214214
while( db_step(&q)==SQLITE_ROW ){
215215
int rid = db_column_int(&q, 0);
216216
int isRemoved = db_column_int(&q, 1);
217217
int isExec = db_column_int(&q, 2);
@@ -222,11 +222,11 @@
222222
char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
223223
Blob delta;
224224
undo_save(zNew);
225225
blob_zero(&delta);
226226
if( rid==0 ){
227
- db_multi_exec("INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)", zNew);
227
+ db_multi_exec("INSERT OR IGNORE INTO sfile(x) VALUES(%Q)", zNew);
228228
db_ephemeral_blob(&q, 6, &delta);
229229
blob_write_to_file(&delta, zNPath);
230230
file_wd_setexe(zNPath, isExec);
231231
}else if( isRemoved ){
232232
fossil_print("DELETE %s\n", zOrig);
233233
--- src/stash.c
+++ src/stash.c
@@ -207,11 +207,11 @@
207 "SELECT rid, isRemoved, isExec, isLink, origname, newname, delta"
208 " FROM stashfile WHERE stashid=%d",
209 stashid
210 );
211 vid = db_lget_int("checkout",0);
212 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
213 filename_collation());
214 while( db_step(&q)==SQLITE_ROW ){
215 int rid = db_column_int(&q, 0);
216 int isRemoved = db_column_int(&q, 1);
217 int isExec = db_column_int(&q, 2);
@@ -222,11 +222,11 @@
222 char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
223 Blob delta;
224 undo_save(zNew);
225 blob_zero(&delta);
226 if( rid==0 ){
227 db_multi_exec("INSERT OR IGNORE INTO sfile(pathname) VALUES(%Q)", zNew);
228 db_ephemeral_blob(&q, 6, &delta);
229 blob_write_to_file(&delta, zNPath);
230 file_wd_setexe(zNPath, isExec);
231 }else if( isRemoved ){
232 fossil_print("DELETE %s\n", zOrig);
233
--- src/stash.c
+++ src/stash.c
@@ -207,11 +207,11 @@
207 "SELECT rid, isRemoved, isExec, isLink, origname, newname, delta"
208 " FROM stashfile WHERE stashid=%d",
209 stashid
210 );
211 vid = db_lget_int("checkout",0);
212 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
213 filename_collation());
214 while( db_step(&q)==SQLITE_ROW ){
215 int rid = db_column_int(&q, 0);
216 int isRemoved = db_column_int(&q, 1);
217 int isExec = db_column_int(&q, 2);
@@ -222,11 +222,11 @@
222 char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew);
223 Blob delta;
224 undo_save(zNew);
225 blob_zero(&delta);
226 if( rid==0 ){
227 db_multi_exec("INSERT OR IGNORE INTO sfile(x) VALUES(%Q)", zNew);
228 db_ephemeral_blob(&q, 6, &delta);
229 blob_write_to_file(&delta, zNPath);
230 file_wd_setexe(zNPath, isExec);
231 }else if( isRemoved ){
232 fossil_print("DELETE %s\n", zOrig);
233
+3 -16
--- src/vfile.c
+++ src/vfile.c
@@ -455,12 +455,10 @@
455455
** Values for the scanFlags parameter to vfile_scan().
456456
*/
457457
#define SCAN_ALL 0x001 /* Includes files that begin with "." */
458458
#define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */
459459
#define SCAN_NESTED 0x004 /* Scan for empty dirs in nested checkouts */
460
-#define SCAN_MTIME 0x008 /* Populate mtime column */
461
-#define SCAN_SIZE 0x010 /* Populate size column */
462460
#endif /* INTERFACE */
463461
464462
/*
465463
** Load into table SFILE the name of every ordinary file in
466464
** the directory pPath. Omit the first nPrefix characters of
@@ -500,18 +498,13 @@
500498
}
501499
if( skipAll ) return;
502500
503501
if( depth==0 ){
504502
db_prepare(&ins,
505
- "INSERT OR IGNORE INTO sfile(pathname%s%s) SELECT :file%s%s"
506
- " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE"
507
- " pathname=:file %s)",
508
- scanFlags & SCAN_MTIME ? ", mtime" : "",
509
- scanFlags & SCAN_SIZE ? ", size" : "",
510
- scanFlags & SCAN_MTIME ? ", :mtime" : "",
511
- scanFlags & SCAN_SIZE ? ", :size" : "",
512
- filename_collation()
503
+ "INSERT OR IGNORE INTO sfile(x) SELECT :file"
504
+ " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE"
505
+ " pathname=:file %s)", filename_collation()
513506
);
514507
}
515508
depth++;
516509
517510
zNative = fossil_utf8_to_path(blob_str(pPath), 1);
@@ -546,16 +539,10 @@
546539
#else
547540
}else if( file_wd_isfile_or_link(zPath) ){
548541
#endif
549542
if( (scanFlags & SCAN_TEMP)==0 || is_temporary_file(zUtf8) ){
550543
db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
551
- if( scanFlags & SCAN_MTIME ){
552
- db_bind_int(&ins, ":mtime", file_mtime(zPath));
553
- }
554
- if( scanFlags & SCAN_SIZE ){
555
- db_bind_int(&ins, ":size", file_size(zPath));
556
- }
557544
db_step(&ins);
558545
db_reset(&ins);
559546
}
560547
}
561548
fossil_path_free(zUtf8);
562549
--- src/vfile.c
+++ src/vfile.c
@@ -455,12 +455,10 @@
455 ** Values for the scanFlags parameter to vfile_scan().
456 */
457 #define SCAN_ALL 0x001 /* Includes files that begin with "." */
458 #define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */
459 #define SCAN_NESTED 0x004 /* Scan for empty dirs in nested checkouts */
460 #define SCAN_MTIME 0x008 /* Populate mtime column */
461 #define SCAN_SIZE 0x010 /* Populate size column */
462 #endif /* INTERFACE */
463
464 /*
465 ** Load into table SFILE the name of every ordinary file in
466 ** the directory pPath. Omit the first nPrefix characters of
@@ -500,18 +498,13 @@
500 }
501 if( skipAll ) return;
502
503 if( depth==0 ){
504 db_prepare(&ins,
505 "INSERT OR IGNORE INTO sfile(pathname%s%s) SELECT :file%s%s"
506 " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE"
507 " pathname=:file %s)",
508 scanFlags & SCAN_MTIME ? ", mtime" : "",
509 scanFlags & SCAN_SIZE ? ", size" : "",
510 scanFlags & SCAN_MTIME ? ", :mtime" : "",
511 scanFlags & SCAN_SIZE ? ", :size" : "",
512 filename_collation()
513 );
514 }
515 depth++;
516
517 zNative = fossil_utf8_to_path(blob_str(pPath), 1);
@@ -546,16 +539,10 @@
546 #else
547 }else if( file_wd_isfile_or_link(zPath) ){
548 #endif
549 if( (scanFlags & SCAN_TEMP)==0 || is_temporary_file(zUtf8) ){
550 db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
551 if( scanFlags & SCAN_MTIME ){
552 db_bind_int(&ins, ":mtime", file_mtime(zPath));
553 }
554 if( scanFlags & SCAN_SIZE ){
555 db_bind_int(&ins, ":size", file_size(zPath));
556 }
557 db_step(&ins);
558 db_reset(&ins);
559 }
560 }
561 fossil_path_free(zUtf8);
562
--- src/vfile.c
+++ src/vfile.c
@@ -455,12 +455,10 @@
455 ** Values for the scanFlags parameter to vfile_scan().
456 */
457 #define SCAN_ALL 0x001 /* Includes files that begin with "." */
458 #define SCAN_TEMP 0x002 /* Only Fossil-generated files like *-baseline */
459 #define SCAN_NESTED 0x004 /* Scan for empty dirs in nested checkouts */
 
 
460 #endif /* INTERFACE */
461
462 /*
463 ** Load into table SFILE the name of every ordinary file in
464 ** the directory pPath. Omit the first nPrefix characters of
@@ -500,18 +498,13 @@
498 }
499 if( skipAll ) return;
500
501 if( depth==0 ){
502 db_prepare(&ins,
503 "INSERT OR IGNORE INTO sfile(x) SELECT :file"
504 " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE"
505 " pathname=:file %s)", filename_collation()
 
 
 
 
 
506 );
507 }
508 depth++;
509
510 zNative = fossil_utf8_to_path(blob_str(pPath), 1);
@@ -546,16 +539,10 @@
539 #else
540 }else if( file_wd_isfile_or_link(zPath) ){
541 #endif
542 if( (scanFlags & SCAN_TEMP)==0 || is_temporary_file(zUtf8) ){
543 db_bind_text(&ins, ":file", &zPath[nPrefix+1]);
 
 
 
 
 
 
544 db_step(&ins);
545 db_reset(&ins);
546 }
547 }
548 fossil_path_free(zUtf8);
549

Keyboard Shortcuts

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