Fossil SCM
Rename "fossil mirror" to "fossil git export". Deprecate the "fossil export" command.
Commit
2faec6b7481520a0b57ea315e6a80462506c539223c983a8487bbfda55935845
Parent
eafe5ce624349d9…
1 file changed
+86
-65
+86
-65
| --- src/export.c | ||
| +++ src/export.c | ||
| @@ -447,13 +447,13 @@ | ||
| 447 | 447 | }while( (rid = bag_next(vers, rid))!=0 ); |
| 448 | 448 | } |
| 449 | 449 | } |
| 450 | 450 | } |
| 451 | 451 | |
| 452 | -/* | |
| 453 | -** COMMAND: export | |
| 454 | -** | |
| 452 | +/* This is the original header command (and hence documentation) for | |
| 453 | +** the "fossil export" command: | |
| 454 | +** | |
| 455 | 455 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 456 | 456 | ** |
| 457 | 457 | ** Write an export of all check-ins to standard output. The export is |
| 458 | 458 | ** written in the git-fast-export file format assuming the --git option is |
| 459 | 459 | ** provided. The git-fast-export format is currently the only VCS |
| @@ -478,10 +478,15 @@ | ||
| 478 | 478 | ** --rename-trunk NAME use NAME as name of exported trunk branch |
| 479 | 479 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 480 | 480 | ** |
| 481 | 481 | ** See also: import |
| 482 | 482 | */ |
| 483 | +/* | |
| 484 | +** COMMAND: export* | |
| 485 | +** | |
| 486 | +** This command is deprecated. Use "fossil git export" instead. | |
| 487 | +*/ | |
| 483 | 488 | void export_cmd(void){ |
| 484 | 489 | Stmt q, q2, q3; |
| 485 | 490 | Bag blobs, vers; |
| 486 | 491 | unsigned int unused_mark = 1; |
| 487 | 492 | const char *markfile_in; |
| @@ -833,20 +838,20 @@ | ||
| 833 | 838 | n = topological_sort_checkins(1); |
| 834 | 839 | fossil_print("%d reorderings required\n", n); |
| 835 | 840 | } |
| 836 | 841 | |
| 837 | 842 | /*************************************************************************** |
| 838 | -** Implementation of the "fossil mirror" command follows. We hope that the | |
| 839 | -** new code that follows will largely replace the legacy "fossil export" code | |
| 840 | -** above. | |
| 843 | +** Implementation of the "fossil git" command follows. We hope that the | |
| 844 | +** new code that follows will largely replace the legacy "fossil export" | |
| 845 | +** and "fossil import" code above. | |
| 841 | 846 | */ |
| 842 | 847 | |
| 843 | 848 | /* |
| 844 | 849 | ** Convert characters of z[] that are not allowed to be in branch or |
| 845 | 850 | ** tag names into "_". |
| 846 | 851 | */ |
| 847 | -static void mirror_sanitize_git_name(char *z){ | |
| 852 | +static void gitmirror_sanitize_name(char *z){ | |
| 848 | 853 | static unsigned char aSafe[] = { |
| 849 | 854 | /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ |
| 850 | 855 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ |
| 851 | 856 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ |
| 852 | 857 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2x */ |
| @@ -875,11 +880,11 @@ | ||
| 875 | 880 | ** If quoting is not necessary, just return a copy of the input string. |
| 876 | 881 | ** |
| 877 | 882 | ** The return value is a held in memory obtained from fossil_malloc() |
| 878 | 883 | ** and must be freed by the caller. |
| 879 | 884 | */ |
| 880 | -static char *mirror_quote_filename_if_needed(const char *zIn){ | |
| 885 | +static char *gitmirror_quote_filename_if_needed(const char *zIn){ | |
| 881 | 886 | int i, j; |
| 882 | 887 | char c; |
| 883 | 888 | int nSpecial = 0; |
| 884 | 889 | char *zOut; |
| 885 | 890 | for(i=0; (c = zIn[i])!=0; i++){ |
| @@ -915,11 +920,11 @@ | ||
| 915 | 920 | ** |
| 916 | 921 | ** The Git tag mechanism is very limited compared to Fossil. Many Fossil |
| 917 | 922 | ** tags cannot be exported to Git. If this tag cannot be exported, then |
| 918 | 923 | ** silently ignore it. |
| 919 | 924 | */ |
| 920 | -static void mirror_send_tag(FILE *xCmd, int rid){ | |
| 925 | +static void gitmirror_send_tag(FILE *xCmd, int rid){ | |
| 921 | 926 | return; |
| 922 | 927 | } |
| 923 | 928 | |
| 924 | 929 | /* |
| 925 | 930 | ** Locate the mark for a UUID. |
| @@ -926,11 +931,11 @@ | ||
| 926 | 931 | ** |
| 927 | 932 | ** If the mark does not exist and if the bCreate flag is false, then |
| 928 | 933 | ** return 0. If the mark does not exist and the bCreate flag is true, |
| 929 | 934 | ** then create the mark. |
| 930 | 935 | */ |
| 931 | -static int mirror_find_mark(const char *zUuid, int bCreate){ | |
| 936 | +static int gitmirror_find_mark(const char *zUuid, int bCreate){ | |
| 932 | 937 | int iMark; |
| 933 | 938 | static Stmt sFind, sIns; |
| 934 | 939 | db_static_prepare(&sFind, |
| 935 | 940 | "SELECT id FROM mirror.mmark WHERE uuid=:uuid" |
| 936 | 941 | ); |
| @@ -956,11 +961,11 @@ | ||
| 956 | 961 | "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; |
| 957 | 962 | |
| 958 | 963 | /* |
| 959 | 964 | ** Export a single file named by zUuid. |
| 960 | 965 | */ |
| 961 | -static void mirror_send_file(FILE *xCmd, const char *zUuid){ | |
| 966 | +static void gitmirror_send_file(FILE *xCmd, const char *zUuid){ | |
| 962 | 967 | int iMark; |
| 963 | 968 | int rid; |
| 964 | 969 | int rc; |
| 965 | 970 | Blob data; |
| 966 | 971 | rid = fast_uuid_to_rid(zUuid); |
| @@ -971,11 +976,11 @@ | ||
| 971 | 976 | if( rc==0 ){ |
| 972 | 977 | blob_init(&data, 0, 0); |
| 973 | 978 | zUuid = zEmptySha3; |
| 974 | 979 | } |
| 975 | 980 | } |
| 976 | - iMark = mirror_find_mark(zUuid, 1); | |
| 981 | + iMark = gitmirror_find_mark(zUuid, 1); | |
| 977 | 982 | fprintf(xCmd, "blob\nmark :%d\ndata %d\n", iMark, blob_size(&data)); |
| 978 | 983 | fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd); |
| 979 | 984 | fprintf(xCmd, "\n"); |
| 980 | 985 | blob_reset(&data); |
| 981 | 986 | } |
| @@ -991,11 +996,11 @@ | ||
| 991 | 996 | ** Before sending the check-in, first make sure all associated files |
| 992 | 997 | ** have already been exported, and send "blob" records for any that |
| 993 | 998 | ** have not been. Update the MIRROR.MMARK table so that it holds the |
| 994 | 999 | ** marks for the exported files. |
| 995 | 1000 | */ |
| 996 | -static void mirror_send_checkin( | |
| 1001 | +static void gitmirror_send_checkin( | |
| 997 | 1002 | FILE *xCmd, /* Write fast-import text on this pipe */ |
| 998 | 1003 | int rid, /* BLOB.RID for the check-in to export */ |
| 999 | 1004 | const char *zUuid, /* BLOB.UUID for the check-in to export */ |
| 1000 | 1005 | int *pnLimit, /* Stop when the counter reaches zero */ |
| 1001 | 1006 | int fManifest /* MFESTFLG_* values */ |
| @@ -1017,15 +1022,15 @@ | ||
| 1017 | 1022 | } |
| 1018 | 1023 | |
| 1019 | 1024 | /* Check to see if any parent logins have not yet been processed, and |
| 1020 | 1025 | ** if so, create them */ |
| 1021 | 1026 | for(i=0; i<pMan->nParent; i++){ |
| 1022 | - int iMark = mirror_find_mark(pMan->azParent[i], 0); | |
| 1027 | + int iMark = gitmirror_find_mark(pMan->azParent[i], 0); | |
| 1023 | 1028 | if( iMark<=0 ){ |
| 1024 | 1029 | int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", |
| 1025 | 1030 | pMan->azParent[i]); |
| 1026 | - mirror_send_checkin(xCmd, prid, pMan->azParent[i], pnLimit, fManifest); | |
| 1031 | + gitmirror_send_checkin(xCmd, prid, pMan->azParent[i], pnLimit, fManifest); | |
| 1027 | 1032 | if( *pnLimit<=0 ){ |
| 1028 | 1033 | manifest_destroy(pMan); |
| 1029 | 1034 | return; |
| 1030 | 1035 | } |
| 1031 | 1036 | } |
| @@ -1037,11 +1042,11 @@ | ||
| 1037 | 1042 | " WHERE uuid NOT IN (SELECT uuid FROM mirror.mmark)", |
| 1038 | 1043 | zUuid |
| 1039 | 1044 | ); |
| 1040 | 1045 | while( db_step(&q)==SQLITE_ROW ){ |
| 1041 | 1046 | const char *zFUuid = db_column_text(&q, 0); |
| 1042 | - mirror_send_file(xCmd, zFUuid); | |
| 1047 | + gitmirror_send_file(xCmd, zFUuid); | |
| 1043 | 1048 | } |
| 1044 | 1049 | db_finalize(&q); |
| 1045 | 1050 | |
| 1046 | 1051 | /* Figure out which branch this check-in is a member of */ |
| 1047 | 1052 | zBranch = db_text(0, |
| @@ -1052,17 +1057,17 @@ | ||
| 1052 | 1057 | fossil_free(zBranch); |
| 1053 | 1058 | zBranch = mprintf("master"); |
| 1054 | 1059 | }else if( zBranch==0 ){ |
| 1055 | 1060 | zBranch = mprintf("unknown"); |
| 1056 | 1061 | }else{ |
| 1057 | - mirror_sanitize_git_name(zBranch); | |
| 1062 | + gitmirror_sanitize_name(zBranch); | |
| 1058 | 1063 | } |
| 1059 | 1064 | |
| 1060 | 1065 | /* Export the check-in */ |
| 1061 | 1066 | fprintf(xCmd, "commit refs/heads/%s\n", zBranch); |
| 1062 | 1067 | fossil_free(zBranch); |
| 1063 | - iMark = mirror_find_mark(zUuid, 1); | |
| 1068 | + iMark = gitmirror_find_mark(zUuid, 1); | |
| 1064 | 1069 | fprintf(xCmd, "mark :%d\n", iMark); |
| 1065 | 1070 | fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n", |
| 1066 | 1071 | pMan->zUser, pMan->zUser, |
| 1067 | 1072 | (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0) |
| 1068 | 1073 | ); |
| @@ -1069,11 +1074,11 @@ | ||
| 1069 | 1074 | zCom = pMan->zComment; |
| 1070 | 1075 | if( zCom==0 ) zCom = "(no comment)"; |
| 1071 | 1076 | fprintf(xCmd, "data %d\n%s\n", (int)strlen(zCom), zCom); |
| 1072 | 1077 | iParent = -1; /* Which ancestor is the primary parent */ |
| 1073 | 1078 | for(i=0; i<pMan->nParent; i++){ |
| 1074 | - int iOther = mirror_find_mark(pMan->azParent[i], 0); | |
| 1079 | + int iOther = gitmirror_find_mark(pMan->azParent[i], 0); | |
| 1075 | 1080 | if( iOther==0 ) continue; |
| 1076 | 1081 | if( iParent<0 ){ |
| 1077 | 1082 | iParent = i; |
| 1078 | 1083 | fprintf(xCmd, "from :%d\n", iOther); |
| 1079 | 1084 | }else{ |
| @@ -1115,11 +1120,11 @@ | ||
| 1115 | 1120 | char *zFNQuoted = 0; |
| 1116 | 1121 | if( zMode ){ |
| 1117 | 1122 | if( strchr(zMode,'x') ) zGitMode = "100755"; |
| 1118 | 1123 | if( strchr(zMode,'l') ) zGitMode = "120000"; |
| 1119 | 1124 | } |
| 1120 | - zFNQuoted = mirror_quote_filename_if_needed(zFilename); | |
| 1125 | + zFNQuoted = gitmirror_quote_filename_if_needed(zFilename); | |
| 1121 | 1126 | fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFNQuoted); |
| 1122 | 1127 | fossil_free(zFNQuoted); |
| 1123 | 1128 | } |
| 1124 | 1129 | db_finalize(&q); |
| 1125 | 1130 | |
| @@ -1147,51 +1152,13 @@ | ||
| 1147 | 1152 | /* The check-in is finished, so decrement the counter */ |
| 1148 | 1153 | (*pnLimit)--; |
| 1149 | 1154 | } |
| 1150 | 1155 | |
| 1151 | 1156 | /* |
| 1152 | -** COMMAND: mirror | |
| 1153 | -** | |
| 1154 | -** Usage: %fossil mirror [--git] MIRROR [-R FOSSIL-REPO] | |
| 1155 | -** | |
| 1156 | -** Create or update another type of repository that is is mirror of | |
| 1157 | -** a Fossil repository. | |
| 1158 | -** | |
| 1159 | -** The current implementation only supports mirrors to Git, and so | |
| 1160 | -** the --git option is optional. The ability to mirror to other version | |
| 1161 | -** control systems may be added in the future, in which case an argument | |
| 1162 | -** to specify the target version control system will become required. | |
| 1163 | -** | |
| 1164 | -** The MIRROR argument is the name of the secondary repository. In the | |
| 1165 | -** case of Git, it is the directory that houses the Git repository. | |
| 1166 | -** If MIRROR does not previously exist, it is created and initialized to | |
| 1167 | -** a copy of the Fossil repository. If MIRROR does already exist, it is | |
| 1168 | -** updated with new check-ins that have been added to the Fossil repository | |
| 1169 | -** since the last "fossil mirror" command to that particular repository. | |
| 1170 | -** | |
| 1171 | -** Implementation notes: | |
| 1172 | -** | |
| 1173 | -** * The git version control system must be installed in order for | |
| 1174 | -** this command to work. Fossil will invoke various git commands | |
| 1175 | -** to run as subprocesses. | |
| 1176 | -** | |
| 1177 | -** * Fossil creates a directory named ".mirror_state" in the top level of | |
| 1178 | -** the created git repository and stores state information in that | |
| 1179 | -** directory. Do not attempt to manage any files in that directory. | |
| 1180 | -** Do not change or delete any files in that directory. Doing so | |
| 1181 | -** may disrupt future calls to the "fossil mirror" command for the | |
| 1182 | -** mirror repository. | |
| 1183 | -** | |
| 1184 | -** Options: | |
| 1185 | -** | |
| 1186 | -** --debug FILE Write fast-export text to FILE rather than | |
| 1187 | -** piping it into "git fast-import". | |
| 1188 | -** | |
| 1189 | -** --limit N Add no more than N new check-ins to MIRROR. | |
| 1190 | -** Useful for debugging | |
| 1157 | +** Implementation of the "fossil git export" command. | |
| 1191 | 1158 | */ |
| 1192 | -void mirror_command(void){ | |
| 1159 | +void gitmirror_export_command(void){ | |
| 1193 | 1160 | const char *zLimit; /* Text of the --limit flag */ |
| 1194 | 1161 | int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */ |
| 1195 | 1162 | int nTotal = 0; /* Total number of check-ins to export */ |
| 1196 | 1163 | char *zMirror; /* Name of the mirror */ |
| 1197 | 1164 | char *z; /* Generic string */ |
| @@ -1203,21 +1170,20 @@ | ||
| 1203 | 1170 | FILE *xCmd; /* Pipe to the "git fast-import" command */ |
| 1204 | 1171 | FILE *pIn, *pOut; /* Git mark files */ |
| 1205 | 1172 | Stmt q; /* Queries */ |
| 1206 | 1173 | char zLine[200]; /* One line of a mark file */ |
| 1207 | 1174 | |
| 1208 | - find_option("git", 0, 0); /* Ignore the --git option for now */ | |
| 1209 | 1175 | zDebug = find_option("debug",0,1); |
| 1210 | 1176 | db_find_and_open_repository(0, 0); |
| 1211 | 1177 | zLimit = find_option("limit", 0, 1); |
| 1212 | 1178 | if( zLimit ){ |
| 1213 | 1179 | nLimit = (unsigned int)atoi(zLimit); |
| 1214 | 1180 | if( nLimit<=0 ) fossil_fatal("--limit must be positive"); |
| 1215 | 1181 | } |
| 1216 | 1182 | verify_all_options(); |
| 1217 | - if( g.argc!=3 ){ usage("--git MIRROR"); } | |
| 1218 | - zMirror = g.argv[2]; | |
| 1183 | + if( g.argc!=4 ){ usage("export MIRROR"); } | |
| 1184 | + zMirror = g.argv[3]; | |
| 1219 | 1185 | |
| 1220 | 1186 | /* Make sure the GIT repository directory exists */ |
| 1221 | 1187 | rc = file_mkdir(zMirror, ExtFILE, 0); |
| 1222 | 1188 | if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror); |
| 1223 | 1189 | |
| @@ -1321,13 +1287,13 @@ | ||
| 1321 | 1287 | const char *zType = db_column_text(&q, 1); |
| 1322 | 1288 | int rid = db_column_int(&q, 0); |
| 1323 | 1289 | const char *zUuid = db_column_text(&q, 3); |
| 1324 | 1290 | if( rMTime>rEnd ) rEnd = rMTime; |
| 1325 | 1291 | if( zType[0]=='t' ){ |
| 1326 | - mirror_send_tag(xCmd, rid); | |
| 1292 | + gitmirror_send_tag(xCmd, rid); | |
| 1327 | 1293 | }else{ |
| 1328 | - mirror_send_checkin(xCmd, rid, zUuid, &nLimit, fManifest); | |
| 1294 | + gitmirror_send_checkin(xCmd, rid, zUuid, &nLimit, fManifest); | |
| 1329 | 1295 | printf("\r%d/%d ", nTotal-nLimit, nTotal); |
| 1330 | 1296 | fflush(stdout); |
| 1331 | 1297 | } |
| 1332 | 1298 | } |
| 1333 | 1299 | db_finalize(&q); |
| @@ -1362,5 +1328,60 @@ | ||
| 1362 | 1328 | fossil_fatal("git fast-import didn't generate a marks file!"); |
| 1363 | 1329 | } |
| 1364 | 1330 | |
| 1365 | 1331 | /* Optionally do a "git push" */ |
| 1366 | 1332 | } |
| 1333 | + | |
| 1334 | +/* | |
| 1335 | +** COMMAND: git | |
| 1336 | +** | |
| 1337 | +** Usage: %fossil git SUBCOMMAND | |
| 1338 | +** | |
| 1339 | +** Do incremental import or export operations between Fossil and Git. | |
| 1340 | +** Subcommands: | |
| 1341 | +** | |
| 1342 | +** fossil git export MIRROR [OPTIONS] | |
| 1343 | +** | |
| 1344 | +** Write content from the Fossil repository into the Git repository | |
| 1345 | +** in directory MIRROR. The Git repository is created if it does not | |
| 1346 | +** already exist. If the Git repository does already exist, then | |
| 1347 | +** new content added to fossil since the previous export is appended. | |
| 1348 | +** | |
| 1349 | +** Repeat this command whenever new checkins are added to the Fossil | |
| 1350 | +** repository in order to reflect those changes into the mirror. | |
| 1351 | +** | |
| 1352 | +** The MIRROR directory will contain a subdirectory named | |
| 1353 | +** ".mirror_state" that contains information that Fossil needs to | |
| 1354 | +** do incremental exports. Do not attempt to manage or edit the files | |
| 1355 | +** in that directory since doing so can disrupt future incremental | |
| 1356 | +** exports. | |
| 1357 | +** | |
| 1358 | +** Options: | |
| 1359 | +** --debug FILE Write fast-export text to FILE rather than | |
| 1360 | +** piping it into "git fast-import". | |
| 1361 | +** --limit N Add no more than N new check-ins to MIRROR. | |
| 1362 | +** Useful for debugging | |
| 1363 | +** | |
| 1364 | +** fossil git import MIRROR | |
| 1365 | +** | |
| 1366 | +** TBD... | |
| 1367 | +*/ | |
| 1368 | +void gitmirror_command(void){ | |
| 1369 | + char *zCmd; | |
| 1370 | + int nCmd; | |
| 1371 | + if( g.argc<3 ){ | |
| 1372 | + usage("export ARGS..."); | |
| 1373 | + } | |
| 1374 | + zCmd = g.argv[2]; | |
| 1375 | + nCmd = (int)strlen(zCmd); | |
| 1376 | + if( nCmd>2 && strncmp(zCmd,"export",nCmd)==0 ){ | |
| 1377 | + gitmirror_export_command(); | |
| 1378 | + }else | |
| 1379 | + if( nCmd>2 && strncmp(zCmd,"import",nCmd)==0 ){ | |
| 1380 | + fossil_fatal("not yet implemented - check back later"); | |
| 1381 | + }else | |
| 1382 | + { | |
| 1383 | + fossil_fatal("unknown subcommand \"%s\": should be one of " | |
| 1384 | + "\"export\", \"import\"", | |
| 1385 | + zCmd); | |
| 1386 | + } | |
| 1387 | +} | |
| 1367 | 1388 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -447,13 +447,13 @@ | |
| 447 | }while( (rid = bag_next(vers, rid))!=0 ); |
| 448 | } |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | /* |
| 453 | ** COMMAND: export |
| 454 | ** |
| 455 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 456 | ** |
| 457 | ** Write an export of all check-ins to standard output. The export is |
| 458 | ** written in the git-fast-export file format assuming the --git option is |
| 459 | ** provided. The git-fast-export format is currently the only VCS |
| @@ -478,10 +478,15 @@ | |
| 478 | ** --rename-trunk NAME use NAME as name of exported trunk branch |
| 479 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 480 | ** |
| 481 | ** See also: import |
| 482 | */ |
| 483 | void export_cmd(void){ |
| 484 | Stmt q, q2, q3; |
| 485 | Bag blobs, vers; |
| 486 | unsigned int unused_mark = 1; |
| 487 | const char *markfile_in; |
| @@ -833,20 +838,20 @@ | |
| 833 | n = topological_sort_checkins(1); |
| 834 | fossil_print("%d reorderings required\n", n); |
| 835 | } |
| 836 | |
| 837 | /*************************************************************************** |
| 838 | ** Implementation of the "fossil mirror" command follows. We hope that the |
| 839 | ** new code that follows will largely replace the legacy "fossil export" code |
| 840 | ** above. |
| 841 | */ |
| 842 | |
| 843 | /* |
| 844 | ** Convert characters of z[] that are not allowed to be in branch or |
| 845 | ** tag names into "_". |
| 846 | */ |
| 847 | static void mirror_sanitize_git_name(char *z){ |
| 848 | static unsigned char aSafe[] = { |
| 849 | /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ |
| 850 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ |
| 851 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ |
| 852 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2x */ |
| @@ -875,11 +880,11 @@ | |
| 875 | ** If quoting is not necessary, just return a copy of the input string. |
| 876 | ** |
| 877 | ** The return value is a held in memory obtained from fossil_malloc() |
| 878 | ** and must be freed by the caller. |
| 879 | */ |
| 880 | static char *mirror_quote_filename_if_needed(const char *zIn){ |
| 881 | int i, j; |
| 882 | char c; |
| 883 | int nSpecial = 0; |
| 884 | char *zOut; |
| 885 | for(i=0; (c = zIn[i])!=0; i++){ |
| @@ -915,11 +920,11 @@ | |
| 915 | ** |
| 916 | ** The Git tag mechanism is very limited compared to Fossil. Many Fossil |
| 917 | ** tags cannot be exported to Git. If this tag cannot be exported, then |
| 918 | ** silently ignore it. |
| 919 | */ |
| 920 | static void mirror_send_tag(FILE *xCmd, int rid){ |
| 921 | return; |
| 922 | } |
| 923 | |
| 924 | /* |
| 925 | ** Locate the mark for a UUID. |
| @@ -926,11 +931,11 @@ | |
| 926 | ** |
| 927 | ** If the mark does not exist and if the bCreate flag is false, then |
| 928 | ** return 0. If the mark does not exist and the bCreate flag is true, |
| 929 | ** then create the mark. |
| 930 | */ |
| 931 | static int mirror_find_mark(const char *zUuid, int bCreate){ |
| 932 | int iMark; |
| 933 | static Stmt sFind, sIns; |
| 934 | db_static_prepare(&sFind, |
| 935 | "SELECT id FROM mirror.mmark WHERE uuid=:uuid" |
| 936 | ); |
| @@ -956,11 +961,11 @@ | |
| 956 | "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; |
| 957 | |
| 958 | /* |
| 959 | ** Export a single file named by zUuid. |
| 960 | */ |
| 961 | static void mirror_send_file(FILE *xCmd, const char *zUuid){ |
| 962 | int iMark; |
| 963 | int rid; |
| 964 | int rc; |
| 965 | Blob data; |
| 966 | rid = fast_uuid_to_rid(zUuid); |
| @@ -971,11 +976,11 @@ | |
| 971 | if( rc==0 ){ |
| 972 | blob_init(&data, 0, 0); |
| 973 | zUuid = zEmptySha3; |
| 974 | } |
| 975 | } |
| 976 | iMark = mirror_find_mark(zUuid, 1); |
| 977 | fprintf(xCmd, "blob\nmark :%d\ndata %d\n", iMark, blob_size(&data)); |
| 978 | fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd); |
| 979 | fprintf(xCmd, "\n"); |
| 980 | blob_reset(&data); |
| 981 | } |
| @@ -991,11 +996,11 @@ | |
| 991 | ** Before sending the check-in, first make sure all associated files |
| 992 | ** have already been exported, and send "blob" records for any that |
| 993 | ** have not been. Update the MIRROR.MMARK table so that it holds the |
| 994 | ** marks for the exported files. |
| 995 | */ |
| 996 | static void mirror_send_checkin( |
| 997 | FILE *xCmd, /* Write fast-import text on this pipe */ |
| 998 | int rid, /* BLOB.RID for the check-in to export */ |
| 999 | const char *zUuid, /* BLOB.UUID for the check-in to export */ |
| 1000 | int *pnLimit, /* Stop when the counter reaches zero */ |
| 1001 | int fManifest /* MFESTFLG_* values */ |
| @@ -1017,15 +1022,15 @@ | |
| 1017 | } |
| 1018 | |
| 1019 | /* Check to see if any parent logins have not yet been processed, and |
| 1020 | ** if so, create them */ |
| 1021 | for(i=0; i<pMan->nParent; i++){ |
| 1022 | int iMark = mirror_find_mark(pMan->azParent[i], 0); |
| 1023 | if( iMark<=0 ){ |
| 1024 | int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", |
| 1025 | pMan->azParent[i]); |
| 1026 | mirror_send_checkin(xCmd, prid, pMan->azParent[i], pnLimit, fManifest); |
| 1027 | if( *pnLimit<=0 ){ |
| 1028 | manifest_destroy(pMan); |
| 1029 | return; |
| 1030 | } |
| 1031 | } |
| @@ -1037,11 +1042,11 @@ | |
| 1037 | " WHERE uuid NOT IN (SELECT uuid FROM mirror.mmark)", |
| 1038 | zUuid |
| 1039 | ); |
| 1040 | while( db_step(&q)==SQLITE_ROW ){ |
| 1041 | const char *zFUuid = db_column_text(&q, 0); |
| 1042 | mirror_send_file(xCmd, zFUuid); |
| 1043 | } |
| 1044 | db_finalize(&q); |
| 1045 | |
| 1046 | /* Figure out which branch this check-in is a member of */ |
| 1047 | zBranch = db_text(0, |
| @@ -1052,17 +1057,17 @@ | |
| 1052 | fossil_free(zBranch); |
| 1053 | zBranch = mprintf("master"); |
| 1054 | }else if( zBranch==0 ){ |
| 1055 | zBranch = mprintf("unknown"); |
| 1056 | }else{ |
| 1057 | mirror_sanitize_git_name(zBranch); |
| 1058 | } |
| 1059 | |
| 1060 | /* Export the check-in */ |
| 1061 | fprintf(xCmd, "commit refs/heads/%s\n", zBranch); |
| 1062 | fossil_free(zBranch); |
| 1063 | iMark = mirror_find_mark(zUuid, 1); |
| 1064 | fprintf(xCmd, "mark :%d\n", iMark); |
| 1065 | fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n", |
| 1066 | pMan->zUser, pMan->zUser, |
| 1067 | (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0) |
| 1068 | ); |
| @@ -1069,11 +1074,11 @@ | |
| 1069 | zCom = pMan->zComment; |
| 1070 | if( zCom==0 ) zCom = "(no comment)"; |
| 1071 | fprintf(xCmd, "data %d\n%s\n", (int)strlen(zCom), zCom); |
| 1072 | iParent = -1; /* Which ancestor is the primary parent */ |
| 1073 | for(i=0; i<pMan->nParent; i++){ |
| 1074 | int iOther = mirror_find_mark(pMan->azParent[i], 0); |
| 1075 | if( iOther==0 ) continue; |
| 1076 | if( iParent<0 ){ |
| 1077 | iParent = i; |
| 1078 | fprintf(xCmd, "from :%d\n", iOther); |
| 1079 | }else{ |
| @@ -1115,11 +1120,11 @@ | |
| 1115 | char *zFNQuoted = 0; |
| 1116 | if( zMode ){ |
| 1117 | if( strchr(zMode,'x') ) zGitMode = "100755"; |
| 1118 | if( strchr(zMode,'l') ) zGitMode = "120000"; |
| 1119 | } |
| 1120 | zFNQuoted = mirror_quote_filename_if_needed(zFilename); |
| 1121 | fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFNQuoted); |
| 1122 | fossil_free(zFNQuoted); |
| 1123 | } |
| 1124 | db_finalize(&q); |
| 1125 | |
| @@ -1147,51 +1152,13 @@ | |
| 1147 | /* The check-in is finished, so decrement the counter */ |
| 1148 | (*pnLimit)--; |
| 1149 | } |
| 1150 | |
| 1151 | /* |
| 1152 | ** COMMAND: mirror |
| 1153 | ** |
| 1154 | ** Usage: %fossil mirror [--git] MIRROR [-R FOSSIL-REPO] |
| 1155 | ** |
| 1156 | ** Create or update another type of repository that is is mirror of |
| 1157 | ** a Fossil repository. |
| 1158 | ** |
| 1159 | ** The current implementation only supports mirrors to Git, and so |
| 1160 | ** the --git option is optional. The ability to mirror to other version |
| 1161 | ** control systems may be added in the future, in which case an argument |
| 1162 | ** to specify the target version control system will become required. |
| 1163 | ** |
| 1164 | ** The MIRROR argument is the name of the secondary repository. In the |
| 1165 | ** case of Git, it is the directory that houses the Git repository. |
| 1166 | ** If MIRROR does not previously exist, it is created and initialized to |
| 1167 | ** a copy of the Fossil repository. If MIRROR does already exist, it is |
| 1168 | ** updated with new check-ins that have been added to the Fossil repository |
| 1169 | ** since the last "fossil mirror" command to that particular repository. |
| 1170 | ** |
| 1171 | ** Implementation notes: |
| 1172 | ** |
| 1173 | ** * The git version control system must be installed in order for |
| 1174 | ** this command to work. Fossil will invoke various git commands |
| 1175 | ** to run as subprocesses. |
| 1176 | ** |
| 1177 | ** * Fossil creates a directory named ".mirror_state" in the top level of |
| 1178 | ** the created git repository and stores state information in that |
| 1179 | ** directory. Do not attempt to manage any files in that directory. |
| 1180 | ** Do not change or delete any files in that directory. Doing so |
| 1181 | ** may disrupt future calls to the "fossil mirror" command for the |
| 1182 | ** mirror repository. |
| 1183 | ** |
| 1184 | ** Options: |
| 1185 | ** |
| 1186 | ** --debug FILE Write fast-export text to FILE rather than |
| 1187 | ** piping it into "git fast-import". |
| 1188 | ** |
| 1189 | ** --limit N Add no more than N new check-ins to MIRROR. |
| 1190 | ** Useful for debugging |
| 1191 | */ |
| 1192 | void mirror_command(void){ |
| 1193 | const char *zLimit; /* Text of the --limit flag */ |
| 1194 | int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */ |
| 1195 | int nTotal = 0; /* Total number of check-ins to export */ |
| 1196 | char *zMirror; /* Name of the mirror */ |
| 1197 | char *z; /* Generic string */ |
| @@ -1203,21 +1170,20 @@ | |
| 1203 | FILE *xCmd; /* Pipe to the "git fast-import" command */ |
| 1204 | FILE *pIn, *pOut; /* Git mark files */ |
| 1205 | Stmt q; /* Queries */ |
| 1206 | char zLine[200]; /* One line of a mark file */ |
| 1207 | |
| 1208 | find_option("git", 0, 0); /* Ignore the --git option for now */ |
| 1209 | zDebug = find_option("debug",0,1); |
| 1210 | db_find_and_open_repository(0, 0); |
| 1211 | zLimit = find_option("limit", 0, 1); |
| 1212 | if( zLimit ){ |
| 1213 | nLimit = (unsigned int)atoi(zLimit); |
| 1214 | if( nLimit<=0 ) fossil_fatal("--limit must be positive"); |
| 1215 | } |
| 1216 | verify_all_options(); |
| 1217 | if( g.argc!=3 ){ usage("--git MIRROR"); } |
| 1218 | zMirror = g.argv[2]; |
| 1219 | |
| 1220 | /* Make sure the GIT repository directory exists */ |
| 1221 | rc = file_mkdir(zMirror, ExtFILE, 0); |
| 1222 | if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror); |
| 1223 | |
| @@ -1321,13 +1287,13 @@ | |
| 1321 | const char *zType = db_column_text(&q, 1); |
| 1322 | int rid = db_column_int(&q, 0); |
| 1323 | const char *zUuid = db_column_text(&q, 3); |
| 1324 | if( rMTime>rEnd ) rEnd = rMTime; |
| 1325 | if( zType[0]=='t' ){ |
| 1326 | mirror_send_tag(xCmd, rid); |
| 1327 | }else{ |
| 1328 | mirror_send_checkin(xCmd, rid, zUuid, &nLimit, fManifest); |
| 1329 | printf("\r%d/%d ", nTotal-nLimit, nTotal); |
| 1330 | fflush(stdout); |
| 1331 | } |
| 1332 | } |
| 1333 | db_finalize(&q); |
| @@ -1362,5 +1328,60 @@ | |
| 1362 | fossil_fatal("git fast-import didn't generate a marks file!"); |
| 1363 | } |
| 1364 | |
| 1365 | /* Optionally do a "git push" */ |
| 1366 | } |
| 1367 |
| --- src/export.c | |
| +++ src/export.c | |
| @@ -447,13 +447,13 @@ | |
| 447 | }while( (rid = bag_next(vers, rid))!=0 ); |
| 448 | } |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | /* This is the original header command (and hence documentation) for |
| 453 | ** the "fossil export" command: |
| 454 | ** |
| 455 | ** Usage: %fossil export --git ?OPTIONS? ?REPOSITORY? |
| 456 | ** |
| 457 | ** Write an export of all check-ins to standard output. The export is |
| 458 | ** written in the git-fast-export file format assuming the --git option is |
| 459 | ** provided. The git-fast-export format is currently the only VCS |
| @@ -478,10 +478,15 @@ | |
| 478 | ** --rename-trunk NAME use NAME as name of exported trunk branch |
| 479 | ** --repository|-R REPOSITORY export the given REPOSITORY |
| 480 | ** |
| 481 | ** See also: import |
| 482 | */ |
| 483 | /* |
| 484 | ** COMMAND: export* |
| 485 | ** |
| 486 | ** This command is deprecated. Use "fossil git export" instead. |
| 487 | */ |
| 488 | void export_cmd(void){ |
| 489 | Stmt q, q2, q3; |
| 490 | Bag blobs, vers; |
| 491 | unsigned int unused_mark = 1; |
| 492 | const char *markfile_in; |
| @@ -833,20 +838,20 @@ | |
| 838 | n = topological_sort_checkins(1); |
| 839 | fossil_print("%d reorderings required\n", n); |
| 840 | } |
| 841 | |
| 842 | /*************************************************************************** |
| 843 | ** Implementation of the "fossil git" command follows. We hope that the |
| 844 | ** new code that follows will largely replace the legacy "fossil export" |
| 845 | ** and "fossil import" code above. |
| 846 | */ |
| 847 | |
| 848 | /* |
| 849 | ** Convert characters of z[] that are not allowed to be in branch or |
| 850 | ** tag names into "_". |
| 851 | */ |
| 852 | static void gitmirror_sanitize_name(char *z){ |
| 853 | static unsigned char aSafe[] = { |
| 854 | /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ |
| 855 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ |
| 856 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ |
| 857 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2x */ |
| @@ -875,11 +880,11 @@ | |
| 880 | ** If quoting is not necessary, just return a copy of the input string. |
| 881 | ** |
| 882 | ** The return value is a held in memory obtained from fossil_malloc() |
| 883 | ** and must be freed by the caller. |
| 884 | */ |
| 885 | static char *gitmirror_quote_filename_if_needed(const char *zIn){ |
| 886 | int i, j; |
| 887 | char c; |
| 888 | int nSpecial = 0; |
| 889 | char *zOut; |
| 890 | for(i=0; (c = zIn[i])!=0; i++){ |
| @@ -915,11 +920,11 @@ | |
| 920 | ** |
| 921 | ** The Git tag mechanism is very limited compared to Fossil. Many Fossil |
| 922 | ** tags cannot be exported to Git. If this tag cannot be exported, then |
| 923 | ** silently ignore it. |
| 924 | */ |
| 925 | static void gitmirror_send_tag(FILE *xCmd, int rid){ |
| 926 | return; |
| 927 | } |
| 928 | |
| 929 | /* |
| 930 | ** Locate the mark for a UUID. |
| @@ -926,11 +931,11 @@ | |
| 931 | ** |
| 932 | ** If the mark does not exist and if the bCreate flag is false, then |
| 933 | ** return 0. If the mark does not exist and the bCreate flag is true, |
| 934 | ** then create the mark. |
| 935 | */ |
| 936 | static int gitmirror_find_mark(const char *zUuid, int bCreate){ |
| 937 | int iMark; |
| 938 | static Stmt sFind, sIns; |
| 939 | db_static_prepare(&sFind, |
| 940 | "SELECT id FROM mirror.mmark WHERE uuid=:uuid" |
| 941 | ); |
| @@ -956,11 +961,11 @@ | |
| 961 | "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"; |
| 962 | |
| 963 | /* |
| 964 | ** Export a single file named by zUuid. |
| 965 | */ |
| 966 | static void gitmirror_send_file(FILE *xCmd, const char *zUuid){ |
| 967 | int iMark; |
| 968 | int rid; |
| 969 | int rc; |
| 970 | Blob data; |
| 971 | rid = fast_uuid_to_rid(zUuid); |
| @@ -971,11 +976,11 @@ | |
| 976 | if( rc==0 ){ |
| 977 | blob_init(&data, 0, 0); |
| 978 | zUuid = zEmptySha3; |
| 979 | } |
| 980 | } |
| 981 | iMark = gitmirror_find_mark(zUuid, 1); |
| 982 | fprintf(xCmd, "blob\nmark :%d\ndata %d\n", iMark, blob_size(&data)); |
| 983 | fwrite(blob_buffer(&data), 1, blob_size(&data), xCmd); |
| 984 | fprintf(xCmd, "\n"); |
| 985 | blob_reset(&data); |
| 986 | } |
| @@ -991,11 +996,11 @@ | |
| 996 | ** Before sending the check-in, first make sure all associated files |
| 997 | ** have already been exported, and send "blob" records for any that |
| 998 | ** have not been. Update the MIRROR.MMARK table so that it holds the |
| 999 | ** marks for the exported files. |
| 1000 | */ |
| 1001 | static void gitmirror_send_checkin( |
| 1002 | FILE *xCmd, /* Write fast-import text on this pipe */ |
| 1003 | int rid, /* BLOB.RID for the check-in to export */ |
| 1004 | const char *zUuid, /* BLOB.UUID for the check-in to export */ |
| 1005 | int *pnLimit, /* Stop when the counter reaches zero */ |
| 1006 | int fManifest /* MFESTFLG_* values */ |
| @@ -1017,15 +1022,15 @@ | |
| 1022 | } |
| 1023 | |
| 1024 | /* Check to see if any parent logins have not yet been processed, and |
| 1025 | ** if so, create them */ |
| 1026 | for(i=0; i<pMan->nParent; i++){ |
| 1027 | int iMark = gitmirror_find_mark(pMan->azParent[i], 0); |
| 1028 | if( iMark<=0 ){ |
| 1029 | int prid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", |
| 1030 | pMan->azParent[i]); |
| 1031 | gitmirror_send_checkin(xCmd, prid, pMan->azParent[i], pnLimit, fManifest); |
| 1032 | if( *pnLimit<=0 ){ |
| 1033 | manifest_destroy(pMan); |
| 1034 | return; |
| 1035 | } |
| 1036 | } |
| @@ -1037,11 +1042,11 @@ | |
| 1042 | " WHERE uuid NOT IN (SELECT uuid FROM mirror.mmark)", |
| 1043 | zUuid |
| 1044 | ); |
| 1045 | while( db_step(&q)==SQLITE_ROW ){ |
| 1046 | const char *zFUuid = db_column_text(&q, 0); |
| 1047 | gitmirror_send_file(xCmd, zFUuid); |
| 1048 | } |
| 1049 | db_finalize(&q); |
| 1050 | |
| 1051 | /* Figure out which branch this check-in is a member of */ |
| 1052 | zBranch = db_text(0, |
| @@ -1052,17 +1057,17 @@ | |
| 1057 | fossil_free(zBranch); |
| 1058 | zBranch = mprintf("master"); |
| 1059 | }else if( zBranch==0 ){ |
| 1060 | zBranch = mprintf("unknown"); |
| 1061 | }else{ |
| 1062 | gitmirror_sanitize_name(zBranch); |
| 1063 | } |
| 1064 | |
| 1065 | /* Export the check-in */ |
| 1066 | fprintf(xCmd, "commit refs/heads/%s\n", zBranch); |
| 1067 | fossil_free(zBranch); |
| 1068 | iMark = gitmirror_find_mark(zUuid, 1); |
| 1069 | fprintf(xCmd, "mark :%d\n", iMark); |
| 1070 | fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n", |
| 1071 | pMan->zUser, pMan->zUser, |
| 1072 | (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0) |
| 1073 | ); |
| @@ -1069,11 +1074,11 @@ | |
| 1074 | zCom = pMan->zComment; |
| 1075 | if( zCom==0 ) zCom = "(no comment)"; |
| 1076 | fprintf(xCmd, "data %d\n%s\n", (int)strlen(zCom), zCom); |
| 1077 | iParent = -1; /* Which ancestor is the primary parent */ |
| 1078 | for(i=0; i<pMan->nParent; i++){ |
| 1079 | int iOther = gitmirror_find_mark(pMan->azParent[i], 0); |
| 1080 | if( iOther==0 ) continue; |
| 1081 | if( iParent<0 ){ |
| 1082 | iParent = i; |
| 1083 | fprintf(xCmd, "from :%d\n", iOther); |
| 1084 | }else{ |
| @@ -1115,11 +1120,11 @@ | |
| 1120 | char *zFNQuoted = 0; |
| 1121 | if( zMode ){ |
| 1122 | if( strchr(zMode,'x') ) zGitMode = "100755"; |
| 1123 | if( strchr(zMode,'l') ) zGitMode = "120000"; |
| 1124 | } |
| 1125 | zFNQuoted = gitmirror_quote_filename_if_needed(zFilename); |
| 1126 | fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFNQuoted); |
| 1127 | fossil_free(zFNQuoted); |
| 1128 | } |
| 1129 | db_finalize(&q); |
| 1130 | |
| @@ -1147,51 +1152,13 @@ | |
| 1152 | /* The check-in is finished, so decrement the counter */ |
| 1153 | (*pnLimit)--; |
| 1154 | } |
| 1155 | |
| 1156 | /* |
| 1157 | ** Implementation of the "fossil git export" command. |
| 1158 | */ |
| 1159 | void gitmirror_export_command(void){ |
| 1160 | const char *zLimit; /* Text of the --limit flag */ |
| 1161 | int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */ |
| 1162 | int nTotal = 0; /* Total number of check-ins to export */ |
| 1163 | char *zMirror; /* Name of the mirror */ |
| 1164 | char *z; /* Generic string */ |
| @@ -1203,21 +1170,20 @@ | |
| 1170 | FILE *xCmd; /* Pipe to the "git fast-import" command */ |
| 1171 | FILE *pIn, *pOut; /* Git mark files */ |
| 1172 | Stmt q; /* Queries */ |
| 1173 | char zLine[200]; /* One line of a mark file */ |
| 1174 | |
| 1175 | zDebug = find_option("debug",0,1); |
| 1176 | db_find_and_open_repository(0, 0); |
| 1177 | zLimit = find_option("limit", 0, 1); |
| 1178 | if( zLimit ){ |
| 1179 | nLimit = (unsigned int)atoi(zLimit); |
| 1180 | if( nLimit<=0 ) fossil_fatal("--limit must be positive"); |
| 1181 | } |
| 1182 | verify_all_options(); |
| 1183 | if( g.argc!=4 ){ usage("export MIRROR"); } |
| 1184 | zMirror = g.argv[3]; |
| 1185 | |
| 1186 | /* Make sure the GIT repository directory exists */ |
| 1187 | rc = file_mkdir(zMirror, ExtFILE, 0); |
| 1188 | if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror); |
| 1189 | |
| @@ -1321,13 +1287,13 @@ | |
| 1287 | const char *zType = db_column_text(&q, 1); |
| 1288 | int rid = db_column_int(&q, 0); |
| 1289 | const char *zUuid = db_column_text(&q, 3); |
| 1290 | if( rMTime>rEnd ) rEnd = rMTime; |
| 1291 | if( zType[0]=='t' ){ |
| 1292 | gitmirror_send_tag(xCmd, rid); |
| 1293 | }else{ |
| 1294 | gitmirror_send_checkin(xCmd, rid, zUuid, &nLimit, fManifest); |
| 1295 | printf("\r%d/%d ", nTotal-nLimit, nTotal); |
| 1296 | fflush(stdout); |
| 1297 | } |
| 1298 | } |
| 1299 | db_finalize(&q); |
| @@ -1362,5 +1328,60 @@ | |
| 1328 | fossil_fatal("git fast-import didn't generate a marks file!"); |
| 1329 | } |
| 1330 | |
| 1331 | /* Optionally do a "git push" */ |
| 1332 | } |
| 1333 | |
| 1334 | /* |
| 1335 | ** COMMAND: git |
| 1336 | ** |
| 1337 | ** Usage: %fossil git SUBCOMMAND |
| 1338 | ** |
| 1339 | ** Do incremental import or export operations between Fossil and Git. |
| 1340 | ** Subcommands: |
| 1341 | ** |
| 1342 | ** fossil git export MIRROR [OPTIONS] |
| 1343 | ** |
| 1344 | ** Write content from the Fossil repository into the Git repository |
| 1345 | ** in directory MIRROR. The Git repository is created if it does not |
| 1346 | ** already exist. If the Git repository does already exist, then |
| 1347 | ** new content added to fossil since the previous export is appended. |
| 1348 | ** |
| 1349 | ** Repeat this command whenever new checkins are added to the Fossil |
| 1350 | ** repository in order to reflect those changes into the mirror. |
| 1351 | ** |
| 1352 | ** The MIRROR directory will contain a subdirectory named |
| 1353 | ** ".mirror_state" that contains information that Fossil needs to |
| 1354 | ** do incremental exports. Do not attempt to manage or edit the files |
| 1355 | ** in that directory since doing so can disrupt future incremental |
| 1356 | ** exports. |
| 1357 | ** |
| 1358 | ** Options: |
| 1359 | ** --debug FILE Write fast-export text to FILE rather than |
| 1360 | ** piping it into "git fast-import". |
| 1361 | ** --limit N Add no more than N new check-ins to MIRROR. |
| 1362 | ** Useful for debugging |
| 1363 | ** |
| 1364 | ** fossil git import MIRROR |
| 1365 | ** |
| 1366 | ** TBD... |
| 1367 | */ |
| 1368 | void gitmirror_command(void){ |
| 1369 | char *zCmd; |
| 1370 | int nCmd; |
| 1371 | if( g.argc<3 ){ |
| 1372 | usage("export ARGS..."); |
| 1373 | } |
| 1374 | zCmd = g.argv[2]; |
| 1375 | nCmd = (int)strlen(zCmd); |
| 1376 | if( nCmd>2 && strncmp(zCmd,"export",nCmd)==0 ){ |
| 1377 | gitmirror_export_command(); |
| 1378 | }else |
| 1379 | if( nCmd>2 && strncmp(zCmd,"import",nCmd)==0 ){ |
| 1380 | fossil_fatal("not yet implemented - check back later"); |
| 1381 | }else |
| 1382 | { |
| 1383 | fossil_fatal("unknown subcommand \"%s\": should be one of " |
| 1384 | "\"export\", \"import\"", |
| 1385 | zCmd); |
| 1386 | } |
| 1387 | } |
| 1388 |