Fossil SCM
Fix issue with branches having wrong parent. Needs cleanup
Commit
5f4e2db949690d16454592574b19a42a9199bb4c
Parent
64c65816dadaab7…
1 file changed
+80
-50
+80
-50
| --- src/import.c | ||
| +++ src/import.c | ||
| @@ -719,15 +719,16 @@ | ||
| 719 | 719 | return; |
| 720 | 720 | } |
| 721 | 721 | |
| 722 | 722 | static struct{ |
| 723 | 723 | int rev; /* SVN revision number */ |
| 724 | - int parent; /* SVN revision number of parent check-in */ | |
| 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 */ | |
| 724 | + int parentRev; /* SVN revision number of parent check-in */ | |
| 725 | + const char *zParentBranch; /* Name of branch of parent check-in */ | |
| 726 | + const char *zBranch; /* Name of a branch for a commit */ | |
| 727 | + const char *zDate; /* Date/time stamp */ | |
| 728 | + const char *zUser; /* User name */ | |
| 729 | + const char *zComment; /* Comment of a commit */ | |
| 729 | 730 | int flatFlag; /* True if whole repo is a single file tree */ |
| 730 | 731 | const char *zTrunk; /* Name of trunk folder in repo root */ |
| 731 | 732 | int lenTrunk; /* String length of zTrunk */ |
| 732 | 733 | const char *zBranches; /* Name of branches folder in repo root */ |
| 733 | 734 | int lenBranches; /* String length of zBranches */ |
| @@ -901,10 +902,11 @@ | ||
| 901 | 902 | static void svn_create_manifest( |
| 902 | 903 | ){ |
| 903 | 904 | Blob manifest; |
| 904 | 905 | static Stmt insRev; |
| 905 | 906 | static Stmt qParent; |
| 907 | + static Stmt qParent2; | |
| 906 | 908 | static Stmt qFiles; |
| 907 | 909 | static Stmt qTags; |
| 908 | 910 | int nBaseFilter; |
| 909 | 911 | int nFilter; |
| 910 | 912 | int rid; |
| @@ -911,10 +913,11 @@ | ||
| 911 | 913 | const char *zParentBranch = 0; |
| 912 | 914 | Blob mcksum; |
| 913 | 915 | |
| 914 | 916 | nBaseFilter = blob_size(&gsvn.filter); |
| 915 | 917 | if( !gsvn.flatFlag ){ |
| 918 | + if( gsvn.zBranch==0 ){ return; } | |
| 916 | 919 | if( strncmp(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){ |
| 917 | 920 | blob_appendf(&gsvn.filter, "%s*", gsvn.zTrunk); |
| 918 | 921 | }else{ |
| 919 | 922 | blob_appendf(&gsvn.filter, "%s%s/*", gsvn.zBranches, gsvn.zBranch); |
| 920 | 923 | } |
| @@ -928,31 +931,36 @@ | ||
| 928 | 931 | return; |
| 929 | 932 | } |
| 930 | 933 | db_static_prepare(&insRev, "REPLACE INTO xrevisions (trev, tbranch, tuuid) " |
| 931 | 934 | "VALUES(:rev, :branch, " |
| 932 | 935 | " (SELECT uuid FROM blob WHERE rid=:rid))"); |
| 933 | - db_static_prepare(&qParent, "SELECT tuuid, tbranch FROM xrevisions " | |
| 934 | - "WHERE trev=:rev"); | |
| 936 | + db_static_prepare(&qParent, "SELECT tuuid, max(trev) FROM xrevisions " | |
| 937 | + "WHERE trev<=:rev AND tbranch=:branch"); | |
| 938 | + db_static_prepare(&qParent2, "SELECT tuuid, min(trev) " | |
| 939 | + "FROM xrevisions WHERE tbranch=:branch"); | |
| 935 | 940 | db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles " |
| 936 | 941 | "WHERE tpath GLOB :filter ORDER BY tpath"); |
| 937 | 942 | db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev"); |
| 938 | 943 | if( !gsvn.flatFlag ){ |
| 939 | - if( gsvn.parent<0 ){ | |
| 940 | - gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions " | |
| 941 | - "WHERE tbranch=%Q", gsvn.zBranch); | |
| 942 | - if( gsvn.parent<0 ){ | |
| 943 | - gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions"); | |
| 944 | + if( gsvn.parentRev<0 ){ | |
| 945 | + gsvn.parentRev = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions " | |
| 946 | + "WHERE tbranch=%Q", gsvn.zBranch); | |
| 947 | + if( gsvn.parentRev<0 ){ | |
| 948 | + gsvn.parentRev = | |
| 949 | + db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions"); | |
| 944 | 950 | } |
| 951 | + gsvn.zParentBranch = gsvn.zBranch; | |
| 945 | 952 | } |
| 946 | 953 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 947 | 954 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 948 | 955 | db_bind_int(&insRev, ":rid", 0); |
| 949 | 956 | db_step(&insRev); |
| 950 | 957 | db_reset(&insRev); |
| 951 | 958 | }else{ |
| 952 | 959 | static int prevRev = -1; |
| 953 | - gsvn.parent = prevRev; | |
| 960 | + gsvn.parentRev = prevRev; | |
| 961 | + gsvn.zParentBranch = gsvn.zBranch = ""; | |
| 954 | 962 | prevRev = gsvn.rev; |
| 955 | 963 | } |
| 956 | 964 | blob_zero(&manifest); |
| 957 | 965 | if( gsvn.zComment ){ |
| 958 | 966 | blob_appendf(&manifest, "C %F\n", gsvn.zComment); |
| @@ -970,22 +978,27 @@ | ||
| 970 | 978 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 971 | 979 | blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm); |
| 972 | 980 | fossil_free(zUuid); |
| 973 | 981 | } |
| 974 | 982 | blob_resize(&gsvn.filter, nBaseFilter); |
| 975 | - if( gsvn.parent>=0 ){ | |
| 983 | + if( gsvn.parentRev>=0 ){ | |
| 976 | 984 | const char *zParentUuid; |
| 977 | - db_bind_int(&qParent, ":rev", gsvn.parent); | |
| 985 | + db_bind_int(&qParent, ":rev", gsvn.parentRev); | |
| 986 | + db_bind_text(&qParent, ":branch", gsvn.zParentBranch); | |
| 978 | 987 | db_step(&qParent); |
| 979 | 988 | zParentUuid = db_column_text(&qParent, 0); |
| 989 | + if( zParentUuid==0 ){ | |
| 990 | + db_bind_text(&qParent2, ":branch", gsvn.zParentBranch); | |
| 991 | + db_step(&qParent2); | |
| 992 | + zParentUuid = db_column_text(&qParent2, 0); | |
| 993 | + } | |
| 980 | 994 | blob_appendf(&manifest, "P %s\n", zParentUuid); |
| 981 | 995 | if( !gsvn.flatFlag ){ |
| 982 | - zParentBranch = db_column_text(&qParent, 1); | |
| 983 | - if( strcmp(gsvn.zBranch, zParentBranch)!=0 ){ | |
| 996 | + if( strcmp(gsvn.zBranch, gsvn.zParentBranch)!=0 ){ | |
| 984 | 997 | blob_appendf(&manifest, "T *branch * %F\n", gsvn.zBranch); |
| 985 | 998 | blob_appendf(&manifest, "T *sym-%F *\n", gsvn.zBranch); |
| 986 | - zParentBranch = mprintf("%F", zParentBranch); | |
| 999 | + zParentBranch = mprintf("%F", gsvn.zParentBranch); | |
| 987 | 1000 | }else{ |
| 988 | 1001 | zParentBranch = 0; |
| 989 | 1002 | } |
| 990 | 1003 | } |
| 991 | 1004 | }else{ |
| @@ -998,10 +1011,11 @@ | ||
| 998 | 1011 | blob_appendf(&manifest, "T +sym-%s *\n", zTag); |
| 999 | 1012 | } |
| 1000 | 1013 | blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev); |
| 1001 | 1014 | if( zParentBranch ) { |
| 1002 | 1015 | blob_appendf(&manifest, "T -sym-%s *\n", zParentBranch); |
| 1016 | + fossil_free(zParentBranch); | |
| 1003 | 1017 | } |
| 1004 | 1018 | if( gsvn.zUser ){ |
| 1005 | 1019 | blob_appendf(&manifest, "U %F\n", gsvn.zUser); |
| 1006 | 1020 | }else{ |
| 1007 | 1021 | const char *zUserOvrd = find_option("user-override",0,1); |
| @@ -1014,10 +1028,16 @@ | ||
| 1014 | 1028 | rid = content_put(&manifest); |
| 1015 | 1029 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 1016 | 1030 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 1017 | 1031 | db_bind_int(&insRev, ":rid", rid); |
| 1018 | 1032 | db_step(&insRev); |
| 1033 | + if( gsvn.zParentBranch == gsvn.zBranch ){ | |
| 1034 | + gsvn.zParentBranch = 0; | |
| 1035 | + } | |
| 1036 | + if( gsvn.flatFlag ){ | |
| 1037 | + gsvn.zBranch = 0; | |
| 1038 | + } | |
| 1019 | 1039 | blob_reset(&manifest); |
| 1020 | 1040 | } |
| 1021 | 1041 | |
| 1022 | 1042 | static u64 svn_get_varint(const char **pz){ |
| 1023 | 1043 | unsigned int v = 0; |
| @@ -1069,10 +1089,33 @@ | ||
| 1069 | 1089 | } |
| 1070 | 1090 | } |
| 1071 | 1091 | zDiff += lenData; |
| 1072 | 1092 | } |
| 1073 | 1093 | } |
| 1094 | + | |
| 1095 | +static char *svn_extract_branch(const char *zPath){ | |
| 1096 | + int nFilter = blob_size(&gsvn.filter); | |
| 1097 | + char *zBranch = 0; | |
| 1098 | + if( strncmp(zPath, blob_str(&gsvn.filter), nFilter)==0 ){ | |
| 1099 | + if( strncmp(zPath+nFilter, gsvn.zBranches, gsvn.lenBranches)==0 ){ | |
| 1100 | + int lenBranch; | |
| 1101 | + const char *zTemp = zPath+nFilter+gsvn.lenBranches; | |
| 1102 | + while( *zTemp && *zTemp!='/' ){ zTemp++; } | |
| 1103 | + lenBranch = zTemp-(zPath+nFilter+gsvn.lenBranches); | |
| 1104 | + zTemp = zPath+nFilter+gsvn.lenBranches; | |
| 1105 | + zBranch = fossil_malloc(lenBranch+1); | |
| 1106 | + memcpy(zBranch, zTemp, lenBranch); | |
| 1107 | + zBranch[lenBranch] = '\0'; | |
| 1108 | + }else | |
| 1109 | + if( strncmp(zPath+nFilter, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){ | |
| 1110 | + zBranch = fossil_malloc(gsvn.lenTrunk); | |
| 1111 | + memcpy(zBranch, gsvn.zTrunk, gsvn.lenTrunk-1); | |
| 1112 | + zBranch[gsvn.lenTrunk-1] = '\0'; | |
| 1113 | + } | |
| 1114 | + } | |
| 1115 | + return zBranch; | |
| 1116 | +} | |
| 1074 | 1117 | |
| 1075 | 1118 | /* |
| 1076 | 1119 | ** Read the svn-dump format from pIn and insert the corresponding |
| 1077 | 1120 | ** content into the database. |
| 1078 | 1121 | */ |
| @@ -1083,11 +1126,12 @@ | ||
| 1083 | 1126 | const char *zUuid; |
| 1084 | 1127 | Stmt addHist; |
| 1085 | 1128 | Stmt insTag; |
| 1086 | 1129 | Stmt cpyPath; |
| 1087 | 1130 | Stmt delPath; |
| 1088 | - int bHasFiles; | |
| 1131 | + int bHasFiles = 0; | |
| 1132 | + int nFilter = blob_size(&gsvn.filter); | |
| 1089 | 1133 | |
| 1090 | 1134 | /* version */ |
| 1091 | 1135 | if( svn_read_rec(pIn, &rec) |
| 1092 | 1136 | && (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){ |
| 1093 | 1137 | ver = atoi(zTemp); |
| @@ -1131,17 +1175,19 @@ | ||
| 1131 | 1175 | svn_create_manifest(); |
| 1132 | 1176 | fossil_free(gsvn.zUser); |
| 1133 | 1177 | fossil_free(gsvn.zComment); |
| 1134 | 1178 | fossil_free(gsvn.zDate); |
| 1135 | 1179 | fossil_free(gsvn.zBranch); |
| 1180 | + fossil_free(gsvn.zParentBranch); | |
| 1136 | 1181 | } |
| 1137 | 1182 | /* start new revision */ |
| 1138 | 1183 | gsvn.rev = atoi(zTemp); |
| 1139 | 1184 | gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author")); |
| 1140 | 1185 | gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log")); |
| 1141 | 1186 | gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date")); |
| 1142 | - gsvn.parent = -1; | |
| 1187 | + gsvn.parentRev = -1; | |
| 1188 | + gsvn.zParentBranch = 0; | |
| 1143 | 1189 | gsvn.zBranch = 0; |
| 1144 | 1190 | bHasFiles = 0; |
| 1145 | 1191 | fossil_print("\rImporting SVN revision: %d", gsvn.rev); |
| 1146 | 1192 | db_bind_int(&addHist, ":rev", gsvn.rev); |
| 1147 | 1193 | db_bind_int(&cpyPath, ":rev", gsvn.rev); |
| @@ -1165,35 +1211,18 @@ | ||
| 1165 | 1211 | }else{ |
| 1166 | 1212 | fossil_fatal("Missing copyfrom-rev"); |
| 1167 | 1213 | } |
| 1168 | 1214 | } |
| 1169 | 1215 | if( !gsvn.flatFlag ){ |
| 1170 | - if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){ | |
| 1171 | - int lenBranch; | |
| 1172 | - zTemp = zPath+gsvn.lenBranches; | |
| 1173 | - while( *zTemp && *zTemp!='/' ){ zTemp++; } | |
| 1174 | - lenBranch = zTemp-zPath-gsvn.lenBranches; | |
| 1175 | - zTemp = zPath+gsvn.lenBranches; | |
| 1176 | - if( gsvn.zBranch!=0 ){ | |
| 1177 | - if( strncmp(zTemp, gsvn.zBranch, lenBranch)!=0 ){ | |
| 1178 | - fossil_fatal("Commit to multiple branches"); | |
| 1179 | - } | |
| 1180 | - }else{ | |
| 1181 | - gsvn.zBranch = fossil_malloc(lenBranch+1); | |
| 1182 | - memcpy(gsvn.zBranch, zTemp, lenBranch); | |
| 1183 | - gsvn.zBranch[lenBranch] = '\0'; | |
| 1184 | - } | |
| 1185 | - }else | |
| 1186 | - if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk)==0 ){ | |
| 1187 | - if( gsvn.zBranch!=0 ){ | |
| 1188 | - if( strncmp(gsvn.zTrunk, gsvn.zBranch, gsvn.lenTrunk-1)!=0 ){ | |
| 1189 | - fossil_fatal("Commit to multiple branches"); | |
| 1190 | - } | |
| 1191 | - }else{ | |
| 1192 | - gsvn.zBranch = fossil_malloc(gsvn.lenTrunk); | |
| 1193 | - memcpy(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1); | |
| 1194 | - gsvn.zBranch[gsvn.lenTrunk-1] = '\0'; | |
| 1216 | + if( (zTemp=svn_extract_branch(zPath))!=0 ){ | |
| 1217 | + if( gsvn.zBranch!=0 ){ | |
| 1218 | + if( strcmp(zTemp, gsvn.zBranch)!=0 ){ | |
| 1219 | + fossil_fatal("Commit to multiple branches"); | |
| 1220 | + } | |
| 1221 | + fossil_free(zTemp); | |
| 1222 | + }else{ | |
| 1223 | + gsvn.zBranch = zTemp; | |
| 1195 | 1224 | } |
| 1196 | 1225 | } |
| 1197 | 1226 | } |
| 1198 | 1227 | if( strncmp(zAction, "delete", 6)==0 |
| 1199 | 1228 | || strncmp(zAction, "replace", 7)==0 ) |
| @@ -1215,17 +1244,18 @@ | ||
| 1215 | 1244 | db_bind_text(&cpyPath, ":srcpath", zSrcPath); |
| 1216 | 1245 | db_step(&cpyPath); |
| 1217 | 1246 | db_reset(&cpyPath); |
| 1218 | 1247 | bHasFiles = 1; |
| 1219 | 1248 | if( !gsvn.flatFlag ){ |
| 1220 | - if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){ | |
| 1221 | - zTemp = zPath+gsvn.lenBranches+strlen(gsvn.zBranch); | |
| 1249 | + if( strncmp(zPath+nFilter, gsvn.zBranches, gsvn.lenBranches)==0 ){ | |
| 1250 | + zTemp = zPath+nFilter+gsvn.lenBranches+strlen(gsvn.zBranch); | |
| 1222 | 1251 | if( *zTemp==0 ){ |
| 1223 | - gsvn.parent = srcRev; | |
| 1252 | + gsvn.parentRev = srcRev; | |
| 1253 | + gsvn.zParentBranch = svn_extract_branch(zSrcPath); | |
| 1224 | 1254 | } |
| 1225 | - }else if( strncmp(zPath, gsvn.zTags, gsvn.lenTags)==0 ){ | |
| 1226 | - zTemp = zPath+gsvn.lenTags; | |
| 1255 | + }else if( strncmp(zPath+nFilter, gsvn.zTags, gsvn.lenTags)==0 ){ | |
| 1256 | + zTemp = zPath+nFilter+gsvn.lenTags; | |
| 1227 | 1257 | db_bind_int(&insTag, ":rev", srcRev); |
| 1228 | 1258 | db_bind_text(&insTag, ":tag", zTemp); |
| 1229 | 1259 | db_step(&insTag); |
| 1230 | 1260 | db_reset(&insTag); |
| 1231 | 1261 | } |
| 1232 | 1262 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -719,15 +719,16 @@ | |
| 719 | return; |
| 720 | } |
| 721 | |
| 722 | static struct{ |
| 723 | int rev; /* SVN revision number */ |
| 724 | int parent; /* SVN revision number of parent check-in */ |
| 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 */ |
| @@ -901,10 +902,11 @@ | |
| 901 | static void svn_create_manifest( |
| 902 | ){ |
| 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,10 +913,11 @@ | |
| 911 | const char *zParentBranch = 0; |
| 912 | Blob mcksum; |
| 913 | |
| 914 | nBaseFilter = blob_size(&gsvn.filter); |
| 915 | if( !gsvn.flatFlag ){ |
| 916 | if( strncmp(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){ |
| 917 | blob_appendf(&gsvn.filter, "%s*", gsvn.zTrunk); |
| 918 | }else{ |
| 919 | blob_appendf(&gsvn.filter, "%s%s/*", gsvn.zBranches, gsvn.zBranch); |
| 920 | } |
| @@ -928,31 +931,36 @@ | |
| 928 | return; |
| 929 | } |
| 930 | db_static_prepare(&insRev, "REPLACE INTO xrevisions (trev, tbranch, tuuid) " |
| 931 | "VALUES(:rev, :branch, " |
| 932 | " (SELECT uuid FROM blob WHERE rid=:rid))"); |
| 933 | db_static_prepare(&qParent, "SELECT tuuid, tbranch FROM xrevisions " |
| 934 | "WHERE trev=:rev"); |
| 935 | db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles " |
| 936 | "WHERE tpath GLOB :filter ORDER BY tpath"); |
| 937 | db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev"); |
| 938 | if( !gsvn.flatFlag ){ |
| 939 | if( gsvn.parent<0 ){ |
| 940 | gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions " |
| 941 | "WHERE tbranch=%Q", gsvn.zBranch); |
| 942 | if( gsvn.parent<0 ){ |
| 943 | gsvn.parent = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions"); |
| 944 | } |
| 945 | } |
| 946 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 947 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 948 | db_bind_int(&insRev, ":rid", 0); |
| 949 | db_step(&insRev); |
| 950 | db_reset(&insRev); |
| 951 | }else{ |
| 952 | static int prevRev = -1; |
| 953 | gsvn.parent = prevRev; |
| 954 | prevRev = gsvn.rev; |
| 955 | } |
| 956 | blob_zero(&manifest); |
| 957 | if( gsvn.zComment ){ |
| 958 | blob_appendf(&manifest, "C %F\n", gsvn.zComment); |
| @@ -970,22 +978,27 @@ | |
| 970 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 971 | blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm); |
| 972 | fossil_free(zUuid); |
| 973 | } |
| 974 | blob_resize(&gsvn.filter, nBaseFilter); |
| 975 | if( gsvn.parent>=0 ){ |
| 976 | const char *zParentUuid; |
| 977 | db_bind_int(&qParent, ":rev", gsvn.parent); |
| 978 | db_step(&qParent); |
| 979 | zParentUuid = db_column_text(&qParent, 0); |
| 980 | blob_appendf(&manifest, "P %s\n", zParentUuid); |
| 981 | if( !gsvn.flatFlag ){ |
| 982 | zParentBranch = db_column_text(&qParent, 1); |
| 983 | if( strcmp(gsvn.zBranch, zParentBranch)!=0 ){ |
| 984 | blob_appendf(&manifest, "T *branch * %F\n", gsvn.zBranch); |
| 985 | blob_appendf(&manifest, "T *sym-%F *\n", gsvn.zBranch); |
| 986 | zParentBranch = mprintf("%F", zParentBranch); |
| 987 | }else{ |
| 988 | zParentBranch = 0; |
| 989 | } |
| 990 | } |
| 991 | }else{ |
| @@ -998,10 +1011,11 @@ | |
| 998 | blob_appendf(&manifest, "T +sym-%s *\n", zTag); |
| 999 | } |
| 1000 | blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev); |
| 1001 | if( zParentBranch ) { |
| 1002 | blob_appendf(&manifest, "T -sym-%s *\n", zParentBranch); |
| 1003 | } |
| 1004 | if( gsvn.zUser ){ |
| 1005 | blob_appendf(&manifest, "U %F\n", gsvn.zUser); |
| 1006 | }else{ |
| 1007 | const char *zUserOvrd = find_option("user-override",0,1); |
| @@ -1014,10 +1028,16 @@ | |
| 1014 | rid = content_put(&manifest); |
| 1015 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 1016 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 1017 | db_bind_int(&insRev, ":rid", rid); |
| 1018 | db_step(&insRev); |
| 1019 | blob_reset(&manifest); |
| 1020 | } |
| 1021 | |
| 1022 | static u64 svn_get_varint(const char **pz){ |
| 1023 | unsigned int v = 0; |
| @@ -1069,10 +1089,33 @@ | |
| 1069 | } |
| 1070 | } |
| 1071 | zDiff += lenData; |
| 1072 | } |
| 1073 | } |
| 1074 | |
| 1075 | /* |
| 1076 | ** Read the svn-dump format from pIn and insert the corresponding |
| 1077 | ** content into the database. |
| 1078 | */ |
| @@ -1083,11 +1126,12 @@ | |
| 1083 | const char *zUuid; |
| 1084 | Stmt addHist; |
| 1085 | Stmt insTag; |
| 1086 | Stmt cpyPath; |
| 1087 | Stmt delPath; |
| 1088 | int bHasFiles; |
| 1089 | |
| 1090 | /* version */ |
| 1091 | if( svn_read_rec(pIn, &rec) |
| 1092 | && (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){ |
| 1093 | ver = atoi(zTemp); |
| @@ -1131,17 +1175,19 @@ | |
| 1131 | svn_create_manifest(); |
| 1132 | fossil_free(gsvn.zUser); |
| 1133 | fossil_free(gsvn.zComment); |
| 1134 | fossil_free(gsvn.zDate); |
| 1135 | fossil_free(gsvn.zBranch); |
| 1136 | } |
| 1137 | /* start new revision */ |
| 1138 | gsvn.rev = atoi(zTemp); |
| 1139 | gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author")); |
| 1140 | gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log")); |
| 1141 | gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date")); |
| 1142 | gsvn.parent = -1; |
| 1143 | gsvn.zBranch = 0; |
| 1144 | bHasFiles = 0; |
| 1145 | fossil_print("\rImporting SVN revision: %d", gsvn.rev); |
| 1146 | db_bind_int(&addHist, ":rev", gsvn.rev); |
| 1147 | db_bind_int(&cpyPath, ":rev", gsvn.rev); |
| @@ -1165,35 +1211,18 @@ | |
| 1165 | }else{ |
| 1166 | fossil_fatal("Missing copyfrom-rev"); |
| 1167 | } |
| 1168 | } |
| 1169 | if( !gsvn.flatFlag ){ |
| 1170 | if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){ |
| 1171 | int lenBranch; |
| 1172 | zTemp = zPath+gsvn.lenBranches; |
| 1173 | while( *zTemp && *zTemp!='/' ){ zTemp++; } |
| 1174 | lenBranch = zTemp-zPath-gsvn.lenBranches; |
| 1175 | zTemp = zPath+gsvn.lenBranches; |
| 1176 | if( gsvn.zBranch!=0 ){ |
| 1177 | if( strncmp(zTemp, gsvn.zBranch, lenBranch)!=0 ){ |
| 1178 | fossil_fatal("Commit to multiple branches"); |
| 1179 | } |
| 1180 | }else{ |
| 1181 | gsvn.zBranch = fossil_malloc(lenBranch+1); |
| 1182 | memcpy(gsvn.zBranch, zTemp, lenBranch); |
| 1183 | gsvn.zBranch[lenBranch] = '\0'; |
| 1184 | } |
| 1185 | }else |
| 1186 | if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk)==0 ){ |
| 1187 | if( gsvn.zBranch!=0 ){ |
| 1188 | if( strncmp(gsvn.zTrunk, gsvn.zBranch, gsvn.lenTrunk-1)!=0 ){ |
| 1189 | fossil_fatal("Commit to multiple branches"); |
| 1190 | } |
| 1191 | }else{ |
| 1192 | gsvn.zBranch = fossil_malloc(gsvn.lenTrunk); |
| 1193 | memcpy(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1); |
| 1194 | gsvn.zBranch[gsvn.lenTrunk-1] = '\0'; |
| 1195 | } |
| 1196 | } |
| 1197 | } |
| 1198 | if( strncmp(zAction, "delete", 6)==0 |
| 1199 | || strncmp(zAction, "replace", 7)==0 ) |
| @@ -1215,17 +1244,18 @@ | |
| 1215 | db_bind_text(&cpyPath, ":srcpath", zSrcPath); |
| 1216 | db_step(&cpyPath); |
| 1217 | db_reset(&cpyPath); |
| 1218 | bHasFiles = 1; |
| 1219 | if( !gsvn.flatFlag ){ |
| 1220 | if( strncmp(zPath, gsvn.zBranches, gsvn.lenBranches)==0 ){ |
| 1221 | zTemp = zPath+gsvn.lenBranches+strlen(gsvn.zBranch); |
| 1222 | if( *zTemp==0 ){ |
| 1223 | gsvn.parent = srcRev; |
| 1224 | } |
| 1225 | }else if( strncmp(zPath, gsvn.zTags, gsvn.lenTags)==0 ){ |
| 1226 | zTemp = zPath+gsvn.lenTags; |
| 1227 | db_bind_int(&insTag, ":rev", srcRev); |
| 1228 | db_bind_text(&insTag, ":tag", zTemp); |
| 1229 | db_step(&insTag); |
| 1230 | db_reset(&insTag); |
| 1231 | } |
| 1232 |
| --- src/import.c | |
| +++ src/import.c | |
| @@ -719,15 +719,16 @@ | |
| 719 | return; |
| 720 | } |
| 721 | |
| 722 | static struct{ |
| 723 | int rev; /* SVN revision number */ |
| 724 | int parentRev; /* SVN revision number of parent check-in */ |
| 725 | const char *zParentBranch; /* Name of branch of parent check-in */ |
| 726 | const char *zBranch; /* Name of a branch for a commit */ |
| 727 | const char *zDate; /* Date/time stamp */ |
| 728 | const char *zUser; /* User name */ |
| 729 | const char *zComment; /* Comment of a commit */ |
| 730 | int flatFlag; /* True if whole repo is a single file tree */ |
| 731 | const char *zTrunk; /* Name of trunk folder in repo root */ |
| 732 | int lenTrunk; /* String length of zTrunk */ |
| 733 | const char *zBranches; /* Name of branches folder in repo root */ |
| 734 | int lenBranches; /* String length of zBranches */ |
| @@ -901,10 +902,11 @@ | |
| 902 | static void svn_create_manifest( |
| 903 | ){ |
| 904 | Blob manifest; |
| 905 | static Stmt insRev; |
| 906 | static Stmt qParent; |
| 907 | static Stmt qParent2; |
| 908 | static Stmt qFiles; |
| 909 | static Stmt qTags; |
| 910 | int nBaseFilter; |
| 911 | int nFilter; |
| 912 | int rid; |
| @@ -911,10 +913,11 @@ | |
| 913 | const char *zParentBranch = 0; |
| 914 | Blob mcksum; |
| 915 | |
| 916 | nBaseFilter = blob_size(&gsvn.filter); |
| 917 | if( !gsvn.flatFlag ){ |
| 918 | if( gsvn.zBranch==0 ){ return; } |
| 919 | if( strncmp(gsvn.zBranch, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){ |
| 920 | blob_appendf(&gsvn.filter, "%s*", gsvn.zTrunk); |
| 921 | }else{ |
| 922 | blob_appendf(&gsvn.filter, "%s%s/*", gsvn.zBranches, gsvn.zBranch); |
| 923 | } |
| @@ -928,31 +931,36 @@ | |
| 931 | return; |
| 932 | } |
| 933 | db_static_prepare(&insRev, "REPLACE INTO xrevisions (trev, tbranch, tuuid) " |
| 934 | "VALUES(:rev, :branch, " |
| 935 | " (SELECT uuid FROM blob WHERE rid=:rid))"); |
| 936 | db_static_prepare(&qParent, "SELECT tuuid, max(trev) FROM xrevisions " |
| 937 | "WHERE trev<=:rev AND tbranch=:branch"); |
| 938 | db_static_prepare(&qParent2, "SELECT tuuid, min(trev) " |
| 939 | "FROM xrevisions WHERE tbranch=:branch"); |
| 940 | db_static_prepare(&qFiles, "SELECT tpath, trid, tperm FROM xfiles " |
| 941 | "WHERE tpath GLOB :filter ORDER BY tpath"); |
| 942 | db_static_prepare(&qTags, "SELECT ttag FROM xtags WHERE trev=:rev"); |
| 943 | if( !gsvn.flatFlag ){ |
| 944 | if( gsvn.parentRev<0 ){ |
| 945 | gsvn.parentRev = db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions " |
| 946 | "WHERE tbranch=%Q", gsvn.zBranch); |
| 947 | if( gsvn.parentRev<0 ){ |
| 948 | gsvn.parentRev = |
| 949 | db_int(-1, "SELECT ifnull(max(trev),-1) FROM xrevisions"); |
| 950 | } |
| 951 | gsvn.zParentBranch = gsvn.zBranch; |
| 952 | } |
| 953 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 954 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 955 | db_bind_int(&insRev, ":rid", 0); |
| 956 | db_step(&insRev); |
| 957 | db_reset(&insRev); |
| 958 | }else{ |
| 959 | static int prevRev = -1; |
| 960 | gsvn.parentRev = prevRev; |
| 961 | gsvn.zParentBranch = gsvn.zBranch = ""; |
| 962 | prevRev = gsvn.rev; |
| 963 | } |
| 964 | blob_zero(&manifest); |
| 965 | if( gsvn.zComment ){ |
| 966 | blob_appendf(&manifest, "C %F\n", gsvn.zComment); |
| @@ -970,22 +978,27 @@ | |
| 978 | zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 979 | blob_appendf(&manifest, "F %F %s %s\n", zFile+nFilter, zUuid, zPerm); |
| 980 | fossil_free(zUuid); |
| 981 | } |
| 982 | blob_resize(&gsvn.filter, nBaseFilter); |
| 983 | if( gsvn.parentRev>=0 ){ |
| 984 | const char *zParentUuid; |
| 985 | db_bind_int(&qParent, ":rev", gsvn.parentRev); |
| 986 | db_bind_text(&qParent, ":branch", gsvn.zParentBranch); |
| 987 | db_step(&qParent); |
| 988 | zParentUuid = db_column_text(&qParent, 0); |
| 989 | if( zParentUuid==0 ){ |
| 990 | db_bind_text(&qParent2, ":branch", gsvn.zParentBranch); |
| 991 | db_step(&qParent2); |
| 992 | zParentUuid = db_column_text(&qParent2, 0); |
| 993 | } |
| 994 | blob_appendf(&manifest, "P %s\n", zParentUuid); |
| 995 | if( !gsvn.flatFlag ){ |
| 996 | if( strcmp(gsvn.zBranch, gsvn.zParentBranch)!=0 ){ |
| 997 | blob_appendf(&manifest, "T *branch * %F\n", gsvn.zBranch); |
| 998 | blob_appendf(&manifest, "T *sym-%F *\n", gsvn.zBranch); |
| 999 | zParentBranch = mprintf("%F", gsvn.zParentBranch); |
| 1000 | }else{ |
| 1001 | zParentBranch = 0; |
| 1002 | } |
| 1003 | } |
| 1004 | }else{ |
| @@ -998,10 +1011,11 @@ | |
| 1011 | blob_appendf(&manifest, "T +sym-%s *\n", zTag); |
| 1012 | } |
| 1013 | blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev); |
| 1014 | if( zParentBranch ) { |
| 1015 | blob_appendf(&manifest, "T -sym-%s *\n", zParentBranch); |
| 1016 | fossil_free(zParentBranch); |
| 1017 | } |
| 1018 | if( gsvn.zUser ){ |
| 1019 | blob_appendf(&manifest, "U %F\n", gsvn.zUser); |
| 1020 | }else{ |
| 1021 | const char *zUserOvrd = find_option("user-override",0,1); |
| @@ -1014,10 +1028,16 @@ | |
| 1028 | rid = content_put(&manifest); |
| 1029 | db_bind_int(&insRev, ":rev", gsvn.rev); |
| 1030 | db_bind_text(&insRev, ":branch", gsvn.zBranch); |
| 1031 | db_bind_int(&insRev, ":rid", rid); |
| 1032 | db_step(&insRev); |
| 1033 | if( gsvn.zParentBranch == gsvn.zBranch ){ |
| 1034 | gsvn.zParentBranch = 0; |
| 1035 | } |
| 1036 | if( gsvn.flatFlag ){ |
| 1037 | gsvn.zBranch = 0; |
| 1038 | } |
| 1039 | blob_reset(&manifest); |
| 1040 | } |
| 1041 | |
| 1042 | static u64 svn_get_varint(const char **pz){ |
| 1043 | unsigned int v = 0; |
| @@ -1069,10 +1089,33 @@ | |
| 1089 | } |
| 1090 | } |
| 1091 | zDiff += lenData; |
| 1092 | } |
| 1093 | } |
| 1094 | |
| 1095 | static char *svn_extract_branch(const char *zPath){ |
| 1096 | int nFilter = blob_size(&gsvn.filter); |
| 1097 | char *zBranch = 0; |
| 1098 | if( strncmp(zPath, blob_str(&gsvn.filter), nFilter)==0 ){ |
| 1099 | if( strncmp(zPath+nFilter, gsvn.zBranches, gsvn.lenBranches)==0 ){ |
| 1100 | int lenBranch; |
| 1101 | const char *zTemp = zPath+nFilter+gsvn.lenBranches; |
| 1102 | while( *zTemp && *zTemp!='/' ){ zTemp++; } |
| 1103 | lenBranch = zTemp-(zPath+nFilter+gsvn.lenBranches); |
| 1104 | zTemp = zPath+nFilter+gsvn.lenBranches; |
| 1105 | zBranch = fossil_malloc(lenBranch+1); |
| 1106 | memcpy(zBranch, zTemp, lenBranch); |
| 1107 | zBranch[lenBranch] = '\0'; |
| 1108 | }else |
| 1109 | if( strncmp(zPath+nFilter, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){ |
| 1110 | zBranch = fossil_malloc(gsvn.lenTrunk); |
| 1111 | memcpy(zBranch, gsvn.zTrunk, gsvn.lenTrunk-1); |
| 1112 | zBranch[gsvn.lenTrunk-1] = '\0'; |
| 1113 | } |
| 1114 | } |
| 1115 | return zBranch; |
| 1116 | } |
| 1117 | |
| 1118 | /* |
| 1119 | ** Read the svn-dump format from pIn and insert the corresponding |
| 1120 | ** content into the database. |
| 1121 | */ |
| @@ -1083,11 +1126,12 @@ | |
| 1126 | const char *zUuid; |
| 1127 | Stmt addHist; |
| 1128 | Stmt insTag; |
| 1129 | Stmt cpyPath; |
| 1130 | Stmt delPath; |
| 1131 | int bHasFiles = 0; |
| 1132 | int nFilter = blob_size(&gsvn.filter); |
| 1133 | |
| 1134 | /* version */ |
| 1135 | if( svn_read_rec(pIn, &rec) |
| 1136 | && (zTemp = svn_find_header(rec, "SVN-fs-dump-format-version")) ){ |
| 1137 | ver = atoi(zTemp); |
| @@ -1131,17 +1175,19 @@ | |
| 1175 | svn_create_manifest(); |
| 1176 | fossil_free(gsvn.zUser); |
| 1177 | fossil_free(gsvn.zComment); |
| 1178 | fossil_free(gsvn.zDate); |
| 1179 | fossil_free(gsvn.zBranch); |
| 1180 | fossil_free(gsvn.zParentBranch); |
| 1181 | } |
| 1182 | /* start new revision */ |
| 1183 | gsvn.rev = atoi(zTemp); |
| 1184 | gsvn.zUser = mprintf("%s", svn_find_prop(rec, "svn:author")); |
| 1185 | gsvn.zComment = mprintf("%s", svn_find_prop(rec, "svn:log")); |
| 1186 | gsvn.zDate = date_in_standard_format(svn_find_prop(rec, "svn:date")); |
| 1187 | gsvn.parentRev = -1; |
| 1188 | gsvn.zParentBranch = 0; |
| 1189 | gsvn.zBranch = 0; |
| 1190 | bHasFiles = 0; |
| 1191 | fossil_print("\rImporting SVN revision: %d", gsvn.rev); |
| 1192 | db_bind_int(&addHist, ":rev", gsvn.rev); |
| 1193 | db_bind_int(&cpyPath, ":rev", gsvn.rev); |
| @@ -1165,35 +1211,18 @@ | |
| 1211 | }else{ |
| 1212 | fossil_fatal("Missing copyfrom-rev"); |
| 1213 | } |
| 1214 | } |
| 1215 | if( !gsvn.flatFlag ){ |
| 1216 | if( (zTemp=svn_extract_branch(zPath))!=0 ){ |
| 1217 | if( gsvn.zBranch!=0 ){ |
| 1218 | if( strcmp(zTemp, gsvn.zBranch)!=0 ){ |
| 1219 | fossil_fatal("Commit to multiple branches"); |
| 1220 | } |
| 1221 | fossil_free(zTemp); |
| 1222 | }else{ |
| 1223 | gsvn.zBranch = zTemp; |
| 1224 | } |
| 1225 | } |
| 1226 | } |
| 1227 | if( strncmp(zAction, "delete", 6)==0 |
| 1228 | || strncmp(zAction, "replace", 7)==0 ) |
| @@ -1215,17 +1244,18 @@ | |
| 1244 | db_bind_text(&cpyPath, ":srcpath", zSrcPath); |
| 1245 | db_step(&cpyPath); |
| 1246 | db_reset(&cpyPath); |
| 1247 | bHasFiles = 1; |
| 1248 | if( !gsvn.flatFlag ){ |
| 1249 | if( strncmp(zPath+nFilter, gsvn.zBranches, gsvn.lenBranches)==0 ){ |
| 1250 | zTemp = zPath+nFilter+gsvn.lenBranches+strlen(gsvn.zBranch); |
| 1251 | if( *zTemp==0 ){ |
| 1252 | gsvn.parentRev = srcRev; |
| 1253 | gsvn.zParentBranch = svn_extract_branch(zSrcPath); |
| 1254 | } |
| 1255 | }else if( strncmp(zPath+nFilter, gsvn.zTags, gsvn.lenTags)==0 ){ |
| 1256 | zTemp = zPath+nFilter+gsvn.lenTags; |
| 1257 | db_bind_int(&insTag, ":rev", srcRev); |
| 1258 | db_bind_text(&insTag, ":tag", zTemp); |
| 1259 | db_step(&insTag); |
| 1260 | db_reset(&insTag); |
| 1261 | } |
| 1262 |