Fossil SCM
Don't rely on vfile.islink to tell whether or not a file is currently a symlink for the purpose of avoiding calling file_contains_merge_marker(). It is possible for a file to have become a symlink since the last commit. If the link target's string length is not equal to the former file size, vfile_check_signature() will treat it as a normal change and not mark it as chnged==8 (SYMLINK), so execution can fall through to the undesirable call to file_contains_merge_marker().
Commit
43140feb1d059e97ac71d65ec2ea06bb9eb382cd
Parent
0dea016de15dc56…
1 file changed
+3
-4
+3
-4
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -150,11 +150,11 @@ | ||
| 150 | 150 | blob_zero(&sql); |
| 151 | 151 | if( flags & C_ALL ){ |
| 152 | 152 | /* Start with a list of all managed files. */ |
| 153 | 153 | blob_append_sql(&sql, |
| 154 | 154 | "SELECT pathname, %s as mtime, %s as size, deleted, chnged, rid," |
| 155 | - " coalesce(origname!=pathname,0) AS renamed, islink, 1 AS managed" | |
| 155 | + " coalesce(origname!=pathname,0) AS renamed, 1 AS managed" | |
| 156 | 156 | " FROM vfile LEFT JOIN blob USING (rid)" |
| 157 | 157 | " WHERE is_selected(id)%s", |
| 158 | 158 | flags & C_MTIME ? "datetime(checkin_mtime(:vid, rid), " |
| 159 | 159 | "'unixepoch', toLocal())" : "''" /*safe-for-%s*/, |
| 160 | 160 | flags & C_SIZE ? "coalesce(blob.size, 0)" : "0" /*safe-for-%s*/, |
| @@ -201,18 +201,17 @@ | ||
| 201 | 201 | /* Execute the query and assemble the report. */ |
| 202 | 202 | blob_zero(&rewrittenPathname); |
| 203 | 203 | while( db_step(&q)==SQLITE_ROW ){ |
| 204 | 204 | const char *zPathname = db_column_text(&q, 0); |
| 205 | 205 | const char *zClass = 0; |
| 206 | - int isManaged = db_column_int(&q, 8); | |
| 206 | + int isManaged = db_column_int(&q, 7); | |
| 207 | 207 | const char *zMtime = db_column_text(&q, 1); |
| 208 | 208 | int size = db_column_int(&q, 2); |
| 209 | 209 | int isDeleted = db_column_int(&q, 3); |
| 210 | 210 | int isChnged = db_column_int(&q, 4); |
| 211 | 211 | int isNew = isManaged && !db_column_int(&q, 5); |
| 212 | 212 | int isRenamed = db_column_int(&q, 6); |
| 213 | - int isLink = db_column_int(&q, 7); | |
| 214 | 213 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 215 | 214 | int isMissing = !file_wd_isfile_or_link(zFullName); |
| 216 | 215 | |
| 217 | 216 | /* Determine the file change classification, if any. */ |
| 218 | 217 | if( isDeleted ){ |
| @@ -255,11 +254,11 @@ | ||
| 255 | 254 | zClass = "SYMLINK"; |
| 256 | 255 | }else if( (flags & C_META) && isChnged==8 ){ |
| 257 | 256 | zClass = "UNEXEC"; |
| 258 | 257 | }else if( (flags & C_META) && isChnged==9 ){ |
| 259 | 258 | zClass = "UNLINK"; |
| 260 | - }else if( (flags & C_CONFLICT) && isChnged && !isLink | |
| 259 | + }else if( (flags & C_CONFLICT) && isChnged && !file_wd_islink(zFullName) | |
| 261 | 260 | && file_contains_merge_marker(zFullName) ){ |
| 262 | 261 | zClass = "CONFLICT"; |
| 263 | 262 | }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged |
| 264 | 263 | && (isChnged<2 || isChnged>9) ){ |
| 265 | 264 | zClass = "EDITED"; |
| 266 | 265 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -150,11 +150,11 @@ | |
| 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 LEFT JOIN 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 ? "coalesce(blob.size, 0)" : "0" /*safe-for-%s*/, |
| @@ -201,18 +201,17 @@ | |
| 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( isDeleted ){ |
| @@ -255,11 +254,11 @@ | |
| 255 | zClass = "SYMLINK"; |
| 256 | }else if( (flags & C_META) && isChnged==8 ){ |
| 257 | zClass = "UNEXEC"; |
| 258 | }else if( (flags & C_META) && isChnged==9 ){ |
| 259 | zClass = "UNLINK"; |
| 260 | }else if( (flags & C_CONFLICT) && isChnged && !isLink |
| 261 | && file_contains_merge_marker(zFullName) ){ |
| 262 | zClass = "CONFLICT"; |
| 263 | }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged |
| 264 | && (isChnged<2 || isChnged>9) ){ |
| 265 | zClass = "EDITED"; |
| 266 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -150,11 +150,11 @@ | |
| 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, 1 AS managed" |
| 156 | " FROM vfile LEFT JOIN 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 ? "coalesce(blob.size, 0)" : "0" /*safe-for-%s*/, |
| @@ -201,18 +201,17 @@ | |
| 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, 7); |
| 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 | char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); |
| 214 | int isMissing = !file_wd_isfile_or_link(zFullName); |
| 215 | |
| 216 | /* Determine the file change classification, if any. */ |
| 217 | if( isDeleted ){ |
| @@ -255,11 +254,11 @@ | |
| 254 | zClass = "SYMLINK"; |
| 255 | }else if( (flags & C_META) && isChnged==8 ){ |
| 256 | zClass = "UNEXEC"; |
| 257 | }else if( (flags & C_META) && isChnged==9 ){ |
| 258 | zClass = "UNLINK"; |
| 259 | }else if( (flags & C_CONFLICT) && isChnged && !file_wd_islink(zFullName) |
| 260 | && file_contains_merge_marker(zFullName) ){ |
| 261 | zClass = "CONFLICT"; |
| 262 | }else if( (flags & (C_EDITED | C_CHANGED)) && isChnged |
| 263 | && (isChnged<2 || isChnged>9) ){ |
| 264 | zClass = "EDITED"; |
| 265 |