Fossil SCM
Merge Joerg's export command improvements into trunk.
Commit
dd74352d2c919e7b5f67d0bc372f8d7f1bd97d44
Parent
ccc2c8f65ea6d87…
2 files changed
+41
-21
+41
-21
+41
-21
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -105,11 +105,11 @@ | ||
| 105 | 105 | ** |
| 106 | 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | 108 | */ |
| 109 | 109 | void export_cmd(void){ |
| 110 | - Stmt q, q2; | |
| 110 | + Stmt q, q2, q3; | |
| 111 | 111 | int i; |
| 112 | 112 | Bag blobs, vers; |
| 113 | 113 | const char *markfile_in; |
| 114 | 114 | const char *markfile_out; |
| 115 | 115 | |
| @@ -122,23 +122,23 @@ | ||
| 122 | 122 | |
| 123 | 123 | db_find_and_open_repository(0, 2); |
| 124 | 124 | verify_all_options(); |
| 125 | 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | 126 | |
| 127 | - db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER)"); | |
| 128 | - db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER)"); | |
| 127 | + db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)"); | |
| 128 | + db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER PRIMARY KEY)"); | |
| 129 | 129 | if( markfile_in!=0 ){ |
| 130 | 130 | Stmt qb,qc; |
| 131 | 131 | char line[100]; |
| 132 | 132 | FILE *f; |
| 133 | 133 | |
| 134 | 134 | f = fopen(markfile_in, "r"); |
| 135 | 135 | if( f==0 ){ |
| 136 | 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | 137 | } |
| 138 | - db_prepare(&qb, "INSERT INTO oldblob VALUES (:rid)"); | |
| 139 | - db_prepare(&qc, "INSERT INTO oldcommit VALUES (:rid)"); | |
| 138 | + db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)"); | |
| 139 | + db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)"); | |
| 140 | 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | 141 | if( *line == 'b' ){ |
| 142 | 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | 143 | db_step(&qb); |
| 144 | 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | ||
| 159 | 159 | |
| 160 | 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | 161 | ** of a check-in |
| 162 | 162 | */ |
| 163 | 163 | fossil_binary_mode(stdout); |
| 164 | + db_multi_exec("CREATE TEMPORARY TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); | |
| 165 | + db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); | |
| 166 | + db_multi_exec( | |
| 167 | + "INSERT INTO newblob" | |
| 168 | + " SELECT DISTINCT fid," | |
| 169 | + " CASE WHEN EXISTS(SELECT 1 FROM delta WHERE rid=fid AND NOT EXISTS(SELECT 1 FROM oldblob WHERE srcid=fid))" | |
| 170 | + " THEN (SELECT srcid FROM delta WHERE rid=fid)" | |
| 171 | + " ELSE 0" | |
| 172 | + " END" | |
| 173 | + " FROM mlink" | |
| 174 | + " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); | |
| 164 | 175 | db_prepare(&q, |
| 165 | 176 | "SELECT DISTINCT fid FROM mlink" |
| 166 | 177 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 167 | 178 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 179 | + db_prepare(&q3, "SELECT rid FROM newblob WHERE srcid= (:srcid)"); | |
| 168 | 180 | while( db_step(&q)==SQLITE_ROW ){ |
| 169 | 181 | int rid = db_column_int(&q, 0); |
| 170 | 182 | Blob content; |
| 171 | - content_get(rid, &content); | |
| 172 | - db_bind_int(&q2, ":rid", rid); | |
| 173 | - db_step(&q2); | |
| 174 | - db_reset(&q2); | |
| 175 | - printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); | |
| 176 | - bag_insert(&blobs, rid); | |
| 177 | - fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); | |
| 178 | - printf("\n"); | |
| 179 | - blob_reset(&content); | |
| 183 | + | |
| 184 | + while( !bag_find(&blobs, rid) ){ | |
| 185 | + content_get(rid, &content); | |
| 186 | + db_bind_int(&q2, ":rid", rid); | |
| 187 | + db_step(&q2); | |
| 188 | + db_reset(&q2); | |
| 189 | + printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); | |
| 190 | + bag_insert(&blobs, rid); | |
| 191 | + fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); | |
| 192 | + printf("\n"); | |
| 193 | + blob_reset(&content); | |
| 194 | + | |
| 195 | + db_bind_int(&q3, ":srcid", rid); | |
| 196 | + if( db_step(&q3) != SQLITE_ROW ){ | |
| 197 | + db_reset(&q3); | |
| 198 | + break; | |
| 199 | + } | |
| 200 | + rid = db_column_int(&q3, 0); | |
| 201 | + db_reset(&q3); | |
| 202 | + } | |
| 180 | 203 | } |
| 181 | 204 | db_finalize(&q); |
| 182 | 205 | db_finalize(&q2); |
| 206 | + db_finalize(&q3); | |
| 183 | 207 | |
| 184 | 208 | /* Output the commit records. |
| 185 | 209 | */ |
| 186 | 210 | db_prepare(&q, |
| 187 | 211 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | ||
| 192 | 216 | " ORDER BY mtime ASC", |
| 193 | 217 | TAG_BRANCH |
| 194 | 218 | ); |
| 195 | 219 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 196 | 220 | while( db_step(&q)==SQLITE_ROW ){ |
| 197 | - Stmt q3, q4; | |
| 221 | + Stmt q4; | |
| 198 | 222 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 199 | 223 | int ckinId = db_column_int(&q, 1); |
| 200 | 224 | const char *zComment = db_column_text(&q, 2); |
| 201 | 225 | const char *zUser = db_column_text(&q, 3); |
| 202 | 226 | const char *zBranch = db_column_text(&q, 4); |
| 203 | 227 | char *zBr; |
| 204 | - int parent; | |
| 205 | 228 | |
| 206 | 229 | bag_insert(&vers, ckinId); |
| 207 | 230 | db_bind_int(&q2, ":rid", ckinId); |
| 208 | 231 | db_step(&q2); |
| 209 | 232 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | ||
| 219 | 242 | printf(" %s +0000\n", zSecondsSince1970); |
| 220 | 243 | if( zComment==0 ) zComment = "null comment"; |
| 221 | 244 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 222 | 245 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 223 | 246 | if( db_step(&q3) == SQLITE_ROW ){ |
| 224 | - parent = db_column_int(&q3, 0); | |
| 225 | - | |
| 226 | - printf("from :%d\n", COMMITMARK(parent)); | |
| 247 | + printf("from :%d\n", COMMITMARK(db_column_int(&q3, 0))); | |
| 227 | 248 | db_prepare(&q4, |
| 228 | 249 | "SELECT pid FROM plink" |
| 229 | 250 | " WHERE cid=%d AND NOT isprim" |
| 230 | 251 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 231 | 252 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | ||
| 233 | 254 | while( db_step(&q4)==SQLITE_ROW ){ |
| 234 | 255 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 235 | 256 | } |
| 236 | 257 | db_finalize(&q4); |
| 237 | 258 | }else{ |
| 238 | - parent = 0; | |
| 239 | 259 | printf("deleteall\n"); |
| 240 | 260 | } |
| 241 | 261 | |
| 242 | 262 | db_prepare(&q4, |
| 243 | 263 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 244 | 264 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 245 | 265 | " WHERE mlink.mid=%d", |
| 246 | - parent | |
| 266 | + ckinId | |
| 247 | 267 | ); |
| 248 | 268 | while( db_step(&q4)==SQLITE_ROW ){ |
| 249 | 269 | const char *zName = db_column_text(&q4,0); |
| 250 | 270 | int zNew = db_column_int(&q4,1); |
| 251 | 271 | int mPerm = db_column_int(&q4,2); |
| 252 | 272 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -105,11 +105,11 @@ | |
| 105 | ** |
| 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | */ |
| 109 | void export_cmd(void){ |
| 110 | Stmt q, q2; |
| 111 | int i; |
| 112 | Bag blobs, vers; |
| 113 | const char *markfile_in; |
| 114 | const char *markfile_out; |
| 115 | |
| @@ -122,23 +122,23 @@ | |
| 122 | |
| 123 | db_find_and_open_repository(0, 2); |
| 124 | verify_all_options(); |
| 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | |
| 127 | db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER)"); |
| 128 | db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER)"); |
| 129 | if( markfile_in!=0 ){ |
| 130 | Stmt qb,qc; |
| 131 | char line[100]; |
| 132 | FILE *f; |
| 133 | |
| 134 | f = fopen(markfile_in, "r"); |
| 135 | if( f==0 ){ |
| 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | } |
| 138 | db_prepare(&qb, "INSERT INTO oldblob VALUES (:rid)"); |
| 139 | db_prepare(&qc, "INSERT INTO oldcommit VALUES (:rid)"); |
| 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | if( *line == 'b' ){ |
| 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | db_step(&qb); |
| 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | |
| 159 | |
| 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | ** of a check-in |
| 162 | */ |
| 163 | fossil_binary_mode(stdout); |
| 164 | db_prepare(&q, |
| 165 | "SELECT DISTINCT fid FROM mlink" |
| 166 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 167 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 168 | while( db_step(&q)==SQLITE_ROW ){ |
| 169 | int rid = db_column_int(&q, 0); |
| 170 | Blob content; |
| 171 | content_get(rid, &content); |
| 172 | db_bind_int(&q2, ":rid", rid); |
| 173 | db_step(&q2); |
| 174 | db_reset(&q2); |
| 175 | printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); |
| 176 | bag_insert(&blobs, rid); |
| 177 | fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); |
| 178 | printf("\n"); |
| 179 | blob_reset(&content); |
| 180 | } |
| 181 | db_finalize(&q); |
| 182 | db_finalize(&q2); |
| 183 | |
| 184 | /* Output the commit records. |
| 185 | */ |
| 186 | db_prepare(&q, |
| 187 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | |
| 192 | " ORDER BY mtime ASC", |
| 193 | TAG_BRANCH |
| 194 | ); |
| 195 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 196 | while( db_step(&q)==SQLITE_ROW ){ |
| 197 | Stmt q3, q4; |
| 198 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 199 | int ckinId = db_column_int(&q, 1); |
| 200 | const char *zComment = db_column_text(&q, 2); |
| 201 | const char *zUser = db_column_text(&q, 3); |
| 202 | const char *zBranch = db_column_text(&q, 4); |
| 203 | char *zBr; |
| 204 | int parent; |
| 205 | |
| 206 | bag_insert(&vers, ckinId); |
| 207 | db_bind_int(&q2, ":rid", ckinId); |
| 208 | db_step(&q2); |
| 209 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | |
| 219 | printf(" %s +0000\n", zSecondsSince1970); |
| 220 | if( zComment==0 ) zComment = "null comment"; |
| 221 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 222 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 223 | if( db_step(&q3) == SQLITE_ROW ){ |
| 224 | parent = db_column_int(&q3, 0); |
| 225 | |
| 226 | printf("from :%d\n", COMMITMARK(parent)); |
| 227 | db_prepare(&q4, |
| 228 | "SELECT pid FROM plink" |
| 229 | " WHERE cid=%d AND NOT isprim" |
| 230 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 231 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | |
| 233 | while( db_step(&q4)==SQLITE_ROW ){ |
| 234 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 235 | } |
| 236 | db_finalize(&q4); |
| 237 | }else{ |
| 238 | parent = 0; |
| 239 | printf("deleteall\n"); |
| 240 | } |
| 241 | |
| 242 | db_prepare(&q4, |
| 243 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 244 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 245 | " WHERE mlink.mid=%d", |
| 246 | parent |
| 247 | ); |
| 248 | while( db_step(&q4)==SQLITE_ROW ){ |
| 249 | const char *zName = db_column_text(&q4,0); |
| 250 | int zNew = db_column_int(&q4,1); |
| 251 | int mPerm = db_column_int(&q4,2); |
| 252 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -105,11 +105,11 @@ | |
| 105 | ** |
| 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | */ |
| 109 | void export_cmd(void){ |
| 110 | Stmt q, q2, q3; |
| 111 | int i; |
| 112 | Bag blobs, vers; |
| 113 | const char *markfile_in; |
| 114 | const char *markfile_out; |
| 115 | |
| @@ -122,23 +122,23 @@ | |
| 122 | |
| 123 | db_find_and_open_repository(0, 2); |
| 124 | verify_all_options(); |
| 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | |
| 127 | db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)"); |
| 128 | db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER PRIMARY KEY)"); |
| 129 | if( markfile_in!=0 ){ |
| 130 | Stmt qb,qc; |
| 131 | char line[100]; |
| 132 | FILE *f; |
| 133 | |
| 134 | f = fopen(markfile_in, "r"); |
| 135 | if( f==0 ){ |
| 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | } |
| 138 | db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)"); |
| 139 | db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)"); |
| 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | if( *line == 'b' ){ |
| 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | db_step(&qb); |
| 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | |
| 159 | |
| 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | ** of a check-in |
| 162 | */ |
| 163 | fossil_binary_mode(stdout); |
| 164 | db_multi_exec("CREATE TEMPORARY TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); |
| 165 | db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); |
| 166 | db_multi_exec( |
| 167 | "INSERT INTO newblob" |
| 168 | " SELECT DISTINCT fid," |
| 169 | " CASE WHEN EXISTS(SELECT 1 FROM delta WHERE rid=fid AND NOT EXISTS(SELECT 1 FROM oldblob WHERE srcid=fid))" |
| 170 | " THEN (SELECT srcid FROM delta WHERE rid=fid)" |
| 171 | " ELSE 0" |
| 172 | " END" |
| 173 | " FROM mlink" |
| 174 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 175 | db_prepare(&q, |
| 176 | "SELECT DISTINCT fid FROM mlink" |
| 177 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 178 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 179 | db_prepare(&q3, "SELECT rid FROM newblob WHERE srcid= (:srcid)"); |
| 180 | while( db_step(&q)==SQLITE_ROW ){ |
| 181 | int rid = db_column_int(&q, 0); |
| 182 | Blob content; |
| 183 | |
| 184 | while( !bag_find(&blobs, rid) ){ |
| 185 | content_get(rid, &content); |
| 186 | db_bind_int(&q2, ":rid", rid); |
| 187 | db_step(&q2); |
| 188 | db_reset(&q2); |
| 189 | printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); |
| 190 | bag_insert(&blobs, rid); |
| 191 | fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); |
| 192 | printf("\n"); |
| 193 | blob_reset(&content); |
| 194 | |
| 195 | db_bind_int(&q3, ":srcid", rid); |
| 196 | if( db_step(&q3) != SQLITE_ROW ){ |
| 197 | db_reset(&q3); |
| 198 | break; |
| 199 | } |
| 200 | rid = db_column_int(&q3, 0); |
| 201 | db_reset(&q3); |
| 202 | } |
| 203 | } |
| 204 | db_finalize(&q); |
| 205 | db_finalize(&q2); |
| 206 | db_finalize(&q3); |
| 207 | |
| 208 | /* Output the commit records. |
| 209 | */ |
| 210 | db_prepare(&q, |
| 211 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | |
| 216 | " ORDER BY mtime ASC", |
| 217 | TAG_BRANCH |
| 218 | ); |
| 219 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 220 | while( db_step(&q)==SQLITE_ROW ){ |
| 221 | Stmt q4; |
| 222 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 223 | int ckinId = db_column_int(&q, 1); |
| 224 | const char *zComment = db_column_text(&q, 2); |
| 225 | const char *zUser = db_column_text(&q, 3); |
| 226 | const char *zBranch = db_column_text(&q, 4); |
| 227 | char *zBr; |
| 228 | |
| 229 | bag_insert(&vers, ckinId); |
| 230 | db_bind_int(&q2, ":rid", ckinId); |
| 231 | db_step(&q2); |
| 232 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | |
| 242 | printf(" %s +0000\n", zSecondsSince1970); |
| 243 | if( zComment==0 ) zComment = "null comment"; |
| 244 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 245 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 246 | if( db_step(&q3) == SQLITE_ROW ){ |
| 247 | printf("from :%d\n", COMMITMARK(db_column_int(&q3, 0))); |
| 248 | db_prepare(&q4, |
| 249 | "SELECT pid FROM plink" |
| 250 | " WHERE cid=%d AND NOT isprim" |
| 251 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 252 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | |
| 254 | while( db_step(&q4)==SQLITE_ROW ){ |
| 255 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 256 | } |
| 257 | db_finalize(&q4); |
| 258 | }else{ |
| 259 | printf("deleteall\n"); |
| 260 | } |
| 261 | |
| 262 | db_prepare(&q4, |
| 263 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 264 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 265 | " WHERE mlink.mid=%d", |
| 266 | ckinId |
| 267 | ); |
| 268 | while( db_step(&q4)==SQLITE_ROW ){ |
| 269 | const char *zName = db_column_text(&q4,0); |
| 270 | int zNew = db_column_int(&q4,1); |
| 271 | int mPerm = db_column_int(&q4,2); |
| 272 |
+41
-21
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -105,11 +105,11 @@ | ||
| 105 | 105 | ** |
| 106 | 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | 108 | */ |
| 109 | 109 | void export_cmd(void){ |
| 110 | - Stmt q, q2; | |
| 110 | + Stmt q, q2, q3; | |
| 111 | 111 | int i; |
| 112 | 112 | Bag blobs, vers; |
| 113 | 113 | const char *markfile_in; |
| 114 | 114 | const char *markfile_out; |
| 115 | 115 | |
| @@ -122,23 +122,23 @@ | ||
| 122 | 122 | |
| 123 | 123 | db_find_and_open_repository(0, 2); |
| 124 | 124 | verify_all_options(); |
| 125 | 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | 126 | |
| 127 | - db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER)"); | |
| 128 | - db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER)"); | |
| 127 | + db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)"); | |
| 128 | + db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER PRIMARY KEY)"); | |
| 129 | 129 | if( markfile_in!=0 ){ |
| 130 | 130 | Stmt qb,qc; |
| 131 | 131 | char line[100]; |
| 132 | 132 | FILE *f; |
| 133 | 133 | |
| 134 | 134 | f = fopen(markfile_in, "r"); |
| 135 | 135 | if( f==0 ){ |
| 136 | 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | 137 | } |
| 138 | - db_prepare(&qb, "INSERT INTO oldblob VALUES (:rid)"); | |
| 139 | - db_prepare(&qc, "INSERT INTO oldcommit VALUES (:rid)"); | |
| 138 | + db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)"); | |
| 139 | + db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)"); | |
| 140 | 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | 141 | if( *line == 'b' ){ |
| 142 | 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | 143 | db_step(&qb); |
| 144 | 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | ||
| 159 | 159 | |
| 160 | 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | 161 | ** of a check-in |
| 162 | 162 | */ |
| 163 | 163 | fossil_binary_mode(stdout); |
| 164 | + db_multi_exec("CREATE TEMPORARY TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); | |
| 165 | + db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); | |
| 166 | + db_multi_exec( | |
| 167 | + "INSERT INTO newblob" | |
| 168 | + " SELECT DISTINCT fid," | |
| 169 | + " CASE WHEN EXISTS(SELECT 1 FROM delta WHERE rid=fid AND NOT EXISTS(SELECT 1 FROM oldblob WHERE srcid=fid))" | |
| 170 | + " THEN (SELECT srcid FROM delta WHERE rid=fid)" | |
| 171 | + " ELSE 0" | |
| 172 | + " END" | |
| 173 | + " FROM mlink" | |
| 174 | + " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); | |
| 164 | 175 | db_prepare(&q, |
| 165 | 176 | "SELECT DISTINCT fid FROM mlink" |
| 166 | 177 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 167 | 178 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 179 | + db_prepare(&q3, "SELECT rid FROM newblob WHERE srcid= (:srcid)"); | |
| 168 | 180 | while( db_step(&q)==SQLITE_ROW ){ |
| 169 | 181 | int rid = db_column_int(&q, 0); |
| 170 | 182 | Blob content; |
| 171 | - content_get(rid, &content); | |
| 172 | - db_bind_int(&q2, ":rid", rid); | |
| 173 | - db_step(&q2); | |
| 174 | - db_reset(&q2); | |
| 175 | - printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); | |
| 176 | - bag_insert(&blobs, rid); | |
| 177 | - fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); | |
| 178 | - printf("\n"); | |
| 179 | - blob_reset(&content); | |
| 183 | + | |
| 184 | + while( !bag_find(&blobs, rid) ){ | |
| 185 | + content_get(rid, &content); | |
| 186 | + db_bind_int(&q2, ":rid", rid); | |
| 187 | + db_step(&q2); | |
| 188 | + db_reset(&q2); | |
| 189 | + printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); | |
| 190 | + bag_insert(&blobs, rid); | |
| 191 | + fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); | |
| 192 | + printf("\n"); | |
| 193 | + blob_reset(&content); | |
| 194 | + | |
| 195 | + db_bind_int(&q3, ":srcid", rid); | |
| 196 | + if( db_step(&q3) != SQLITE_ROW ){ | |
| 197 | + db_reset(&q3); | |
| 198 | + break; | |
| 199 | + } | |
| 200 | + rid = db_column_int(&q3, 0); | |
| 201 | + db_reset(&q3); | |
| 202 | + } | |
| 180 | 203 | } |
| 181 | 204 | db_finalize(&q); |
| 182 | 205 | db_finalize(&q2); |
| 206 | + db_finalize(&q3); | |
| 183 | 207 | |
| 184 | 208 | /* Output the commit records. |
| 185 | 209 | */ |
| 186 | 210 | db_prepare(&q, |
| 187 | 211 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | ||
| 192 | 216 | " ORDER BY mtime ASC", |
| 193 | 217 | TAG_BRANCH |
| 194 | 218 | ); |
| 195 | 219 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 196 | 220 | while( db_step(&q)==SQLITE_ROW ){ |
| 197 | - Stmt q3, q4; | |
| 221 | + Stmt q4; | |
| 198 | 222 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 199 | 223 | int ckinId = db_column_int(&q, 1); |
| 200 | 224 | const char *zComment = db_column_text(&q, 2); |
| 201 | 225 | const char *zUser = db_column_text(&q, 3); |
| 202 | 226 | const char *zBranch = db_column_text(&q, 4); |
| 203 | 227 | char *zBr; |
| 204 | - int parent; | |
| 205 | 228 | |
| 206 | 229 | bag_insert(&vers, ckinId); |
| 207 | 230 | db_bind_int(&q2, ":rid", ckinId); |
| 208 | 231 | db_step(&q2); |
| 209 | 232 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | ||
| 219 | 242 | printf(" %s +0000\n", zSecondsSince1970); |
| 220 | 243 | if( zComment==0 ) zComment = "null comment"; |
| 221 | 244 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 222 | 245 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 223 | 246 | if( db_step(&q3) == SQLITE_ROW ){ |
| 224 | - parent = db_column_int(&q3, 0); | |
| 225 | - | |
| 226 | - printf("from :%d\n", COMMITMARK(parent)); | |
| 247 | + printf("from :%d\n", COMMITMARK(db_column_int(&q3, 0))); | |
| 227 | 248 | db_prepare(&q4, |
| 228 | 249 | "SELECT pid FROM plink" |
| 229 | 250 | " WHERE cid=%d AND NOT isprim" |
| 230 | 251 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 231 | 252 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | ||
| 233 | 254 | while( db_step(&q4)==SQLITE_ROW ){ |
| 234 | 255 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 235 | 256 | } |
| 236 | 257 | db_finalize(&q4); |
| 237 | 258 | }else{ |
| 238 | - parent = 0; | |
| 239 | 259 | printf("deleteall\n"); |
| 240 | 260 | } |
| 241 | 261 | |
| 242 | 262 | db_prepare(&q4, |
| 243 | 263 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 244 | 264 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 245 | 265 | " WHERE mlink.mid=%d", |
| 246 | - parent | |
| 266 | + ckinId | |
| 247 | 267 | ); |
| 248 | 268 | while( db_step(&q4)==SQLITE_ROW ){ |
| 249 | 269 | const char *zName = db_column_text(&q4,0); |
| 250 | 270 | int zNew = db_column_int(&q4,1); |
| 251 | 271 | int mPerm = db_column_int(&q4,2); |
| 252 | 272 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -105,11 +105,11 @@ | |
| 105 | ** |
| 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | */ |
| 109 | void export_cmd(void){ |
| 110 | Stmt q, q2; |
| 111 | int i; |
| 112 | Bag blobs, vers; |
| 113 | const char *markfile_in; |
| 114 | const char *markfile_out; |
| 115 | |
| @@ -122,23 +122,23 @@ | |
| 122 | |
| 123 | db_find_and_open_repository(0, 2); |
| 124 | verify_all_options(); |
| 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | |
| 127 | db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER)"); |
| 128 | db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER)"); |
| 129 | if( markfile_in!=0 ){ |
| 130 | Stmt qb,qc; |
| 131 | char line[100]; |
| 132 | FILE *f; |
| 133 | |
| 134 | f = fopen(markfile_in, "r"); |
| 135 | if( f==0 ){ |
| 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | } |
| 138 | db_prepare(&qb, "INSERT INTO oldblob VALUES (:rid)"); |
| 139 | db_prepare(&qc, "INSERT INTO oldcommit VALUES (:rid)"); |
| 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | if( *line == 'b' ){ |
| 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | db_step(&qb); |
| 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | |
| 159 | |
| 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | ** of a check-in |
| 162 | */ |
| 163 | fossil_binary_mode(stdout); |
| 164 | db_prepare(&q, |
| 165 | "SELECT DISTINCT fid FROM mlink" |
| 166 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 167 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 168 | while( db_step(&q)==SQLITE_ROW ){ |
| 169 | int rid = db_column_int(&q, 0); |
| 170 | Blob content; |
| 171 | content_get(rid, &content); |
| 172 | db_bind_int(&q2, ":rid", rid); |
| 173 | db_step(&q2); |
| 174 | db_reset(&q2); |
| 175 | printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); |
| 176 | bag_insert(&blobs, rid); |
| 177 | fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); |
| 178 | printf("\n"); |
| 179 | blob_reset(&content); |
| 180 | } |
| 181 | db_finalize(&q); |
| 182 | db_finalize(&q2); |
| 183 | |
| 184 | /* Output the commit records. |
| 185 | */ |
| 186 | db_prepare(&q, |
| 187 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | |
| 192 | " ORDER BY mtime ASC", |
| 193 | TAG_BRANCH |
| 194 | ); |
| 195 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 196 | while( db_step(&q)==SQLITE_ROW ){ |
| 197 | Stmt q3, q4; |
| 198 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 199 | int ckinId = db_column_int(&q, 1); |
| 200 | const char *zComment = db_column_text(&q, 2); |
| 201 | const char *zUser = db_column_text(&q, 3); |
| 202 | const char *zBranch = db_column_text(&q, 4); |
| 203 | char *zBr; |
| 204 | int parent; |
| 205 | |
| 206 | bag_insert(&vers, ckinId); |
| 207 | db_bind_int(&q2, ":rid", ckinId); |
| 208 | db_step(&q2); |
| 209 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | |
| 219 | printf(" %s +0000\n", zSecondsSince1970); |
| 220 | if( zComment==0 ) zComment = "null comment"; |
| 221 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 222 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 223 | if( db_step(&q3) == SQLITE_ROW ){ |
| 224 | parent = db_column_int(&q3, 0); |
| 225 | |
| 226 | printf("from :%d\n", COMMITMARK(parent)); |
| 227 | db_prepare(&q4, |
| 228 | "SELECT pid FROM plink" |
| 229 | " WHERE cid=%d AND NOT isprim" |
| 230 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 231 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | |
| 233 | while( db_step(&q4)==SQLITE_ROW ){ |
| 234 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 235 | } |
| 236 | db_finalize(&q4); |
| 237 | }else{ |
| 238 | parent = 0; |
| 239 | printf("deleteall\n"); |
| 240 | } |
| 241 | |
| 242 | db_prepare(&q4, |
| 243 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 244 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 245 | " WHERE mlink.mid=%d", |
| 246 | parent |
| 247 | ); |
| 248 | while( db_step(&q4)==SQLITE_ROW ){ |
| 249 | const char *zName = db_column_text(&q4,0); |
| 250 | int zNew = db_column_int(&q4,1); |
| 251 | int mPerm = db_column_int(&q4,2); |
| 252 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -105,11 +105,11 @@ | |
| 105 | ** |
| 106 | ** If the "--export-marks FILE" option is used, the rid of all commits and |
| 107 | ** blobs written on exit for use with "--import-marks" on the next run. |
| 108 | */ |
| 109 | void export_cmd(void){ |
| 110 | Stmt q, q2, q3; |
| 111 | int i; |
| 112 | Bag blobs, vers; |
| 113 | const char *markfile_in; |
| 114 | const char *markfile_out; |
| 115 | |
| @@ -122,23 +122,23 @@ | |
| 122 | |
| 123 | db_find_and_open_repository(0, 2); |
| 124 | verify_all_options(); |
| 125 | if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); } |
| 126 | |
| 127 | db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)"); |
| 128 | db_multi_exec("CREATE TEMPORARY TABLE oldcommit(rid INTEGER PRIMARY KEY)"); |
| 129 | if( markfile_in!=0 ){ |
| 130 | Stmt qb,qc; |
| 131 | char line[100]; |
| 132 | FILE *f; |
| 133 | |
| 134 | f = fopen(markfile_in, "r"); |
| 135 | if( f==0 ){ |
| 136 | fossil_panic("cannot open %s for reading", markfile_in); |
| 137 | } |
| 138 | db_prepare(&qb, "INSERT OR IGNORE INTO oldblob VALUES (:rid)"); |
| 139 | db_prepare(&qc, "INSERT OR IGNORE INTO oldcommit VALUES (:rid)"); |
| 140 | while( fgets(line, sizeof(line), f)!=0 ){ |
| 141 | if( *line == 'b' ){ |
| 142 | db_bind_text(&qb, ":rid", line + 1); |
| 143 | db_step(&qb); |
| 144 | db_reset(&qb); |
| @@ -159,29 +159,53 @@ | |
| 159 | |
| 160 | /* Step 1: Generate "blob" records for every artifact that is part |
| 161 | ** of a check-in |
| 162 | */ |
| 163 | fossil_binary_mode(stdout); |
| 164 | db_multi_exec("CREATE TEMPORARY TABLE newblob(rid INTEGER KEY, srcid INTEGER)"); |
| 165 | db_multi_exec("CREATE INDEX newblob_src ON newblob(srcid)"); |
| 166 | db_multi_exec( |
| 167 | "INSERT INTO newblob" |
| 168 | " SELECT DISTINCT fid," |
| 169 | " CASE WHEN EXISTS(SELECT 1 FROM delta WHERE rid=fid AND NOT EXISTS(SELECT 1 FROM oldblob WHERE srcid=fid))" |
| 170 | " THEN (SELECT srcid FROM delta WHERE rid=fid)" |
| 171 | " ELSE 0" |
| 172 | " END" |
| 173 | " FROM mlink" |
| 174 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 175 | db_prepare(&q, |
| 176 | "SELECT DISTINCT fid FROM mlink" |
| 177 | " WHERE fid>0 AND NOT EXISTS(SELECT 1 FROM oldblob WHERE rid=fid)"); |
| 178 | db_prepare(&q2, "INSERT INTO oldblob VALUES (:rid)"); |
| 179 | db_prepare(&q3, "SELECT rid FROM newblob WHERE srcid= (:srcid)"); |
| 180 | while( db_step(&q)==SQLITE_ROW ){ |
| 181 | int rid = db_column_int(&q, 0); |
| 182 | Blob content; |
| 183 | |
| 184 | while( !bag_find(&blobs, rid) ){ |
| 185 | content_get(rid, &content); |
| 186 | db_bind_int(&q2, ":rid", rid); |
| 187 | db_step(&q2); |
| 188 | db_reset(&q2); |
| 189 | printf("blob\nmark :%d\ndata %d\n", BLOBMARK(rid), blob_size(&content)); |
| 190 | bag_insert(&blobs, rid); |
| 191 | fwrite(blob_buffer(&content), 1, blob_size(&content), stdout); |
| 192 | printf("\n"); |
| 193 | blob_reset(&content); |
| 194 | |
| 195 | db_bind_int(&q3, ":srcid", rid); |
| 196 | if( db_step(&q3) != SQLITE_ROW ){ |
| 197 | db_reset(&q3); |
| 198 | break; |
| 199 | } |
| 200 | rid = db_column_int(&q3, 0); |
| 201 | db_reset(&q3); |
| 202 | } |
| 203 | } |
| 204 | db_finalize(&q); |
| 205 | db_finalize(&q2); |
| 206 | db_finalize(&q3); |
| 207 | |
| 208 | /* Output the commit records. |
| 209 | */ |
| 210 | db_prepare(&q, |
| 211 | "SELECT strftime('%%s',mtime), objid, coalesce(comment,ecomment)," |
| @@ -192,18 +216,17 @@ | |
| 216 | " ORDER BY mtime ASC", |
| 217 | TAG_BRANCH |
| 218 | ); |
| 219 | db_prepare(&q2, "INSERT INTO oldcommit VALUES (:rid)"); |
| 220 | while( db_step(&q)==SQLITE_ROW ){ |
| 221 | Stmt q4; |
| 222 | const char *zSecondsSince1970 = db_column_text(&q, 0); |
| 223 | int ckinId = db_column_int(&q, 1); |
| 224 | const char *zComment = db_column_text(&q, 2); |
| 225 | const char *zUser = db_column_text(&q, 3); |
| 226 | const char *zBranch = db_column_text(&q, 4); |
| 227 | char *zBr; |
| 228 | |
| 229 | bag_insert(&vers, ckinId); |
| 230 | db_bind_int(&q2, ":rid", ckinId); |
| 231 | db_step(&q2); |
| 232 | db_reset(&q2); |
| @@ -219,13 +242,11 @@ | |
| 242 | printf(" %s +0000\n", zSecondsSince1970); |
| 243 | if( zComment==0 ) zComment = "null comment"; |
| 244 | printf("data %d\n%s\n", (int)strlen(zComment), zComment); |
| 245 | db_prepare(&q3, "SELECT pid FROM plink WHERE cid=%d AND isprim", ckinId); |
| 246 | if( db_step(&q3) == SQLITE_ROW ){ |
| 247 | printf("from :%d\n", COMMITMARK(db_column_int(&q3, 0))); |
| 248 | db_prepare(&q4, |
| 249 | "SELECT pid FROM plink" |
| 250 | " WHERE cid=%d AND NOT isprim" |
| 251 | " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=pid)" |
| 252 | " ORDER BY pid", |
| @@ -233,19 +254,18 @@ | |
| 254 | while( db_step(&q4)==SQLITE_ROW ){ |
| 255 | printf("merge :%d\n", COMMITMARK(db_column_int(&q4,0))); |
| 256 | } |
| 257 | db_finalize(&q4); |
| 258 | }else{ |
| 259 | printf("deleteall\n"); |
| 260 | } |
| 261 | |
| 262 | db_prepare(&q4, |
| 263 | "SELECT filename.name, mlink.fid, mlink.mperm FROM mlink" |
| 264 | " JOIN filename ON filename.fnid=mlink.fnid" |
| 265 | " WHERE mlink.mid=%d", |
| 266 | ckinId |
| 267 | ); |
| 268 | while( db_step(&q4)==SQLITE_ROW ){ |
| 269 | const char *zName = db_column_text(&q4,0); |
| 270 | int zNew = db_column_int(&q4,1); |
| 271 | int mPerm = db_column_int(&q4,2); |
| 272 |