Fossil SCM

Improvements to "fossil status" processing. Automatically detect when a file has undergone a null-edit - when the mtime has changed but the content of the file is unchanged - and mark such files as unchanged.

drh 2011-12-28 13:40 trunk
Commit b9227b85cbd78f333e183f370acead94a47a6669
1 file changed +60 -38
+60 -38
--- src/vfile.c
+++ src/vfile.c
@@ -124,30 +124,40 @@
124124
manifest_destroy(p);
125125
db_end_transaction(0);
126126
}
127127
128128
/*
129
-** Check the file signature of the disk image for every VFILE of vid.
130
-**
131
-** Set the VFILE.CHNGED field on every file that has changed. Also
132
-** set VFILE.CHNGED on every folder that contains a file or folder
133
-** that has changed.
134
-**
135
-** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume
136
-** the file has changed without having the check the on-disk image.
137
-**
138
-** If the size of the file has changed, then we assume that it has
139
-** changed. If the mtime of the file has not changed and useSha1sum is false
140
-** and the mtime-changes setting is true (the default) then we assume that
141
-** the file has not changed. If the mtime has changed, we go ahead and
142
-** double-check that the file has changed by looking at its SHA1 sum.
129
+** Look at every VFILE entry with the given vid and set update
130
+** VFILE.CHNGED field on every file according to whether or not
131
+** the file has changes. 0 means no change. 1 means edited. 2 means
132
+** the file has changed due to a merge. 3 means the file was added
133
+** by a merge.
134
+**
135
+** If VFILE.DELETED is true or if VFILE.RID is zero, then the file was
136
+** either removed from managemented via "fossil rm" or added via
137
+** "fossil add", respectively, and in both cases we always know that
138
+** the file has changed without having the check the size, mtime,
139
+** or on-disk content.
140
+**
141
+** If the size of the file has changed, then we always know that the file
142
+** changed without having to look at the mtime or on-disk content.
143
+**
144
+** The mtime of the file is only a factor if the mtime-changes setting
145
+** is false and the useSha1sum flag is false. If the mtime-changes
146
+** setting is true (or undefined - it defaults to true) or if useSha1sum
147
+** is true, then we do not trust the mtime and will examine the on-disk
148
+** content to determine if a file really is the same.
149
+**
150
+** If the mtime is used, it is used only to determine if files are the same.
151
+** If the mtime of a file has changed, we still examine the on-disk content
152
+** to see whether or not the edit was a null-edit.
143153
*/
144154
void vfile_check_signature(int vid, int notFileIsFatal, int useSha1sum){
145155
int nErr = 0;
146156
Stmt q;
147157
Blob fileCksum, origCksum;
148
- int checkMtime = useSha1sum==0 && db_get_boolean("mtime-changes", 1);
158
+ int useMtime = useSha1sum==0 && db_get_boolean("mtime-changes", 1);
149159
150160
db_begin_transaction();
151161
db_prepare(&q, "SELECT id, %Q || pathname,"
152162
" vfile.mrid, deleted, chnged, uuid, size, mtime"
153163
" FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
@@ -157,55 +167,67 @@
157167
const char *zName;
158168
int chnged = 0;
159169
int oldChnged;
160170
i64 oldMtime;
161171
i64 currentMtime;
172
+ i64 origSize;
173
+ i64 currentSize;
162174
163175
id = db_column_int(&q, 0);
164176
zName = db_column_text(&q, 1);
165177
rid = db_column_int(&q, 2);
166178
isDeleted = db_column_int(&q, 3);
167
- oldChnged = db_column_int(&q, 4);
179
+ oldChnged = chnged = db_column_int(&q, 4);
168180
oldMtime = db_column_int64(&q, 7);
169
- if( isDeleted ){
181
+ currentSize = file_wd_size(zName);
182
+ origSize = db_column_int64(&q, 6);
183
+ currentMtime = file_wd_mtime(0);
184
+ if( chnged==0 && (isDeleted || rid==0) ){
185
+ /* "fossil rm" or "fossil add" always change the file */
170186
chnged = 1;
171
- }else if( !file_wd_isfile_or_link(zName) && file_wd_size(0)>=0 ){
187
+ }else if( !file_wd_isfile_or_link(0) && currentSize>=0 ){
172188
if( notFileIsFatal ){
173189
fossil_warning("not an ordinary file: %s", zName);
174190
nErr++;
175191
}
176192
chnged = 1;
177
- }else if( oldChnged>=2 ){
178
- chnged = oldChnged;
179
- }else if( rid==0 ){
180
- chnged = 1;
181
- }
182
- if( chnged!=1 ){
183
- i64 origSize = db_column_int64(&q, 6);
184
- currentMtime = file_wd_mtime(0);
185
- if( origSize!=file_wd_size(0) ){
186
- /* A file size change is definitive - the file has changed. No
187
- ** need to check the sha1sum */
188
- chnged = 1;
189
- }
190
- }
191
- if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
193
+ }
194
+ if( origSize!=currentSize ){
195
+ if( chnged==0 ){
196
+ /* A file size change is definitive - the file has changed. No
197
+ ** need to check the mtime or sha1sum */
198
+ chnged = 1;
199
+ }
200
+ }else if( (chnged==1 || chnged==2) && rid!=0 && !isDeleted ){
201
+ /* File is believed to have changed but it is the same size.
202
+ ** Double check that it really has changed by looking at content. */
203
+ assert( origSize==currentSize );
204
+ db_ephemeral_blob(&q, 5, &origCksum);
205
+ if( sha1sum_file(zName, &fileCksum) ){
206
+ blob_zero(&fileCksum);
207
+ }
208
+ if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
209
+ blob_reset(&origCksum);
210
+ blob_reset(&fileCksum);
211
+ }else if( chnged==0 && (useMtime==0 || currentMtime!=oldMtime) ){
212
+ /* For files that were formerly believed to be unchanged, if their
213
+ ** mtime changes, or unconditionally if --sha1sum is used, check
214
+ ** to see if they have been edited by looking at their SHA1 sum */
215
+ assert( origSize==currentSize );
192216
db_ephemeral_blob(&q, 5, &origCksum);
193217
if( sha1sum_file(zName, &fileCksum) ){
194218
blob_zero(&fileCksum);
195219
}
196220
if( blob_compare(&fileCksum, &origCksum) ){
197221
chnged = 1;
198
- }else if( currentMtime!=oldMtime ){
199
- db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
200
- currentMtime, id);
201222
}
202223
blob_reset(&origCksum);
203224
blob_reset(&fileCksum);
204225
}
205
- if( chnged!=oldChnged && (chnged || !checkMtime) ){
206
- db_multi_exec("UPDATE vfile SET chnged=%d WHERE id=%d", chnged, id);
226
+ if( currentMtime!=oldMtime || chnged!=oldChnged ){
227
+ db_multi_exec("UPDATE vfile SET mtime=%lld, chnged=%d WHERE id=%d",
228
+ currentMtime, chnged, id);
207229
}
208230
}
209231
db_finalize(&q);
210232
if( nErr ) fossil_fatal("abort due to prior errors");
211233
db_end_transaction(0);
212234
--- src/vfile.c
+++ src/vfile.c
@@ -124,30 +124,40 @@
124 manifest_destroy(p);
125 db_end_transaction(0);
126 }
127
128 /*
129 ** Check the file signature of the disk image for every VFILE of vid.
130 **
131 ** Set the VFILE.CHNGED field on every file that has changed. Also
132 ** set VFILE.CHNGED on every folder that contains a file or folder
133 ** that has changed.
134 **
135 ** If VFILE.DELETED is null or if VFILE.RID is zero, then we can assume
136 ** the file has changed without having the check the on-disk image.
137 **
138 ** If the size of the file has changed, then we assume that it has
139 ** changed. If the mtime of the file has not changed and useSha1sum is false
140 ** and the mtime-changes setting is true (the default) then we assume that
141 ** the file has not changed. If the mtime has changed, we go ahead and
142 ** double-check that the file has changed by looking at its SHA1 sum.
 
 
 
 
 
 
 
 
 
 
143 */
144 void vfile_check_signature(int vid, int notFileIsFatal, int useSha1sum){
145 int nErr = 0;
146 Stmt q;
147 Blob fileCksum, origCksum;
148 int checkMtime = useSha1sum==0 && db_get_boolean("mtime-changes", 1);
149
150 db_begin_transaction();
151 db_prepare(&q, "SELECT id, %Q || pathname,"
152 " vfile.mrid, deleted, chnged, uuid, size, mtime"
153 " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
@@ -157,55 +167,67 @@
157 const char *zName;
158 int chnged = 0;
159 int oldChnged;
160 i64 oldMtime;
161 i64 currentMtime;
 
 
162
163 id = db_column_int(&q, 0);
164 zName = db_column_text(&q, 1);
165 rid = db_column_int(&q, 2);
166 isDeleted = db_column_int(&q, 3);
167 oldChnged = db_column_int(&q, 4);
168 oldMtime = db_column_int64(&q, 7);
169 if( isDeleted ){
 
 
 
 
170 chnged = 1;
171 }else if( !file_wd_isfile_or_link(zName) && file_wd_size(0)>=0 ){
172 if( notFileIsFatal ){
173 fossil_warning("not an ordinary file: %s", zName);
174 nErr++;
175 }
176 chnged = 1;
177 }else if( oldChnged>=2 ){
178 chnged = oldChnged;
179 }else if( rid==0 ){
180 chnged = 1;
181 }
182 if( chnged!=1 ){
183 i64 origSize = db_column_int64(&q, 6);
184 currentMtime = file_wd_mtime(0);
185 if( origSize!=file_wd_size(0) ){
186 /* A file size change is definitive - the file has changed. No
187 ** need to check the sha1sum */
188 chnged = 1;
189 }
190 }
191 if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
 
 
 
 
 
 
 
 
192 db_ephemeral_blob(&q, 5, &origCksum);
193 if( sha1sum_file(zName, &fileCksum) ){
194 blob_zero(&fileCksum);
195 }
196 if( blob_compare(&fileCksum, &origCksum) ){
197 chnged = 1;
198 }else if( currentMtime!=oldMtime ){
199 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d",
200 currentMtime, id);
201 }
202 blob_reset(&origCksum);
203 blob_reset(&fileCksum);
204 }
205 if( chnged!=oldChnged && (chnged || !checkMtime) ){
206 db_multi_exec("UPDATE vfile SET chnged=%d WHERE id=%d", chnged, id);
 
207 }
208 }
209 db_finalize(&q);
210 if( nErr ) fossil_fatal("abort due to prior errors");
211 db_end_transaction(0);
212
--- src/vfile.c
+++ src/vfile.c
@@ -124,30 +124,40 @@
124 manifest_destroy(p);
125 db_end_transaction(0);
126 }
127
128 /*
129 ** Look at every VFILE entry with the given vid and set update
130 ** VFILE.CHNGED field on every file according to whether or not
131 ** the file has changes. 0 means no change. 1 means edited. 2 means
132 ** the file has changed due to a merge. 3 means the file was added
133 ** by a merge.
134 **
135 ** If VFILE.DELETED is true or if VFILE.RID is zero, then the file was
136 ** either removed from managemented via "fossil rm" or added via
137 ** "fossil add", respectively, and in both cases we always know that
138 ** the file has changed without having the check the size, mtime,
139 ** or on-disk content.
140 **
141 ** If the size of the file has changed, then we always know that the file
142 ** changed without having to look at the mtime or on-disk content.
143 **
144 ** The mtime of the file is only a factor if the mtime-changes setting
145 ** is false and the useSha1sum flag is false. If the mtime-changes
146 ** setting is true (or undefined - it defaults to true) or if useSha1sum
147 ** is true, then we do not trust the mtime and will examine the on-disk
148 ** content to determine if a file really is the same.
149 **
150 ** If the mtime is used, it is used only to determine if files are the same.
151 ** If the mtime of a file has changed, we still examine the on-disk content
152 ** to see whether or not the edit was a null-edit.
153 */
154 void vfile_check_signature(int vid, int notFileIsFatal, int useSha1sum){
155 int nErr = 0;
156 Stmt q;
157 Blob fileCksum, origCksum;
158 int useMtime = useSha1sum==0 && db_get_boolean("mtime-changes", 1);
159
160 db_begin_transaction();
161 db_prepare(&q, "SELECT id, %Q || pathname,"
162 " vfile.mrid, deleted, chnged, uuid, size, mtime"
163 " FROM vfile LEFT JOIN blob ON vfile.mrid=blob.rid"
@@ -157,55 +167,67 @@
167 const char *zName;
168 int chnged = 0;
169 int oldChnged;
170 i64 oldMtime;
171 i64 currentMtime;
172 i64 origSize;
173 i64 currentSize;
174
175 id = db_column_int(&q, 0);
176 zName = db_column_text(&q, 1);
177 rid = db_column_int(&q, 2);
178 isDeleted = db_column_int(&q, 3);
179 oldChnged = chnged = db_column_int(&q, 4);
180 oldMtime = db_column_int64(&q, 7);
181 currentSize = file_wd_size(zName);
182 origSize = db_column_int64(&q, 6);
183 currentMtime = file_wd_mtime(0);
184 if( chnged==0 && (isDeleted || rid==0) ){
185 /* "fossil rm" or "fossil add" always change the file */
186 chnged = 1;
187 }else if( !file_wd_isfile_or_link(0) && currentSize>=0 ){
188 if( notFileIsFatal ){
189 fossil_warning("not an ordinary file: %s", zName);
190 nErr++;
191 }
192 chnged = 1;
193 }
194 if( origSize!=currentSize ){
195 if( chnged==0 ){
196 /* A file size change is definitive - the file has changed. No
197 ** need to check the mtime or sha1sum */
198 chnged = 1;
199 }
200 }else if( (chnged==1 || chnged==2) && rid!=0 && !isDeleted ){
201 /* File is believed to have changed but it is the same size.
202 ** Double check that it really has changed by looking at content. */
203 assert( origSize==currentSize );
204 db_ephemeral_blob(&q, 5, &origCksum);
205 if( sha1sum_file(zName, &fileCksum) ){
206 blob_zero(&fileCksum);
207 }
208 if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
209 blob_reset(&origCksum);
210 blob_reset(&fileCksum);
211 }else if( chnged==0 && (useMtime==0 || currentMtime!=oldMtime) ){
212 /* For files that were formerly believed to be unchanged, if their
213 ** mtime changes, or unconditionally if --sha1sum is used, check
214 ** to see if they have been edited by looking at their SHA1 sum */
215 assert( origSize==currentSize );
216 db_ephemeral_blob(&q, 5, &origCksum);
217 if( sha1sum_file(zName, &fileCksum) ){
218 blob_zero(&fileCksum);
219 }
220 if( blob_compare(&fileCksum, &origCksum) ){
221 chnged = 1;
 
 
 
222 }
223 blob_reset(&origCksum);
224 blob_reset(&fileCksum);
225 }
226 if( currentMtime!=oldMtime || chnged!=oldChnged ){
227 db_multi_exec("UPDATE vfile SET mtime=%lld, chnged=%d WHERE id=%d",
228 currentMtime, chnged, id);
229 }
230 }
231 db_finalize(&q);
232 if( nErr ) fossil_fatal("abort due to prior errors");
233 db_end_transaction(0);
234

Keyboard Shortcuts

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