Fossil SCM

Options to set trunk/branches/tags folder names and project repository root (filter). Various fixes

baruch 2014-11-02 13:59 svn-import
Commit f67cb93fa6612082c6bb4a901d38500bf2df7b8a
1 file changed +84 -34
+84 -34
--- src/import.c
+++ src/import.c
@@ -725,10 +725,17 @@
725725
char *zBranch; /* Name of a branch for a commit */
726726
char *zDate; /* Date/time stamp */
727727
char *zUser; /* User name */
728728
char *zComment; /* Comment of a commit */
729729
int flatFlag; /* True if whole repo is a single file tree */
730
+ const char *zTrunk; /* Name of trunk folder in repo root */
731
+ int lenTrunk; /* String length of zTrunk */
732
+ const char *zBranches; /* Name of branches folder in repo root */
733
+ int lenBranches; /* String length of zBranches */
734
+ const char *zTags; /* Name of tags folder in repo root */
735
+ int lenTags; /* String length of zTags */
736
+ Blob filter; /* Path to repo root */
730737
} gsvn;
731738
typedef struct {
732739
const char *zKey;
733740
const char *zVal;
734741
} KeyVal;
@@ -896,11 +903,11 @@
896903
Blob manifest;
897904
static Stmt insRev;
898905
static Stmt qParent;
899906
static Stmt qFiles;
900907
static Stmt qTags;
901
- char zFilter[200];
908
+ int nBaseFilter;
902909
int nFilter;
903910
int rid;
904911
const char *zParentBranch = 0;
905912
Blob mcksum;
906913
@@ -910,13 +917,11 @@
910917
db_static_prepare(&qParent, "SELECT tuuid, tbranch FROM xrevisions "
911918
"WHERE trev=:rev");
912919
db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles "
913920
"WHERE tpath GLOB :filter ORDER BY tpath");
914921
db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev");
915
- if( db_int(0, "SELECT 1 FROM xfiles LIMIT 1")==0 ){ return; }
916922
if( !gsvn.flatFlag ){
917
- if( gsvn.zBranch==0 || gsvn.zBranch[0]=='\0' ){ return; }
918923
if( gsvn.parent<0 ){
919924
gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions "
920925
"WHERE tbranch=%Q", gsvn.zBranch);
921926
}
922927
db_bind_int(&insRev, ":rev", gsvn.rev);
@@ -934,27 +939,28 @@
934939
blob_appendf(&manifest, "C %F\n", gsvn.zComment);
935940
}else{
936941
blob_append(&manifest, "C (no\\scomment)\n", 16);
937942
}
938943
blob_appendf(&manifest, "D %s\n", gsvn.zDate);
939
- if( strncmp(gsvn.zBranch, "trunk", 5)==0 ){
940
- memcpy(zFilter, "trunk/*", 8);
941
- nFilter = 6;
944
+ nBaseFilter = blob_size(&gsvn.filter);
945
+ if( strcmp(gsvn.zBranch, gsvn.zTrunk)==0 ){
946
+ blob_appendf(&gsvn.filter, "%s*", gsvn.zTrunk);
942947
}else{
943
- sqlite3_snprintf(sizeof(zFilter), zFilter, "branches/%s/*", gsvn.zBranch);
944
- nFilter = strlen(zFilter)-1;
948
+ blob_appendf(&gsvn.filter, "%s%s/*", gsvn.zBranches, gsvn.zBranch);
945949
}
946
- db_bind_text(&qFiles, ":filter", zFilter);
950
+ db_bind_text(&qFiles, ":filter", blob_str(&gsvn.filter));
951
+ nFilter = blob_size(&gsvn.filter);
947952
while( db_step(&qFiles)==SQLITE_ROW ){
948953
const char *zFile = db_column_text(&qFiles, 0);
949954
int rid = db_column_int(&qFiles, 1);
950955
const char *zPerm = db_column_text(&qFiles, 2);
951956
const char *zUuid;
952957
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
953958
blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm);
954959
fossil_free(zUuid);
955960
}
961
+ blob_resize(&gsvn.filter, nBaseFilter);
956962
if( gsvn.parent>=0 ){
957963
const char *zParentUuid;
958964
db_bind_int(&qParent, ":rev", gsvn.parent);
959965
db_step(&qParent);
960966
zParentUuid = db_column_text(&qParent, 0);
@@ -1016,11 +1022,11 @@
10161022
}
10171023
zDiff += 4;
10181024
blob_zero(pOut);
10191025
while( zDiff<(blob_buffer(pDiff)+blob_size(pDiff)) ){
10201026
u64 offSrc = svn_get_varint(&zDiff);
1021
- u64 lenSrc = svn_get_varint(&zDiff);
1027
+ /*u64 lenSrc =*/ svn_get_varint(&zDiff);
10221028
u64 lenOut = svn_get_varint(&zDiff);
10231029
u64 lenInst = svn_get_varint(&zDiff);
10241030
u64 lenData = svn_get_varint(&zDiff);
10251031
const char *zInst = zDiff;
10261032
const char *zData = zInst+lenInst;
@@ -1063,10 +1069,11 @@
10631069
const char *zTemp;
10641070
const char *zUuid;
10651071
Stmt addHist;
10661072
Stmt insTag;
10671073
Stmt cpyPath;
1074
+ int bHasFiles;
10681075
10691076
/* version */
10701077
if( svn_read_rec(pIn, &rec)
10711078
&& (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){
10721079
ver = atoi(zTemp);
@@ -1099,11 +1106,11 @@
10991106
);
11001107
gsvn.rev = -1;
11011108
while( svn_read_rec(pIn, &rec) ){
11021109
if( (zTemp = svn_find_header(rec, "Revision-number")) ){ /* revision node */
11031110
/* finish previous revision */
1104
- if( gsvn.rev>=0 ){
1111
+ if( bHasFiles ){
11051112
svn_create_manifest();
11061113
fossil_free(gsvn.zUser);
11071114
fossil_free(gsvn.zComment);
11081115
fossil_free(gsvn.zDate);
11091116
fossil_free(gsvn.zBranch);
@@ -1113,10 +1120,11 @@
11131120
gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author"));
11141121
gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log"));
11151122
gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date"));
11161123
gsvn.parent = -1;
11171124
gsvn.zBranch = 0;
1125
+ bHasFiles = 0;
11181126
fossil_print("\rImporting SVN revision: %d", gsvn.rev);
11191127
db_bind_int(&addHist, ":rev", gsvn.rev);
11201128
db_bind_int(&cpyPath, ":rev", gsvn.rev);
11211129
}else
11221130
if( (zTemp = svn_find_header(rec, "Node-path")) ){ /* file/dir node */
@@ -1137,27 +1145,38 @@
11371145
}else{
11381146
fossil_fatal("Missing copyfrom-rev");
11391147
}
11401148
}
11411149
if( !gsvn.flatFlag ){
1142
- if( strncmp(zPath, "branches/", 9)==0 ){
1143
- int nBranch;
1144
- zTemp = zPath+9;
1150
+ if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){
1151
+ int lenBranch;
1152
+ zTemp = zPath+gsvn.lenBranches;
11451153
while( *zTemp && *zTemp!='/' ){ zTemp++; }
1146
- nBranch = zTemp-zPath+9;
1147
- gsvn.zBranch = fossil_malloc(nBranch+1);
1148
- memcpy(gsvn.zBranch, zPath+9, nBranch);
1149
- gsvn.zBranch[nBranch] = '\0';
1150
- }else
1151
- if( strncmp(zPath, "trunk/", 6)==0 ){
1152
- gsvn.zBranch = mprintf("trunk");
1153
- }else
1154
- if( strncmp(zPath, "tags/", 5)!=0
1155
- && strcmp(zPath, "branches")!=0
1156
- && strcmp(zPath, "trunk")!=0
1157
- && strcmp(zPath, "tags")!=0){
1158
- fossil_fatal("Write outside repository layout: %s", zPath);
1154
+ lenBranch = zTemp-zPath-gsvn.lenBranches;
1155
+ zTemp = zPath+gsvn.lenBranches;
1156
+ if( gsvn.zBranch!=0 ){
1157
+ if( strncmp(zTemp, gsvn.zBranch, lenBranch)!=0 ){
1158
+ fossil_fatal("Commit to multiple branches");
1159
+ }
1160
+ }else{
1161
+ gsvn.zBranch = fossil_malloc(lenBranch+1);
1162
+ memcpy(gsvn.zBranch, zTemp, lenBranch);
1163
+ gsvn.zBranch[lenBranch] = '\0';
1164
+ bHasFiles = 1;
1165
+ }
1166
+ }else
1167
+ if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk)==0 ){
1168
+ if( gsvn.zBranch!=0 ){
1169
+ if( strncmp(gsvn.zTrunk, gsvn.zBranch, gsvn.lenTrunk-1)!=0 ){
1170
+ fossil_fatal("Commit to multiple branches");
1171
+ }
1172
+ }else{
1173
+ gsvn.zBranch = fossil_malloc(gsvn.lenTrunk);
1174
+ memcpy(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1);
1175
+ gsvn.zBranch[gsvn.lenTrunk-1] = '\0';
1176
+ bHasFiles = 1;
1177
+ }
11591178
}
11601179
}
11611180
if( strncmp(zAction, "delete", 6)==0
11621181
|| strncmp(zAction, "replace", 7)==0 )
11631182
{
@@ -1178,17 +1197,17 @@
11781197
db_bind_text(&cpyPath, ":path", zPath);
11791198
db_bind_text(&cpyPath, ":srcpath", zSrcPath);
11801199
db_step(&cpyPath);
11811200
db_reset(&cpyPath);
11821201
if( !gsvn.flatFlag ){
1183
- if( strncmp(zPath, "branches/", 9)==0 ){
1184
- zTemp = zPath+9+strlen(gsvn.zBranch);
1202
+ if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){
1203
+ zTemp = zPath+gsvn.lenBranches+strlen(gsvn.zBranch);
11851204
if( *zTemp==0 ){
11861205
gsvn.parent = srcRev;
11871206
}
1188
- }else if( strncmp(zPath, "tags/", 5)==0 ){
1189
- zTemp = zPath+5;
1207
+ }else if( strncmp(zPath, gsvn.zTags, gsvn.lenTags)==0 ){
1208
+ zTemp = zPath+gsvn.lenTags;
11901209
db_bind_int(&insTag, ":rev", srcRev);
11911210
db_bind_text(&insTag, ":tag", zTemp);
11921211
db_step(&insTag);
11931212
db_reset(&insTag);
11941213
}
@@ -1278,14 +1297,20 @@
12781297
**
12791298
** The following formats are currently understood by this command
12801299
**
12811300
** git Import from the git-fast-export file format
12821301
**
1283
-** svn Import from the svnadmin-dump file format
1302
+** svn Import from the svnadmin-dump file format. The default
1303
+** behaviour is to treat 3 folders in the SVN root as special,
1304
+** following the common layout of SVN repositories. These are
1305
+** (by default) trunk/, branches/ and tags/
12841306
** Options:
1285
-** --flat The whole dump is a single branch. The default
1286
-** is to use the trunk/branches/tags svn layout
1307
+** --trunk FOLDER Name of trunk folder
1308
+** --branches FOLDER Name of branches folder
1309
+** --tags FOLDER Name of tags folder
1310
+** --fiter PATH Path to project root in repository
1311
+** --flat The whole dump is a single branch
12871312
**
12881313
** The --incremental option allows an existing repository to be extended
12891314
** with new content.
12901315
**
12911316
** Options:
@@ -1295,12 +1320,16 @@
12951320
*/
12961321
void import_cmd(void){
12971322
char *zPassword;
12981323
FILE *pIn;
12991324
Stmt q;
1325
+ const char *zFilter = find_option("filter", 0, 1);
13001326
int forceFlag = find_option("force", "f", 0)!=0;
13011327
int incrFlag = find_option("incremental", "i", 0)!=0;
1328
+ gsvn.zTrunk = find_option("trunk", 0, 1);
1329
+ gsvn.zBranches = find_option("branches", 0, 1);
1330
+ gsvn.zTags = find_option("tags", 0, 1);
13021331
gsvn.flatFlag = find_option("flat", 0, 0)!=0;
13031332
13041333
verify_all_options();
13051334
if( g.argc!=4 && g.argc!=5 ){
13061335
usage("FORMAT REPOSITORY-NAME");
@@ -1378,10 +1407,31 @@
13781407
" VALUES(new.tpath, new.trid, new.tperm); END;"
13791408
"CREATE TEMP TABLE xtags("
13801409
" trev INT, ttag TEXT"
13811410
");"
13821411
);
1412
+ if( gsvn.zTrunk==0 ){ gsvn.zTrunk = "trunk/"; }
1413
+ if( gsvn.zBranches==0 ){ gsvn.zBranches = "branches/"; }
1414
+ if( gsvn.zTags==0 ){ gsvn.zTags = "tags/"; }
1415
+ gsvn.lenTrunk = strlen(gsvn.zTrunk);
1416
+ gsvn.lenBranches = strlen(gsvn.zBranches);
1417
+ gsvn.lenTags = strlen(gsvn.zTags);
1418
+ if( gsvn.zTrunk[gsvn.lenTrunk-1]!='/' ){
1419
+ gsvn.zTrunk = mprintf("%s/", gsvn.zTrunk);
1420
+ gsvn.lenTrunk++;
1421
+ }
1422
+ if( gsvn.zBranches[gsvn.lenBranches-1]!='/' ){
1423
+ gsvn.zBranches = mprintf("%s/", gsvn.zBranches);
1424
+ gsvn.lenBranches++;
1425
+ }
1426
+ if( gsvn.zTags[gsvn.lenTags-1]!='/' ){
1427
+ gsvn.zTags = mprintf("%s/", gsvn.zTags);
1428
+ gsvn.lenTags++;
1429
+ }
1430
+ if( zFilter==0 ){ zFilter = ""; }
1431
+ blob_zero(&gsvn.filter);
1432
+ blob_set(&gsvn.filter, zFilter);
13831433
svn_dump_import(pIn);
13841434
}
13851435
13861436
verify_cancel();
13871437
db_end_transaction(0);
13881438
--- src/import.c
+++ src/import.c
@@ -725,10 +725,17 @@
725 char *zBranch; /* Name of a branch for a commit */
726 char *zDate; /* Date/time stamp */
727 char *zUser; /* User name */
728 char *zComment; /* Comment of a commit */
729 int flatFlag; /* True if whole repo is a single file tree */
 
 
 
 
 
 
 
730 } gsvn;
731 typedef struct {
732 const char *zKey;
733 const char *zVal;
734 } KeyVal;
@@ -896,11 +903,11 @@
896 Blob manifest;
897 static Stmt insRev;
898 static Stmt qParent;
899 static Stmt qFiles;
900 static Stmt qTags;
901 char zFilter[200];
902 int nFilter;
903 int rid;
904 const char *zParentBranch = 0;
905 Blob mcksum;
906
@@ -910,13 +917,11 @@
910 db_static_prepare(&qParent, "SELECT tuuid, tbranch FROM xrevisions "
911 "WHERE trev=:rev");
912 db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles "
913 "WHERE tpath GLOB :filter ORDER BY tpath");
914 db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev");
915 if( db_int(0, "SELECT 1 FROM xfiles LIMIT 1")==0 ){ return; }
916 if( !gsvn.flatFlag ){
917 if( gsvn.zBranch==0 || gsvn.zBranch[0]=='\0' ){ return; }
918 if( gsvn.parent<0 ){
919 gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions "
920 "WHERE tbranch=%Q", gsvn.zBranch);
921 }
922 db_bind_int(&insRev, ":rev", gsvn.rev);
@@ -934,27 +939,28 @@
934 blob_appendf(&manifest, "C %F\n", gsvn.zComment);
935 }else{
936 blob_append(&manifest, "C (no\\scomment)\n", 16);
937 }
938 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
939 if( strncmp(gsvn.zBranch, "trunk", 5)==0 ){
940 memcpy(zFilter, "trunk/*", 8);
941 nFilter = 6;
942 }else{
943 sqlite3_snprintf(sizeof(zFilter), zFilter, "branches/%s/*", gsvn.zBranch);
944 nFilter = strlen(zFilter)-1;
945 }
946 db_bind_text(&qFiles, ":filter", zFilter);
 
947 while( db_step(&qFiles)==SQLITE_ROW ){
948 const char *zFile = db_column_text(&qFiles, 0);
949 int rid = db_column_int(&qFiles, 1);
950 const char *zPerm = db_column_text(&qFiles, 2);
951 const char *zUuid;
952 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
953 blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm);
954 fossil_free(zUuid);
955 }
 
