Fossil SCM
Abort update or merge operation if there is content missing from files. Add --force-missing option to allow override if desired.
Commit
f2adddfe601d33c98974f9c645e8aceb9622aa86
Parent
d02f144d708e892…
3 files changed
+8
-2
+6
-1
+9
-5
+8
-2
| --- src/merge.c | ||
| +++ src/merge.c | ||
| @@ -91,10 +91,12 @@ | ||
| 91 | 91 | ** files whose names differ only in case are taken |
| 92 | 92 | ** to be the same file. |
| 93 | 93 | ** |
| 94 | 94 | ** -f|--force Force the merge even if it would be a no-op. |
| 95 | 95 | ** |
| 96 | +** --force-missing Force the merge even if there is missing content. | |
| 97 | +** | |
| 96 | 98 | ** --integrate Merged branch will be closed when committing. |
| 97 | 99 | ** |
| 98 | 100 | ** -n|--dry-run If given, display instead of run actions |
| 99 | 101 | ** |
| 100 | 102 | ** -v|--verbose Show additional details of the merge |
| @@ -107,10 +109,11 @@ | ||
| 107 | 109 | int integrateFlag; /* True if the --integrate option is present */ |
| 108 | 110 | int pickFlag; /* True if the --cherrypick option is present */ |
| 109 | 111 | int backoutFlag; /* True if the --backout option is present */ |
| 110 | 112 | int dryRunFlag; /* True if the --dry-run or -n option is present */ |
| 111 | 113 | int forceFlag; /* True if the --force or -f option is present */ |
| 114 | + int forceMissingFlag; /* True if the --force-missing option is present */ | |
| 112 | 115 | const char *zBinGlob; /* The value of --binary */ |
| 113 | 116 | const char *zPivot; /* The value of --baseline */ |
| 114 | 117 | int debugFlag; /* True if --debug is present */ |
| 115 | 118 | int nChng; /* Number of file name changes */ |
| 116 | 119 | int *aChng; /* An array of file name changes */ |
| @@ -127,10 +130,11 @@ | ||
| 127 | 130 | ** P The "pivot" - the most recent common ancestor of V and M. |
| 128 | 131 | */ |
| 129 | 132 | |
| 130 | 133 | undo_capture_command_line(); |
| 131 | 134 | verboseFlag = find_option("verbose","v",0)!=0; |
| 135 | + forceMissingFlag = find_option("force-missing",0,0)!=0; | |
| 132 | 136 | if( !verboseFlag ){ |
| 133 | 137 | verboseFlag = find_option("detail",0,0)!=0; /* deprecated */ |
| 134 | 138 | } |
| 135 | 139 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 136 | 140 | integrateFlag = find_option("integrate",0,0)!=0; |
| @@ -269,12 +273,14 @@ | ||
| 269 | 273 | print_checkin_description(pid, 12, "baseline:"); |
| 270 | 274 | } |
| 271 | 275 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 272 | 276 | db_begin_transaction(); |
| 273 | 277 | if( !dryRunFlag ) undo_begin(); |
| 274 | - load_vfile_from_rid(mid); | |
| 275 | - load_vfile_from_rid(pid); | |
| 278 | + if( ( load_vfile_from_rid(mid) | load_vfile_from_rid(pid) )!=0 | |
| 279 | + && !forceMissingFlag ){ | |
| 280 | + fossil_fatal("missing content, unable to merge"); | |
| 281 | + } | |
| 276 | 282 | if( debugFlag ){ |
| 277 | 283 | char *z; |
| 278 | 284 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pid); |
| 279 | 285 | fossil_print("P=%d %z\n", pid, z); |
| 280 | 286 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid); |
| 281 | 287 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,10 +91,12 @@ | |
| 91 | ** files whose names differ only in case are taken |
| 92 | ** to be the same file. |
| 93 | ** |
| 94 | ** -f|--force Force the merge even if it would be a no-op. |
| 95 | ** |
| 96 | ** --integrate Merged branch will be closed when committing. |
| 97 | ** |
| 98 | ** -n|--dry-run If given, display instead of run actions |
| 99 | ** |
| 100 | ** -v|--verbose Show additional details of the merge |
| @@ -107,10 +109,11 @@ | |
| 107 | int integrateFlag; /* True if the --integrate option is present */ |
| 108 | int pickFlag; /* True if the --cherrypick option is present */ |
| 109 | int backoutFlag; /* True if the --backout option is present */ |
| 110 | int dryRunFlag; /* True if the --dry-run or -n option is present */ |
| 111 | int forceFlag; /* True if the --force or -f option is present */ |
| 112 | const char *zBinGlob; /* The value of --binary */ |
| 113 | const char *zPivot; /* The value of --baseline */ |
| 114 | int debugFlag; /* True if --debug is present */ |
| 115 | int nChng; /* Number of file name changes */ |
| 116 | int *aChng; /* An array of file name changes */ |
| @@ -127,10 +130,11 @@ | |
| 127 | ** P The "pivot" - the most recent common ancestor of V and M. |
| 128 | */ |
| 129 | |
| 130 | undo_capture_command_line(); |
| 131 | verboseFlag = find_option("verbose","v",0)!=0; |
| 132 | if( !verboseFlag ){ |
| 133 | verboseFlag = find_option("detail",0,0)!=0; /* deprecated */ |
| 134 | } |
| 135 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 136 | integrateFlag = find_option("integrate",0,0)!=0; |
| @@ -269,12 +273,14 @@ | |
| 269 | print_checkin_description(pid, 12, "baseline:"); |
| 270 | } |
| 271 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 272 | db_begin_transaction(); |
| 273 | if( !dryRunFlag ) undo_begin(); |
| 274 | load_vfile_from_rid(mid); |
| 275 | load_vfile_from_rid(pid); |
| 276 | if( debugFlag ){ |
| 277 | char *z; |
| 278 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pid); |
| 279 | fossil_print("P=%d %z\n", pid, z); |
| 280 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid); |
| 281 |
| --- src/merge.c | |
| +++ src/merge.c | |
| @@ -91,10 +91,12 @@ | |
| 91 | ** files whose names differ only in case are taken |
| 92 | ** to be the same file. |
| 93 | ** |
| 94 | ** -f|--force Force the merge even if it would be a no-op. |
| 95 | ** |
| 96 | ** --force-missing Force the merge even if there is missing content. |
| 97 | ** |
| 98 | ** --integrate Merged branch will be closed when committing. |
| 99 | ** |
| 100 | ** -n|--dry-run If given, display instead of run actions |
| 101 | ** |
| 102 | ** -v|--verbose Show additional details of the merge |
| @@ -107,10 +109,11 @@ | |
| 109 | int integrateFlag; /* True if the --integrate option is present */ |
| 110 | int pickFlag; /* True if the --cherrypick option is present */ |
| 111 | int backoutFlag; /* True if the --backout option is present */ |
| 112 | int dryRunFlag; /* True if the --dry-run or -n option is present */ |
| 113 | int forceFlag; /* True if the --force or -f option is present */ |
| 114 | int forceMissingFlag; /* True if the --force-missing option is present */ |
| 115 | const char *zBinGlob; /* The value of --binary */ |
| 116 | const char *zPivot; /* The value of --baseline */ |
| 117 | int debugFlag; /* True if --debug is present */ |
| 118 | int nChng; /* Number of file name changes */ |
| 119 | int *aChng; /* An array of file name changes */ |
| @@ -127,10 +130,11 @@ | |
| 130 | ** P The "pivot" - the most recent common ancestor of V and M. |
| 131 | */ |
| 132 | |
| 133 | undo_capture_command_line(); |
| 134 | verboseFlag = find_option("verbose","v",0)!=0; |
| 135 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 136 | if( !verboseFlag ){ |
| 137 | verboseFlag = find_option("detail",0,0)!=0; /* deprecated */ |
| 138 | } |
| 139 | pickFlag = find_option("cherrypick",0,0)!=0; |
| 140 | integrateFlag = find_option("integrate",0,0)!=0; |
| @@ -269,12 +273,14 @@ | |
| 273 | print_checkin_description(pid, 12, "baseline:"); |
| 274 | } |
| 275 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 276 | db_begin_transaction(); |
| 277 | if( !dryRunFlag ) undo_begin(); |
| 278 | if( ( load_vfile_from_rid(mid) | load_vfile_from_rid(pid) )!=0 |
| 279 | && !forceMissingFlag ){ |
| 280 | fossil_fatal("missing content, unable to merge"); |
| 281 | } |
| 282 | if( debugFlag ){ |
| 283 | char *z; |
| 284 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", pid); |
| 285 | fossil_print("P=%d %z\n", pid, z); |
| 286 | z = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid); |
| 287 |
+6
-1
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -88,10 +88,11 @@ | ||
| 88 | 88 | ** |
| 89 | 89 | ** Options: |
| 90 | 90 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 91 | 91 | ** --debug print debug information on stdout |
| 92 | 92 | ** --latest acceptable in place of VERSION, update to latest version |
| 93 | +** --force-missing force update if missing content after sync | |
| 93 | 94 | ** -n|--dry-run If given, display instead of run actions |
| 94 | 95 | ** -v|--verbose print status information about all files |
| 95 | 96 | ** |
| 96 | 97 | ** See also: revert |
| 97 | 98 | */ |
| @@ -100,10 +101,11 @@ | ||
| 100 | 101 | int tid=0; /* Target version - version we are changing to */ |
| 101 | 102 | Stmt q; |
| 102 | 103 | int latestFlag; /* --latest. Pick the latest version if true */ |
| 103 | 104 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 104 | 105 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 106 | + int forceMissingFlag; /* -f or --force. Continue if missing content */ | |
| 105 | 107 | int debugFlag; /* --debug option */ |
| 106 | 108 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 107 | 109 | int nChng; /* Number of file renames */ |
| 108 | 110 | int *aChng; /* Array of file renames */ |
| 109 | 111 | int i; /* Loop counter */ |
| @@ -120,10 +122,11 @@ | ||
| 120 | 122 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 121 | 123 | if( !dryRunFlag ){ |
| 122 | 124 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 123 | 125 | } |
| 124 | 126 | verboseFlag = find_option("verbose","v",0)!=0; |
| 127 | + forceMissingFlag = find_option("force-missing",0,0)!=0; | |
| 125 | 128 | debugFlag = find_option("debug",0,0)!=0; |
| 126 | 129 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 127 | 130 | capture_case_sensitive_option(); |
| 128 | 131 | db_must_be_within_tree(); |
| 129 | 132 | vid = db_lget_int("checkout", 0); |
| @@ -205,11 +208,13 @@ | ||
| 205 | 208 | } |
| 206 | 209 | |
| 207 | 210 | db_begin_transaction(); |
| 208 | 211 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 209 | 212 | if( !dryRunFlag && !internalUpdate ) undo_begin(); |
| 210 | - load_vfile_from_rid(tid); | |
| 213 | + if( load_vfile_from_rid(tid) && !forceMissingFlag ){ | |
| 214 | + fossil_fatal("missing content, unable to update"); | |
| 215 | + }; | |
| 211 | 216 | |
| 212 | 217 | /* |
| 213 | 218 | ** The record.fn field is used to match files against each other. The |
| 214 | 219 | ** FV table contains one row for each each unique filename in |
| 215 | 220 | ** in the current checkout, the pivot, and the version being merged. |
| 216 | 221 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -88,10 +88,11 @@ | |
| 88 | ** |
| 89 | ** Options: |
| 90 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 91 | ** --debug print debug information on stdout |
| 92 | ** --latest acceptable in place of VERSION, update to latest version |
| 93 | ** -n|--dry-run If given, display instead of run actions |
| 94 | ** -v|--verbose print status information about all files |
| 95 | ** |
| 96 | ** See also: revert |
| 97 | */ |
| @@ -100,10 +101,11 @@ | |
| 100 | int tid=0; /* Target version - version we are changing to */ |
| 101 | Stmt q; |
| 102 | int latestFlag; /* --latest. Pick the latest version if true */ |
| 103 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 104 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 105 | int debugFlag; /* --debug option */ |
| 106 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 107 | int nChng; /* Number of file renames */ |
| 108 | int *aChng; /* Array of file renames */ |
| 109 | int i; /* Loop counter */ |
| @@ -120,10 +122,11 @@ | |
| 120 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 121 | if( !dryRunFlag ){ |
| 122 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 123 | } |
| 124 | verboseFlag = find_option("verbose","v",0)!=0; |
| 125 | debugFlag = find_option("debug",0,0)!=0; |
| 126 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 127 | capture_case_sensitive_option(); |
| 128 | db_must_be_within_tree(); |
| 129 | vid = db_lget_int("checkout", 0); |
| @@ -205,11 +208,13 @@ | |
| 205 | } |
| 206 | |
| 207 | db_begin_transaction(); |
| 208 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 209 | if( !dryRunFlag && !internalUpdate ) undo_begin(); |
| 210 | load_vfile_from_rid(tid); |
| 211 | |
| 212 | /* |
| 213 | ** The record.fn field is used to match files against each other. The |
| 214 | ** FV table contains one row for each each unique filename in |
| 215 | ** in the current checkout, the pivot, and the version being merged. |
| 216 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -88,10 +88,11 @@ | |
| 88 | ** |
| 89 | ** Options: |
| 90 | ** --case-sensitive <BOOL> override case-sensitive setting |
| 91 | ** --debug print debug information on stdout |
| 92 | ** --latest acceptable in place of VERSION, update to latest version |
| 93 | ** --force-missing force update if missing content after sync |
| 94 | ** -n|--dry-run If given, display instead of run actions |
| 95 | ** -v|--verbose print status information about all files |
| 96 | ** |
| 97 | ** See also: revert |
| 98 | */ |
| @@ -100,10 +101,11 @@ | |
| 101 | int tid=0; /* Target version - version we are changing to */ |
| 102 | Stmt q; |
| 103 | int latestFlag; /* --latest. Pick the latest version if true */ |
| 104 | int dryRunFlag; /* -n or --dry-run. Do a dry run */ |
| 105 | int verboseFlag; /* -v or --verbose. Output extra information */ |
| 106 | int forceMissingFlag; /* -f or --force. Continue if missing content */ |
| 107 | int debugFlag; /* --debug option */ |
| 108 | int setmtimeFlag; /* --setmtime. Set mtimes on files */ |
| 109 | int nChng; /* Number of file renames */ |
| 110 | int *aChng; /* Array of file renames */ |
| 111 | int i; /* Loop counter */ |
| @@ -120,10 +122,11 @@ | |
| 122 | dryRunFlag = find_option("dry-run","n",0)!=0; |
| 123 | if( !dryRunFlag ){ |
| 124 | dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */ |
| 125 | } |
| 126 | verboseFlag = find_option("verbose","v",0)!=0; |
| 127 | forceMissingFlag = find_option("force-missing",0,0)!=0; |
| 128 | debugFlag = find_option("debug",0,0)!=0; |
| 129 | setmtimeFlag = find_option("setmtime",0,0)!=0; |
| 130 | capture_case_sensitive_option(); |
| 131 | db_must_be_within_tree(); |
| 132 | vid = db_lget_int("checkout", 0); |
| @@ -205,11 +208,13 @@ | |
| 208 | } |
| 209 | |
| 210 | db_begin_transaction(); |
| 211 | vfile_check_signature(vid, CKSIG_ENOTFILE); |
| 212 | if( !dryRunFlag && !internalUpdate ) undo_begin(); |
| 213 | if( load_vfile_from_rid(tid) && !forceMissingFlag ){ |
| 214 | fossil_fatal("missing content, unable to update"); |
| 215 | }; |
| 216 | |
| 217 | /* |
| 218 | ** The record.fn field is used to match files against each other. The |
| 219 | ** FV table contains one row for each each unique filename in |
| 220 | ** in the current checkout, the pivot, and the version being merged. |
| 221 |
+9
-5
| --- src/vfile.c | ||
| +++ src/vfile.c | ||
| @@ -68,34 +68,36 @@ | ||
| 68 | 68 | return rid; |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | |
| 72 | 72 | /* |
| 73 | -** Load a vfile from a record ID. | |
| 73 | +** Load a vfile from a record ID. Return the number of files with | |
| 74 | +** missing content. | |
| 74 | 75 | */ |
| 75 | -void load_vfile_from_rid(int vid){ | |
| 76 | - int rid, size; | |
| 76 | +int load_vfile_from_rid(int vid){ | |
| 77 | + int rid, size, nMissing; | |
| 77 | 78 | Stmt ins, ridq; |
| 78 | 79 | Manifest *p; |
| 79 | 80 | ManifestFile *pFile; |
| 80 | 81 | |
| 81 | 82 | if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){ |
| 82 | - return; | |
| 83 | + return 0; | |
| 83 | 84 | } |
| 84 | 85 | |
| 85 | 86 | db_begin_transaction(); |
| 86 | 87 | p = manifest_get(vid, CFTYPE_MANIFEST, 0); |
| 87 | 88 | if( p==0 ) { |
| 88 | 89 | db_end_transaction(1); |
| 89 | - return; | |
| 90 | + return 0; | |
| 90 | 91 | } |
| 91 | 92 | db_prepare(&ins, |
| 92 | 93 | "INSERT INTO vfile(vid,isexe,islink,rid,mrid,pathname) " |
| 93 | 94 | " VALUES(:vid,:isexe,:islink,:id,:id,:name)"); |
| 94 | 95 | db_prepare(&ridq, "SELECT rid,size FROM blob WHERE uuid=:uuid"); |
| 95 | 96 | db_bind_int(&ins, ":vid", vid); |
| 96 | 97 | manifest_file_rewind(p); |
| 98 | + nMissing = 0; | |
| 97 | 99 | while( (pFile = manifest_file_next(p,0))!=0 ){ |
| 98 | 100 | if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue; |
| 99 | 101 | db_bind_text(&ridq, ":uuid", pFile->zUuid); |
| 100 | 102 | if( db_step(&ridq)==SQLITE_ROW ){ |
| 101 | 103 | rid = db_column_int(&ridq, 0); |
| @@ -105,10 +107,11 @@ | ||
| 105 | 107 | size = 0; |
| 106 | 108 | } |
| 107 | 109 | db_reset(&ridq); |
| 108 | 110 | if( rid==0 || size<0 ){ |
| 109 | 111 | fossil_warning("content missing for %s", pFile->zName); |
| 112 | + nMissing++; | |
| 110 | 113 | continue; |
| 111 | 114 | } |
| 112 | 115 | db_bind_int(&ins, ":isexe", ( manifest_file_mperm(pFile)==PERM_EXE )); |
| 113 | 116 | db_bind_int(&ins, ":id", rid); |
| 114 | 117 | db_bind_text(&ins, ":name", pFile->zName); |
| @@ -118,10 +121,11 @@ | ||
| 118 | 121 | } |
| 119 | 122 | db_finalize(&ridq); |
| 120 | 123 | db_finalize(&ins); |
| 121 | 124 | manifest_destroy(p); |
| 122 | 125 | db_end_transaction(0); |
| 126 | + return nMissing; | |
| 123 | 127 | } |
| 124 | 128 | |
| 125 | 129 | #if INTERFACE |
| 126 | 130 | /* |
| 127 | 131 | ** The cksigFlags parameter to vfile_check_signature() is an OR-ed |
| 128 | 132 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -68,34 +68,36 @@ | |
| 68 | return rid; |
| 69 | } |
| 70 | |
| 71 | |
| 72 | /* |
| 73 | ** Load a vfile from a record ID. |
| 74 | */ |
| 75 | void load_vfile_from_rid(int vid){ |
| 76 | int rid, size; |
| 77 | Stmt ins, ridq; |
| 78 | Manifest *p; |
| 79 | ManifestFile *pFile; |
| 80 | |
| 81 | if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){ |
| 82 | return; |
| 83 | } |
| 84 | |
| 85 | db_begin_transaction(); |
| 86 | p = manifest_get(vid, CFTYPE_MANIFEST, 0); |
| 87 | if( p==0 ) { |
| 88 | db_end_transaction(1); |
| 89 | return; |
| 90 | } |
| 91 | db_prepare(&ins, |
| 92 | "INSERT INTO vfile(vid,isexe,islink,rid,mrid,pathname) " |
| 93 | " VALUES(:vid,:isexe,:islink,:id,:id,:name)"); |
| 94 | db_prepare(&ridq, "SELECT rid,size FROM blob WHERE uuid=:uuid"); |
| 95 | db_bind_int(&ins, ":vid", vid); |
| 96 | manifest_file_rewind(p); |
| 97 | while( (pFile = manifest_file_next(p,0))!=0 ){ |
| 98 | if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue; |
| 99 | db_bind_text(&ridq, ":uuid", pFile->zUuid); |
| 100 | if( db_step(&ridq)==SQLITE_ROW ){ |
| 101 | rid = db_column_int(&ridq, 0); |
| @@ -105,10 +107,11 @@ | |
| 105 | size = 0; |
| 106 | } |
| 107 | db_reset(&ridq); |
| 108 | if( rid==0 || size<0 ){ |
| 109 | fossil_warning("content missing for %s", pFile->zName); |
| 110 | continue; |
| 111 | } |
| 112 | db_bind_int(&ins, ":isexe", ( manifest_file_mperm(pFile)==PERM_EXE )); |
| 113 | db_bind_int(&ins, ":id", rid); |
| 114 | db_bind_text(&ins, ":name", pFile->zName); |
| @@ -118,10 +121,11 @@ | |
| 118 | } |
| 119 | db_finalize(&ridq); |
| 120 | db_finalize(&ins); |
| 121 | manifest_destroy(p); |
| 122 | db_end_transaction(0); |
| 123 | } |
| 124 | |
| 125 | #if INTERFACE |
| 126 | /* |
| 127 | ** The cksigFlags parameter to vfile_check_signature() is an OR-ed |
| 128 |
| --- src/vfile.c | |
| +++ src/vfile.c | |
| @@ -68,34 +68,36 @@ | |
| 68 | return rid; |
| 69 | } |
| 70 | |
| 71 | |
| 72 | /* |
| 73 | ** Load a vfile from a record ID. Return the number of files with |
| 74 | ** missing content. |
| 75 | */ |
| 76 | int load_vfile_from_rid(int vid){ |
| 77 | int rid, size, nMissing; |
| 78 | Stmt ins, ridq; |
| 79 | Manifest *p; |
| 80 | ManifestFile *pFile; |
| 81 | |
| 82 | if( db_exists("SELECT 1 FROM vfile WHERE vid=%d", vid) ){ |
| 83 | return 0; |
| 84 | } |
| 85 | |
| 86 | db_begin_transaction(); |
| 87 | p = manifest_get(vid, CFTYPE_MANIFEST, 0); |
| 88 | if( p==0 ) { |
| 89 | db_end_transaction(1); |
| 90 | return 0; |
| 91 | } |
| 92 | db_prepare(&ins, |
| 93 | "INSERT INTO vfile(vid,isexe,islink,rid,mrid,pathname) " |
| 94 | " VALUES(:vid,:isexe,:islink,:id,:id,:name)"); |
| 95 | db_prepare(&ridq, "SELECT rid,size FROM blob WHERE uuid=:uuid"); |
| 96 | db_bind_int(&ins, ":vid", vid); |
| 97 | manifest_file_rewind(p); |
| 98 | nMissing = 0; |
| 99 | while( (pFile = manifest_file_next(p,0))!=0 ){ |
| 100 | if( pFile->zUuid==0 || uuid_is_shunned(pFile->zUuid) ) continue; |
| 101 | db_bind_text(&ridq, ":uuid", pFile->zUuid); |
| 102 | if( db_step(&ridq)==SQLITE_ROW ){ |
| 103 | rid = db_column_int(&ridq, 0); |
| @@ -105,10 +107,11 @@ | |
| 107 | size = 0; |
| 108 | } |
| 109 | db_reset(&ridq); |
| 110 | if( rid==0 || size<0 ){ |
| 111 | fossil_warning("content missing for %s", pFile->zName); |
| 112 | nMissing++; |
| 113 | continue; |
| 114 | } |
| 115 | db_bind_int(&ins, ":isexe", ( manifest_file_mperm(pFile)==PERM_EXE )); |
| 116 | db_bind_int(&ins, ":id", rid); |
| 117 | db_bind_text(&ins, ":name", pFile->zName); |
| @@ -118,10 +121,11 @@ | |
| 121 | } |
| 122 | db_finalize(&ridq); |
| 123 | db_finalize(&ins); |
| 124 | manifest_destroy(p); |
| 125 | db_end_transaction(0); |
| 126 | return nMissing; |
| 127 | } |
| 128 | |
| 129 | #if INTERFACE |
| 130 | /* |
| 131 | ** The cksigFlags parameter to vfile_check_signature() is an OR-ed |
| 132 |