Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Detect when the check-out contains missing files and filesystem objects that ought to be files but are not. Issue reasonable warnings. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
76f169fca6c040496b14bd37a9e2c5e0 |
| User & Date: | drh 2009-12-18 00:29:51.000 |
References
|
2009-12-18
| ||
| 00:31 | • Fixed ticket [9ad1a5401c]: MISSING files are not handled gracefully plus 2 other changes artifact: 676ec85c9b user: drh | |
Context
|
2009-12-18
| ||
| 20:15 | Add an "annotate" command to the command-line to suppliment the "annotate" web page. check-in: 73b7faa58b user: drh tags: trunk | |
| 00:29 | Detect when the check-out contains missing files and filesystem objects that ought to be files but are not. Issue reasonable warnings. check-in: 76f169fca6 user: drh tags: trunk | |
|
2009-12-17
| ||
| 22:55 | Enhancements to the "update" command. Missing files are reverted. One or more files can be specified on the "update" command line after the VERSION and only the files named will be updated. check-in: 2d996b080e user: drh tags: trunk | |
Changes
Changes to src/checkin.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 36 | #include <assert.h> /* ** Generate text describing all changes. Prepend zPrefix to each line ** of output. ** ** We assume that vfile_check_signature has been run. */ | > > > | > > > > > | > | > > > > > > | > > > > > | | | | > > > | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
#include <assert.h>
/*
** Generate text describing all changes. Prepend zPrefix to each line
** of output.
**
** We assume that vfile_check_signature has been run.
**
** If missingIsFatal is true, then any files that are missing or which
** are not true files results in a fatal error.
*/
static void status_report(
Blob *report, /* Append the status report here */
const char *zPrefix, /* Prefix on each line of the report */
int missingIsFatal /* MISSING and NOT_A_FILE are fatal errors */
){
Stmt q;
int nPrefix = strlen(zPrefix);
int nErr = 0;
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
" FROM vfile "
" WHERE file_is_selected(id)"
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q,0);
int isDeleted = db_column_int(&q, 1);
int isChnged = db_column_int(&q,2);
int isNew = db_column_int(&q,3)==0;
int isRenamed = db_column_int(&q,4);
char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
blob_append(report, zPrefix, nPrefix);
if( isDeleted ){
blob_appendf(report, "DELETED %s\n", zPathname);
}else if( !file_isfile(zFullName) ){
if( access(zFullName, 0)==0 ){
blob_appendf(report, "NOT_A_FILE %s\n", zPathname);
if( missingIsFatal ){
fossil_warning("not a file: %s", zPathname);
nErr++;
}
}else{
blob_appendf(report, "MISSING %s\n", zPathname);
if( missingIsFatal ){
fossil_warning("missing file: %s", zPathname);
nErr++;
}
}
}else if( isNew ){
blob_appendf(report, "ADDED %s\n", zPathname);
}else if( isDeleted ){
blob_appendf(report, "DELETED %s\n", zPathname);
}else if( isChnged==2 ){
blob_appendf(report, "UPDATED_BY_MERGE %s\n", zPathname);
}else if( isChnged==3 ){
blob_appendf(report, "ADDED_BY_MERGE %s\n", zPathname);
}else if( isChnged==1 ){
blob_appendf(report, "EDITED %s\n", zPathname);
}else if( isRenamed ){
blob_appendf(report, "RENAMED %s\n", zPathname);
}
free(zFullName);
}
db_finalize(&q);
db_prepare(&q, "SELECT uuid FROM vmerge JOIN blob ON merge=rid"
" WHERE id=0");
while( db_step(&q)==SQLITE_ROW ){
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "MERGED_WITH %s\n", db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
}
}
/*
** COMMAND: changes
**
** Usage: %fossil changes
**
** Report on the edit status of all files in the current checkout.
** See also the "status" and "extra" commands.
*/
void changes_cmd(void){
Blob report;
int vid;
db_must_be_within_tree();
blob_zero(&report);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0);
status_report(&report, "", 0);
blob_write_to_file(&report, "-");
}
/*
** COMMAND: status
**
** Usage: %fossil status
|
| ︙ | ︙ | |||
132 133 134 135 136 137 138 |
int vid;
Stmt q;
int isBrief;
isBrief = find_option("l","l", 0)==0;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
| | | > | | > > > | | | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
int vid;
Stmt q;
int isBrief;
isBrief = find_option("l","l", 0)==0;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0);
db_prepare(&q,
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
" FROM vfile"
" ORDER BY 1"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zPathname = db_column_text(&q,0);
int isDeleted = db_column_int(&q, 1);
int isNew = db_column_int(&q,2)==0;
int chnged = db_column_int(&q,3);
int renamed = db_column_int(&q,4);
char *zFullName = mprintf("%s/%s", g.zLocalRoot, zPathname);
if( isBrief ){
printf("%s\n", zPathname);
}else if( isNew ){
printf("ADDED %s\n", zPathname);
}else if( !file_isfile(zFullName) ){
if( access(zFullName, 0)==0 ){
printf("NOT_A_FILE %s\n", zPathname);
}else{
printf("MISSING %s\n", zPathname);
}
}else if( isDeleted ){
printf("DELETED %s\n", zPathname);
}else if( chnged ){
printf("EDITED %s\n", zPathname);
}else if( renamed ){
printf("RENAMED %s\n", zPathname);
}else{
printf("UNCHANGED %s\n", zPathname);
}
free(zFullName);
}
db_finalize(&q);
}
/*
|
| ︙ | ︙ | |||
301 302 303 304 305 306 307 |
if( g.markPrivate ){
blob_append(&text,
"# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
"# repositories.\n"
"#\n", -1
);
}
| | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
if( g.markPrivate ){
blob_append(&text,
"# PRIVATE BRANCH: This check-in will be private and will not sync to\n"
"# repositories.\n"
"#\n", -1
);
}
status_report(&text, "# ", 1);
zEditor = db_get("editor", 0);
if( zEditor==0 ){
zEditor = getenv("VISUAL");
}
if( zEditor==0 ){
zEditor = getenv("EDITOR");
}
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
37 38 39 40 41 42 43 |
** 2: There is no existing checkout
*/
int unsaved_changes(void){
int vid;
db_must_be_within_tree();
vid = db_lget_int("checkout",0);
if( vid==0 ) return 2;
| | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
** 2: There is no existing checkout
*/
int unsaved_changes(void){
int vid;
db_must_be_within_tree();
vid = db_lget_int("checkout",0);
if( vid==0 ) return 2;
vfile_check_signature(vid, 1);
return db_exists("SELECT 1 FROM vfile WHERE chnged"
" OR coalesce(origname!=pathname,0)");
}
/*
** Undo the current check-out. Unlink all files from the disk.
** Clear the VFILE table.
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
205 206 207 208 209 210 211 |
*/
static void diff_all_against_disk(const char *zFrom, const char *zDiffCmd){
int vid;
Blob sql;
Stmt q;
vid = db_lget_int("checkout", 0);
| | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
*/
static void diff_all_against_disk(const char *zFrom, const char *zDiffCmd){
int vid;
Blob sql;
Stmt q;
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 1);
blob_zero(&sql);
db_begin_transaction();
if( zFrom ){
int rid = name_to_rid(zFrom);
if( !is_a_version(rid) ){
fossil_fatal("no such check-in: %s", zFrom);
}
|
| ︙ | ︙ |
Changes to src/merge.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 |
if( pid<=0 ){
fossil_panic("cannot find a common ancestor between the current"
"checkout and %s", g.argv[2]);
}
if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){
fossil_panic("not a version: record #%d", mid);
}
| | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
if( pid<=0 ){
fossil_panic("cannot find a common ancestor between the current"
"checkout and %s", g.argv[2]);
}
if( pid>1 && !db_exists("SELECT 1 FROM plink WHERE cid=%d", pid) ){
fossil_panic("not a version: record #%d", mid);
}
vfile_check_signature(vid, 1);
db_begin_transaction();
undo_begin();
load_vfile_from_rid(mid);
load_vfile_from_rid(pid);
/*
** The vfile.pathname field is used to match files against each other. The
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
116 117 118 119 120 121 122 |
}
tid = db_int(0, "SELECT rid FROM leaves, event"
" WHERE event.objid=leaves.rid"
" ORDER BY event.mtime DESC");
}
db_begin_transaction();
| | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
}
tid = db_int(0, "SELECT rid FROM leaves, event"
" WHERE event.objid=leaves.rid"
" ORDER BY event.mtime DESC");
}
db_begin_transaction();
vfile_check_signature(vid, 1);
undo_begin();
load_vfile_from_rid(tid);
/*
** The record.fn field is used to match files against each other. The
** FV table contains one row for each each unique filename in
** in the current checkout, the pivot, and the version being merged.
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
140 141 142 143 144 145 146 | ** Set the VFILE.CHNGED field on every file that has changed. Also ** set VFILE.CHNGED on every folder that contains a file or folder ** that has changed. ** ** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume ** the file has changed without having the check the on-disk image. */ | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
** Set the VFILE.CHNGED field on every file that has changed. Also
** set VFILE.CHNGED on every folder that contains a file or folder
** that has changed.
**
** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume
** the file has changed without having the check the on-disk image.
*/
void vfile_check_signature(int vid, int notFileIsFatal){
int nErr = 0;
Stmt q;
Blob fileCksum, origCksum;
int checkMtime = db_get_boolean("mtime-changes", 0);
db_begin_transaction();
db_prepare(&q, "SELECT id, %Q || pathname,"
|
| ︙ | ︙ | |||
166 167 168 169 170 171 172 |
id = db_column_int(&q, 0);
zName = db_column_text(&q, 1);
rid = db_column_int(&q, 2);
isDeleted = db_column_int(&q, 3);
oldChnged = db_column_int(&q, 4);
oldMtime = db_column_int64(&q, 6);
if( !file_isfile(zName) && file_size(zName)>=0 ){
| > | | < | > | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
id = db_column_int(&q, 0);
zName = db_column_text(&q, 1);
rid = db_column_int(&q, 2);
isDeleted = db_column_int(&q, 3);
oldChnged = db_column_int(&q, 4);
oldMtime = db_column_int64(&q, 6);
if( !file_isfile(zName) && file_size(zName)>=0 ){
if( notFileIsFatal ){
fossil_warning("not a ordinary file: %s", zName);
nErr++;
}
chnged = 1;
}else if( oldChnged>=2 ){
chnged = oldChnged;
}else if( isDeleted || rid==0 ){
chnged = 1;
}
if( chnged!=1 ){
currentMtime = file_mtime(zName);
}
|
| ︙ | ︙ |