956 if( gsvn.parent>=0 ){
957 const char *zParentUuid;
958 db_bind_int(&qParent, ":rev", gsvn.parent);
959 db_step(&qParent);
960 zParentUuid = db_column_text(&qParent, 0);
@@ -1016,11 +1022,11 @@
1016 }
1017 zDiff += 4;
1018 blob_zero(pOut);
1019 while( zDiff<(blob_buffer(pDiff)+blob_size(pDiff)) ){
1020 u64 offSrc = svn_get_varint(&zDiff);
1021 u64 lenSrc = svn_get_varint(&zDiff);
1022 u64 lenOut = svn_get_varint(&zDiff);
1023 u64 lenInst = svn_get_varint(&zDiff);
1024 u64 lenData = svn_get_varint(&zDiff);
1025 const char *zInst = zDiff;
1026 const char *zData = zInst+lenInst;
@@ -1063,10 +1069,11 @@
1063 const char *zTemp;
1064 const char *zUuid;
1065 Stmt addHist;
1066 Stmt insTag;
1067 Stmt cpyPath;
 
1068
1069 /* version */
1070 if( svn_read_rec(pIn, &rec)
1071 && (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){
1072 ver = atoi(zTemp);
@@ -1099,11 +1106,11 @@
1099 );
1100 gsvn.rev = -1;
1101 while( svn_read_rec(pIn, &rec) ){
1102 if( (zTemp = svn_find_header(rec, "Revision-number")) ){ /* revision node */
1103 /* finish previous revision */
1104 if( gsvn.rev>=0 ){
1105 svn_create_manifest();
1106 fossil_free(gsvn.zUser);
1107 fossil_free(gsvn.zComment);
1108 fossil_free(gsvn.zDate);
1109 fossil_free(gsvn.zBranch);
@@ -1113,10 +1120,11 @@
1113 gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author"));
1114 gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log"));
1115 gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date"));
1116 gsvn.parent = -1;
1117 gsvn.zBranch = 0;
 
1118 fossil_print("\rImporting SVN revision: %d", gsvn.rev);
1119 db_bind_int(&addHist, ":rev", gsvn.rev);
1120 db_bind_int(&cpyPath, ":rev", gsvn.rev);
1121 }else
1122 if( (zTemp = svn_find_header(rec, "Node-path")) ){ /* file/dir node */
@@ -1137,27 +1145,38 @@
1137 }else{
1138 fossil_fatal("Missing copyfrom-rev");
1139 }
1140 }
1141 if( !gsvn.flatFlag ){
1142 if( strncmp(zPath, "branches/", 9)==0 ){
1143 int nBranch;
1144 zTemp = zPath+9;
1145 while( *zTemp && *zTemp!='/' ){ zTemp++; }
1146 nBranch = zTemp-zPath+9;
1147 gsvn.zBranch = fossil_malloc(nBranch+1);
1148 memcpy(gsvn.zBranch, zPath+9, nBranch);
1149 gsvn.zBranch[nBranch] = '\0';
1150 }else
1151 if( strncmp(zPath, "trunk/", 6)==0 ){
1152 gsvn.zBranch = mprintf("trunk");
1153 }else
1154 if( strncmp(zPath, "tags/", 5)!=0
1155 && strcmp(zPath, "branches")!=0
1156 && strcmp(zPath, "trunk")!=0
1157 && strcmp(zPath, "tags")!=0){
1158 fossil_fatal("Write outside repository layout: %s", zPath);
 
 
 
 
 
 
 
 
 
 
 
1159 }
1160 }
1161 if( strncmp(zAction, "delete", 6)==0
1162 || strncmp(zAction, "replace", 7)==0 )
1163 {
@@ -1178,17 +1197,17 @@
1178 db_bind_text(&cpyPath, ":path", zPath);
1179 db_bind_text(&cpyPath, ":srcpath", zSrcPath);
1180 db_step(&cpyPath);
1181 db_reset(&cpyPath);
1182 if( !gsvn.flatFlag ){
1183 if( strncmp(zPath, "branches/", 9)==0 ){
1184 zTemp = zPath+9+strlen(gsvn.zBranch);
1185 if( *zTemp==0 ){
1186 gsvn.parent = srcRev;
1187 }
1188 }else if( strncmp(zPath, "tags/", 5)==0 ){
1189 zTemp = zPath+5;
1190 db_bind_int(&insTag, ":rev", srcRev);
1191 db_bind_text(&insTag, ":tag", zTemp);
1192 db_step(&insTag);
1193 db_reset(&insTag);
1194 }
@@ -1278,14 +1297,20 @@
1278 **
1279 ** The following formats are currently understood by this command
1280 **
1281 ** git Import from the git-fast-export file format
1282 **
1283 ** svn Import from the svnadmin-dump file format
 
 
 
1284 ** Options:
1285 ** --flat The whole dump is a single branch. The default
1286 ** is to use the trunk/branches/tags svn layout
 
 
 
1287 **
1288 ** The --incremental option allows an existing repository to be extended
1289 ** with new content.
1290 **
1291 ** Options:
@@ -1295,12 +1320,16 @@
1295 */
1296 void import_cmd(void){
1297 char *zPassword;
1298 FILE *pIn;
1299 Stmt q;
 
1300 int forceFlag = find_option("force", "f", 0)!=0;
1301 int incrFlag = find_option("incremental", "i", 0)!=0;
 
 
 
1302 gsvn.flatFlag = find_option("flat", 0, 0)!=0;
1303
1304 verify_all_options();
1305 if( g.argc!=4 && g.argc!=5 ){
1306 usage("FORMAT REPOSITORY-NAME");
@@ -1378,10 +1407,31 @@
1378 " VALUES(new.tpath, new.trid, new.tperm); END;"
1379 "CREATE TEMP TABLE xtags("
1380 " trev INT, ttag TEXT"
1381 ");"
1382 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1383 svn_dump_import(pIn);
1384 }
1385
1386 verify_cancel();
1387 db_end_transaction(0);
1388
--- src/import.c
+++ src/import.c
@@ -725,10 +725,17 @@
725 char *zBranch; /* Name of a branch for a commit */
726 char *zDate; /* Date/time stamp */
727 char *zUser; /* User name */
728 char *zComment; /* Comment of a commit */
729 int flatFlag; /* True if whole repo is a single file tree */
730 const char *zTrunk; /* Name of trunk folder in repo root */
731 int lenTrunk; /* String length of zTrunk */
732 const char *zBranches; /* Name of branches folder in repo root */
733 int lenBranches; /* String length of zBranches */
734 const char *zTags; /* Name of tags folder in repo root */
735 int lenTags; /* String length of zTags */
736 Blob filter; /* Path to repo root */
737 } gsvn;
738 typedef struct {
739 const char *zKey;
740 const char *zVal;
741 } KeyVal;
@@ -896,11 +903,11 @@
903 Blob manifest;
904 static Stmt insRev;
905 static Stmt qParent;
906 static Stmt qFiles;
907 static Stmt qTags;
908 int nBaseFilter;
909 int nFilter;
910 int rid;
911 const char *zParentBranch = 0;
912 Blob mcksum;
913
@@ -910,13 +917,11 @@
917 db_static_prepare(&qParent, "SELECT tuuid, tbranch FROM xrevisions "
918 "WHERE trev=:rev");
919 db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles "
920 "WHERE tpath GLOB :filter ORDER BY tpath");
921 db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev");
 
922 if( !gsvn.flatFlag ){
 
923 if( gsvn.parent<0 ){
924 gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions "
925 "WHERE tbranch=%Q", gsvn.zBranch);
926 }
927 db_bind_int(&insRev, ":rev", gsvn.rev);
@@ -934,27 +939,28 @@
939 blob_appendf(&manifest, "C %F\n", gsvn.zComment);
940 }else{
941 blob_append(&manifest, "C (no\\scomment)\n", 16);
942 }
943 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
944 nBaseFilter = blob_size(&gsvn.filter);
945 if( strcmp(gsvn.zBranch, gsvn.zTrunk)==0 ){
946 blob_appendf(&gsvn.filter, "%s*", gsvn.zTrunk);
947 }else{
948 blob_appendf(&gsvn.filter, "%s%s/*", gsvn.zBranches, gsvn.zBranch);
 
949 }
950 db_bind_text(&qFiles, ":filter", blob_str(&gsvn.filter));
951 nFilter = blob_size(&gsvn.filter);
952 while( db_step(&qFiles)==SQLITE_ROW ){
953 const char *zFile = db_column_text(&qFiles, 0);
954 int rid = db_column_int(&qFiles, 1);
955 const char *zPerm = db_column_text(&qFiles, 2);
956 const char *zUuid;
957 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
958 blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm);
959 fossil_free(zUuid);
960 }
961 blob_resize(&gsvn.filter, nBaseFilter);
962 if( gsvn.parent>=0 ){
963 const char *zParentUuid;
964 db_bind_int(&qParent, ":rev", gsvn.parent);
965 db_step(&qParent);
966 zParentUuid = db_column_text(&qParent, 0);
@@ -1016,11 +1022,11 @@
1022 }
1023 zDiff += 4;
1024 blob_zero(pOut);
1025 while( zDiff<(blob_buffer(pDiff)+blob_size(pDiff)) ){
1026 u64 offSrc = svn_get_varint(&zDiff);
1027 /*u64 lenSrc =*/ svn_get_varint(&zDiff);
1028 u64 lenOut = svn_get_varint(&zDiff);
1029 u64 lenInst = svn_get_varint(&zDiff);
1030 u64 lenData = svn_get_varint(&zDiff);
1031 const char *zInst = zDiff;
1032 const char *zData = zInst+lenInst;
@@ -1063,10 +1069,11 @@
1069 const char *zTemp;
1070 const char *zUuid;
1071 Stmt addHist;
1072 Stmt insTag;
1073 Stmt cpyPath;
1074 int bHasFiles;
1075
1076 /* version */
1077 if( svn_read_rec(pIn, &rec)
1078 && (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){
1079 ver = atoi(zTemp);
@@ -1099,11 +1106,11 @@
1106 );
1107 gsvn.rev = -1;
1108 while( svn_read_rec(pIn, &rec) ){
1109 if( (zTemp = svn_find_header(rec, "Revision-number")) ){ /* revision node */
1110 /* finish previous revision */
1111 if( bHasFiles ){
1112 svn_create_manifest();
1113 fossil_free(gsvn.zUser);
1114 fossil_free(gsvn.zComment);
1115 fossil_free(gsvn.zDate);
1116 fossil_free(gsvn.zBranch);
@@ -1113,10 +1120,11 @@
1120 gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author"));
1121 gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log"));
1122 gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date"));
1123 gsvn.parent = -1;
1124 gsvn.zBranch = 0;
1125 bHasFiles = 0;
1126 fossil_print("\rImporting SVN revision: %d", gsvn.rev);
1127 db_bind_int(&addHist, ":rev", gsvn.rev);
1128 db_bind_int(&cpyPath, ":rev", gsvn.rev);
1129 }else
1130 if( (zTemp = svn_find_header(rec, "Node-path")) ){ /* file/dir node */
@@ -1137,27 +1145,38 @@
1145 }else{
1146 fossil_fatal("Missing copyfrom-rev");
1147 }
1148 }
1149 if( !gsvn.flatFlag ){
1150 if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){
1151 int lenBranch;
1152 zTemp = zPath+gsvn.lenBranches;
1153 while( *zTemp && *zTemp!='/' ){ zTemp++; }
1154 lenBranch = zTemp-zPath-gsvn.lenBranches;
1155 zTemp = zPath+gsvn.lenBranches;
1156 if( gsvn.zBranch!=0 ){
1157 if( strncmp(zTemp, gsvn.zBranch, lenBranch)!=0 ){
1158 fossil_fatal("Commit to multiple branches");
1159 }
1160 }else{
1161 gsvn.zBranch = fossil_malloc(lenBranch+1);
1162 memcpy(gsvn.zBranch, zTemp, lenBranch);
1163 gsvn.zBranch[lenBranch] = '\0';
1164 bHasFiles = 1;
1165 }
1166 }else
1167 if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk)==0 ){
1168 if( gsvn.zBranch!=0 ){
1169 if( strncmp(gsvn.zTrunk, gsvn.zBranch, gsvn.lenTrunk-1)!=0 ){
1170 fossil_fatal("Commit to multiple branches");
1171 }
1172 }else{
1173 gsvn.zBranch = fossil_malloc(gsvn.lenTrunk);
1174 memcpy(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1);
1175 gsvn.zBranch[gsvn.lenTrunk-1] = '\0';
1176 bHasFiles = 1;
1177 }
1178 }
1179 }
1180 if( strncmp(zAction, "delete", 6)==0
1181 || strncmp(zAction, "replace", 7)==0 )
1182 {
@@ -1178,17 +1197,17 @@
1197 db_bind_text(&cpyPath, ":path", zPath);
1198 db_bind_text(&cpyPath, ":srcpath", zSrcPath);
1199 db_step(&cpyPath);
1200 db_reset(&cpyPath);
1201 if( !gsvn.flatFlag ){
1202 if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){
1203 zTemp = zPath+gsvn.lenBranches+strlen(gsvn.zBranch);
1204 if( *zTemp==0 ){
1205 gsvn.parent = srcRev;
1206 }
1207 }else if( strncmp(zPath, gsvn.zTags, gsvn.lenTags)==0 ){
1208 zTemp = zPath+gsvn.lenTags;
1209 db_bind_int(&insTag, ":rev", srcRev);
1210 db_bind_text(&insTag, ":tag", zTemp);
1211 db_step(&insTag);
1212 db_reset(&insTag);
1213 }
@@ -1278,14 +1297,20 @@
1297 **
1298 ** The following formats are currently understood by this command
1299 **
1300 ** git Import from the git-fast-export file format
1301 **
1302 ** svn Import from the svnadmin-dump file format. The default
1303 ** behaviour is to treat 3 folders in the SVN root as special,
1304 ** following the common layout of SVN repositories. These are
1305 ** (by default) trunk/, branches/ and tags/
1306 ** Options:
1307 ** --trunk FOLDER Name of trunk folder
1308 ** --branches FOLDER Name of branches folder
1309 ** --tags FOLDER Name of tags folder
1310 ** --fiter PATH Path to project root in repository
1311 ** --flat The whole dump is a single branch
1312 **
1313 ** The --incremental option allows an existing repository to be extended
1314 ** with new content.
1315 **
1316 ** Options:
@@ -1295,12 +1320,16 @@
1320 */
1321 void import_cmd(void){
1322 char *zPassword;
1323 FILE *pIn;
1324 Stmt q;
1325 const char *zFilter = find_option("filter", 0, 1);
1326 int forceFlag = find_option("force", "f", 0)!=0;
1327 int incrFlag = find_option("incremental", "i", 0)!=0;
1328 gsvn.zTrunk = find_option("trunk", 0, 1);
1329 gsvn.zBranches = find_option("branches", 0, 1);
1330 gsvn.zTags = find_option("tags", 0, 1);
1331 gsvn.flatFlag = find_option("flat", 0, 0)!=0;
1332
1333 verify_all_options();
1334 if( g.argc!=4 && g.argc!=5 ){
1335 usage("FORMAT REPOSITORY-NAME");
@@ -1378,10 +1407,31 @@
1407 " VALUES(new.tpath, new.trid, new.tperm); END;"
1408 "CREATE TEMP TABLE xtags("
1409 " trev INT, ttag TEXT"
1410 ");"
1411 );
1412 if( gsvn.zTrunk==0 ){ gsvn.zTrunk = "trunk/"; }
1413 if( gsvn.zBranches==0 ){ gsvn.zBranches = "branches/"; }
1414 if( gsvn.zTags==0 ){ gsvn.zTags = "tags/"; }
1415 gsvn.lenTrunk = strlen(gsvn.zTrunk);
1416 gsvn.lenBranches = strlen(gsvn.zBranches);
1417 gsvn.lenTags = strlen(gsvn.zTags);
1418 if( gsvn.zTrunk[gsvn.lenTrunk-1]!='/' ){
1419 gsvn.zTrunk = mprintf("%s/", gsvn.zTrunk);
1420 gsvn.lenTrunk++;
1421 }
1422 if( gsvn.zBranches[gsvn.lenBranches-1]!='/' ){
1423 gsvn.zBranches = mprintf("%s/", gsvn.zBranches);
1424 gsvn.lenBranches++;
1425 }
1426 if( gsvn.zTags[gsvn.lenTags-1]!='/' ){
1427 gsvn.zTags = mprintf("%s/", gsvn.zTags);
1428 gsvn.lenTags++;
1429 }
1430 if( zFilter==0 ){ zFilter = ""; }
1431 blob_zero(&gsvn.filter);
1432 blob_set(&gsvn.filter, zFilter);
1433 svn_dump_import(pIn);
1434 }
1435
1436 verify_cancel();
1437 db_end_transaction(0);
1438

Keyboard Shortcuts

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