Changes to src/import.c.
︙ | | |
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
+
+
+
+
+
+
+
+
+
+
|
char *zPrior; /* Prior name if the name was changed */
char isFrom; /* True if obtained from the parent */
char isExe; /* True if executable */
char isLink; /* True if symlink */
};
#endif
/*
** State information common to all import types.
*/
static struct {
const char *zTrunkName; /* Name of trunk branch */
const char *zBranchPre; /* Prepended to non-trunk branch names */
const char *zBranchSuf; /* Appended to non-trunk branch names */
const char *zTagPre; /* Prepended to non-trunk tag names */
const char *zTagSuf; /* Appended to non-trunk tag names */
} gimport;
/*
** State information about an on-going fast-import parse.
*/
static struct {
void (*xFinish)(void); /* Function to finish a prior record */
int nData; /* Bytes of data */
|
︙ | | |
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
-
+
+
|
** control artifact to the BLOB table.
*/
static void finish_tag(void){
Blob record, cksum;
if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
blob_zero(&record);
blob_appendf(&record, "D %s\n", gg.zDate);
blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom);
blob_appendf(&record, "T +%F%F%F %s\n", gimport.zTagPre, gg.zTag,
gimport.zTagSuf, gg.zFrom);
blob_appendf(&record, "U %F\n", gg.zUser);
md5sum_blob(&record, &cksum);
blob_appendf(&record, "Z %b\n", &cksum);
fast_insert_content(&record, 0, 0, 1);
blob_reset(&cksum);
}
import_reset(0);
|
︙ | | |
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
-
-
+
+
+
+
-
+
+
-
+
|
zFromBranch = 0;
}
/* Add the required "T" cards to the manifest. Make sure they are added
** in sorted order and without any duplicates. Otherwise, fossil will not
** recognize the document as a valid manifest. */
if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
aTCard[nTCard++] = mprintf("T *branch * %F\n", gg.zBranch);
aTCard[nTCard++] = mprintf("T *sym-%F *\n", gg.zBranch);
aTCard[nTCard++] = mprintf("T *branch * %F%F%F\n", gimport.zBranchPre,
gg.zBranch, gimport.zBranchSuf);
aTCard[nTCard++] = mprintf("T *sym-%F%F%F *\n", gimport.zBranchPre,
gg.zBranch, gimport.zBranchSuf);
if( zFromBranch ){
aTCard[nTCard++] = mprintf("T -sym-%F *\n", zFromBranch);
aTCard[nTCard++] = mprintf("T -sym-%F%F%F *\n", gimport.zBranchPre,
zFromBranch, gimport.zBranchSuf);
}
}
if( gg.zFrom==0 ){
aTCard[nTCard++] = mprintf("T *sym-trunk *\n");
aTCard[nTCard++] = mprintf("T *sym-%F *\n", gimport.zTrunkName);
}
qsort(aTCard, nTCard, sizeof(char *), string_cmp);
for(i=0; i<nTCard; i++){
if( i==0 || fossil_strcmp(aTCard[i-1], aTCard[i]) ){
blob_appendf(&record, "%s", aTCard[i]);
}
}
|
︙ | | |
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
|
-
+
+
|
** but overwrite that entry if a later instance of the same tag appears.
**
** This behavior seems like a bug in git-fast-export, but it is easier
** to work around the problem than to fix git-fast-export.
*/
if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
blob_appendf(&record, "D %s\n", gg.zDate);
blob_appendf(&record, "T +sym-%F %s\n", gg.zBranch, gg.zPrevCheckin);
blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
gimport.zBranchSuf, gg.zPrevCheckin);
blob_appendf(&record, "U %F\n", gg.zUser);
md5sum_blob(&record, &cksum);
blob_appendf(&record, "Z %b\n", &cksum);
db_multi_exec(
"INSERT OR REPLACE INTO xtag(tname, tcontent)"
" VALUES(%Q,%Q)", gg.zBranch, blob_str(&record)
);
|
︙ | | |
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
|
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
|
-
+
+
+
+
|
const char *zTrunk; /* Name of trunk folder in repo root */
int lenTrunk; /* String length of zTrunk */
const char *zBranches; /* Name of branches folder in repo root */
int lenBranches; /* String length of zBranches */
const char *zTags; /* Name of tags folder in repo root */
int lenTags; /* String length of zTags */
Bag newBranches; /* Branches that were created in this revision */
int incrFlag; /* Add svn-rev-nn tags on every checkin */
int revFlag; /* Add svn-rev-nn tags on every checkin */
const char *zRevPre; /* Prepended to revision tag names */
const char *zRevSuf; /* Appended to revision tag names */
const char **azIgnTree; /* NULL-terminated list of dirs to ignore */
} gsvn;
typedef struct {
char *zKey;
char *zVal;
} KeyVal;
typedef struct {
KeyVal *aHeaders;
|
︙ | | |
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
|
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
|
+
-
-
-
-
-
+
+
+
+
+
+
|
if( !bag_find(&gsvn.newBranches, branchId) ){
parentRid = db_int(0, "SELECT trid, max(trev) FROM xrevisions"
" WHERE trev<%d AND tbranch=%d",
gsvn.rev, branchId);
}
if( parentRid>0 ){
pParentManifest = manifest_get(parentRid, CFTYPE_MANIFEST, 0);
if( pParentManifest ){
pParentFile = manifest_file_next(pParentManifest, 0);
parentBranch = db_int(0, "SELECT tbranch FROM xrevisions WHERE trid=%d",
parentRid);
if( parentBranch!=branchId && branchType!=SVN_TAG ){
sameAsParent = 0;
pParentFile = manifest_file_next(pParentManifest, 0);
parentBranch = db_int(0, "SELECT tbranch FROM xrevisions WHERE trid=%d",
parentRid);
if( parentBranch!=branchId && branchType!=SVN_TAG ){
sameAsParent = 0;
}
}
}
if( mergeRid<MAX_INT_32 ){
if( gsvn.zComment ){
blob_appendf(&manifest, "C %F\n", gsvn.zComment);
}else{
blob_append(&manifest, "C (no\\scomment)\n", 16);
|
︙ | | |
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
|
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
|
-
-
-
-
+
+
+
+
+
+
+
-
+
+
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+
-
+
+
-
+
+
|
char *zParentUuid = rid_to_uuid(parentRid);
if( parentRid==mergeRid || mergeRid==0){
char *zParentBranch =
db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
parentBranch
);
blob_appendf(&manifest, "P %s\n", zParentUuid);
blob_appendf(&manifest, "T *branch * %F\n", zBranch);
blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
if( gsvn.incrFlag ){
blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
blob_appendf(&manifest, "T *branch * %F%F%F\n", gimport.zBranchPre,
zBranch, gimport.zBranchSuf);
blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
zBranch, gimport.zBranchSuf);
if( gsvn.revFlag ){
blob_appendf(&manifest, "T +sym-%Fr%d%F *\n", gimport.zTagPre,
gsvn.rev, gimport.zTagSuf);
}
blob_appendf(&manifest, "T -sym-%F *\n", zParentBranch);
blob_appendf(&manifest, "T -sym-%F%F%F *\n", gimport.zBranchPre,
zParentBranch, gimport.zBranchSuf);
fossil_free(zParentBranch);
}else{
char *zMergeUuid = rid_to_uuid(mergeRid);
blob_appendf(&manifest, "P %s %s\n", zParentUuid, zMergeUuid);
if( gsvn.incrFlag ){
blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
if( gsvn.revFlag ){
blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
gsvn.rev, gsvn.zRevSuf);
}
fossil_free(zMergeUuid);
}
fossil_free(zParentUuid);
}else{
blob_appendf(&manifest, "T *branch * %F\n", zBranch);
blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
if( gsvn.incrFlag ){
blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
blob_appendf(&manifest, "T *branch * %F%F%F\n",
gimport.zBranchPre, zBranch, gimport.zBranchSuf);
blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
zBranch, gimport.zBranchSuf);
if( gsvn.revFlag ){
blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre, gsvn.rev,
gsvn.zRevSuf);
}
}
}else if( branchType==SVN_TAG ){
char *zParentUuid = rid_to_uuid(parentRid);
blob_reset(&manifest);
blob_appendf(&manifest, "D %s\n", gsvn.zDate);
blob_appendf(&manifest, "T +sym-%F %s\n", zBranch, zParentUuid);
blob_appendf(&manifest, "T +sym-%F%F%F %s\n", gimport.zTagPre, zBranch,
gimport.zTagSuf, zParentUuid);
fossil_free(zParentUuid);
}
}else{
char *zParentUuid = rid_to_uuid(parentRid);
blob_appendf(&manifest, "D %s\n", gsvn.zDate);
if( branchType!=SVN_TAG ){
blob_appendf(&manifest, "T +closed %s\n", zParentUuid);
}else{
blob_appendf(&manifest, "T -sym-%F %s\n", zBranch, zParentUuid);
blob_appendf(&manifest, "T -sym-%F%F%F %s\n", gimport.zBranchPre,
zBranch, gimport.zBranchSuf, zParentUuid);
}
fossil_free(zParentUuid);
}
if( gsvn.zUser ){
blob_appendf(&manifest, "U %F\n", gsvn.zUser);
}else{
const char *zUserOvrd = find_option("user-override",0,1);
|
︙ | | |
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
|
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
|
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
|
}
zDiff += lenData;
}
}
/*
** Extract the branch or tag that the given path is on. Return the branch ID.
** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
*/
*/
static int svn_parse_path(char *zPath, char **zFile, int *type){
char *zBranch = 0;
int branchId = 0;
if( gsvn.azIgnTree ){
const char **pzIgnTree;
unsigned nPath = strlen(zPath);
for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
const char *zIgn = *pzIgnTree;
int nIgn = strlen(zIgn);
if( strncmp(zPath, zIgn, nIgn) == 0
&& ( nPath == nIgn || (nPath > nIgn && zPath[nIgn] == '/')) ){
return 0;
}
}
}
*type = SVN_UNKNOWN;
*zFile = 0;
if( gsvn.lenTrunk==0 ){
zBranch = "trunk";
*zFile = zPath;
*type = SVN_TRUNK;
}else
|
︙ | | |
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
|
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
|
-
+
|
}
}else
if( strncmp(zAction, "change", 6)==0 ){
int rid = 0;
if( zKind==0 ){
fossil_fatal("Missing Node-kind");
}
if( strncmp(zKind, "dir", 3)!=0 ){
if( rec.contentFlag && strncmp(zKind, "dir", 3)!=0 ){
if( deltaFlag ){
Blob deltaSrc;
Blob target;
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=("
" SELECT tuuid FROM xfiles"
" WHERE tpath=%Q AND tbranch=%d"
")", zFile, branchId);
|
︙ | | |
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
|
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
|
-
+
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
|
** The following formats are currently understood by this command
**
** --git Import from the git-fast-export file format (default)
** Options:
** --import-marks FILE Restore marks table from FILE
** --export-marks FILE Save marks table to FILE
**
** --svn Import from the svnadmin-dump file format. The default
** --svn Import from the svnadmin-dump file format. The default
** behaviour (unless overridden by --flat) is to treat 3
** folders in the SVN root as special, following the
** common layout of SVN repositories. These are (by
** default) trunk/, branches/ and tags/
** common layout of SVN repositories. These are (by
** default) trunk/, branches/ and tags/. The SVN --deltas
** format is supported but not required.
** Options:
** --trunk FOLDER Name of trunk folder
** --branches FOLDER Name of branches folder
** --tags FOLDER Name of tags folder
** --base PATH Path to project root in repository
** --flat The whole dump is a single branch
** --rev-tags Tag each revision, implied by -i
** --no-rev-tags Disables tagging effect of -i
** --rename-rev PAT Rev tag names, default "svn-rev-%"
** --ignore-tree DIR Ignores subtree rooted at DIR
**
** Common Options:
** -i|--incremental allow importing into an existing repository
** -f|--force overwrite repository if already exists
** -q|--quiet omit progress output
** --no-rebuild skip the "rebuilding metadata" step
** --no-vacuum skip the final VACUUM of the database file
** -i|--incremental allow importing into an existing repository
** -f|--force overwrite repository if already exists
** -q|--quiet omit progress output
** --no-rebuild skip the "rebuilding metadata" step
** --no-vacuum skip the final VACUUM of the database file
** --rename-trunk NAME use NAME as name of imported trunk branch
** --rename-branch PAT rename all branch names using PAT pattern
** --rename-tag PAT rename all tag names using PAT pattern
**
** The --incremental option allows an existing repository to be extended
** with new content.
** with new content. The --rename-* options may be useful to avoid name
** conflicts when using the --incremental option.
**
** The argument to --rename-* contains one "%" character to be replaced
** with the original name. For example, "--rename-tag svn-%-tag" renames
** the tag called "release" to "svn-release-tag".
**
** --ignore-tree is useful for importing Subversion repositories which
** move branches to subdirectories of "branches/deleted" instead of
** deleting them. It can be supplied multiple times if necessary.
**
** See also: export
*/
void import_cmd(void){
char *zPassword;
FILE *pIn;
Stmt q;
|
︙ | | |
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
|
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
|
/* Options for --svn only */
const char *zBase="";
int flatFlag=0;
/* Options for --git only */
const char *markfile_in;
const char *markfile_out;
/* Interpret --rename-* options. Use a table to avoid code duplication. */
const struct {
const char *zOpt, **varPre, *zDefaultPre, **varSuf, *zDefaultSuf;
int format; /* 1=git, 2=svn, 3=any */
} renOpts[] = {
{"rename-branch", &gimport.zBranchPre, "", &gimport.zBranchSuf, "", 3},
{"rename-tag" , &gimport.zTagPre , "", &gimport.zTagSuf , "", 3},
{"rename-rev" , &gsvn.zRevPre, "svn-rev-", &gsvn.zRevSuf , "", 2},
}, *renOpt = renOpts;
int i;
for( i = 0; i < sizeof(renOpts) / sizeof(*renOpts); ++i, ++renOpt ){
if( 1 << svnFlag & renOpt->format ){
const char *zArgument = find_option(renOpt->zOpt, 0, 1);
if( zArgument ){
const char *sep = strchr(zArgument, '%');
if( !sep ){
fossil_fatal("missing '%%' in argument to --%s", renOpt->zOpt);
}else if( strchr(sep + 1, '%') ){
fossil_fatal("multiple '%%' in argument to --%s", renOpt->zOpt);
}
*renOpt->varPre = fossil_malloc(sep - zArgument + 1);
memcpy((char *)*renOpt->varPre, zArgument, sep - zArgument);
((char *)*renOpt->varPre)[sep - zArgument] = 0;
*renOpt->varSuf = sep + 1;
}else{
*renOpt->varPre = renOpt->zDefaultPre;
*renOpt->varSuf = renOpt->zDefaultSuf;
}
}
}
if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
gimport.zTrunkName = "trunk";
}
if( svnFlag ){
/* Get --svn related options here, so verify_all_options() fail when svn
* only option are specify with --git
/* Get --svn related options here, so verify_all_options() fails when
* svn-only options are specified with --git
*/
const char *zIgnTree;
unsigned nIgnTree = 0;
while( (zIgnTree = find_option("ignore-tree", 0, 1)) ){
if ( *zIgnTree ){
gsvn.azIgnTree = fossil_realloc(gsvn.azIgnTree,
sizeof(*gsvn.azIgnTree) * (nIgnTree + 2));
gsvn.azIgnTree[nIgnTree++] = zIgnTree;
gsvn.azIgnTree[nIgnTree] = 0;
}
}
zBase = find_option("base", 0, 1);
flatFlag = find_option("flat", 0, 0)!=0;
gsvn.zTrunk = find_option("trunk", 0, 1);
gsvn.zBranches = find_option("branches", 0, 1);
gsvn.zTags = find_option("tags", 0, 1);
gsvn.revFlag = find_option("rev-tags", 0, 0)
gsvn.incrFlag = incrFlag;
|| (incrFlag && !find_option("no-rev-tags", 0, 0));
}else if( gitFlag ){
markfile_in = find_option("import-marks", 0, 1);
markfile_out = find_option("export-marks", 0, 1);
}
verify_all_options();
if( g.argc!=3 && g.argc!=4 ){
|
︙ | | |