Fossil SCM

Add -rename-trunk, -rename-branch, -rename-tag, -rename-rev, -rev-tags, and -no-rev-tags options to import command

andygoth 2016-05-12 16:12 trunk
Commit d7b8b3e18328605ed0ce084b4a1eb344217306f6
1 file changed +106 -32
+106 -32
--- src/import.c
+++ src/import.c
@@ -34,10 +34,20 @@
3434
char isExe; /* True if executable */
3535
char isLink; /* True if symlink */
3636
};
3737
#endif
3838
39
+/*
40
+** State information common to all import types.
41
+*/
42
+static struct {
43
+ const char *zTrunkName; /* Name of trunk branch */
44
+ const char *zBranchPre; /* Prepended to non-trunk branch names */
45
+ const char *zBranchSuf; /* Appended to non-trunk branch names */
46
+ const char *zTagPre; /* Prepended to non-trunk tag names */
47
+ const char *zTagSuf; /* Appended to non-trunk tag names */
48
+} gimport;
3949
4050
/*
4151
** State information about an on-going fast-import parse.
4252
*/
4353
static struct {
@@ -198,11 +208,12 @@
198208
static void finish_tag(void){
199209
Blob record, cksum;
200210
if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
201211
blob_zero(&record);
202212
blob_appendf(&record, "D %s\n", gg.zDate);
203
- blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom);
213
+ blob_appendf(&record, "T +%F%F%F %s\n", gimport.zTagPre, gg.zTag,
214
+ gimport.zTagSuf, gg.zFrom);
204215
blob_appendf(&record, "U %F\n", gg.zUser);
205216
md5sum_blob(&record, &cksum);
206217
blob_appendf(&record, "Z %b\n", &cksum);
207218
fast_insert_content(&record, 0, 0, 1);
208219
blob_reset(&cksum);
@@ -275,18 +286,21 @@
275286
276287
/* Add the required "T" cards to the manifest. Make sure they are added
277288
** in sorted order and without any duplicates. Otherwise, fossil will not
278289
** recognize the document as a valid manifest. */
279290
if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
280
- aTCard[nTCard++] = mprintf("T *branch * %F\n", gg.zBranch);
281
- aTCard[nTCard++] = mprintf("T *sym-%F *\n", gg.zBranch);
291
+ aTCard[nTCard++] = mprintf("T *branch * %F%F%F\n", gimport.zBranchPre,
292
+ gg.zBranch, gimport.zBranchSuf);
293
+ aTCard[nTCard++] = mprintf("T *sym-%F%F%F *\n", gimport.zBranchPre,
294
+ gg.zBranch, gimport.zBranchSuf);
282295
if( zFromBranch ){
283
- aTCard[nTCard++] = mprintf("T -sym-%F *\n", zFromBranch);
296
+ aTCard[nTCard++] = mprintf("T -sym-%F%F%F *\n", gimport.zBranchPre,
297
+ zFromBranch, gimport.zBranchSuf);
284298
}
285299
}
286300
if( gg.zFrom==0 ){
287
- aTCard[nTCard++] = mprintf("T *sym-trunk *\n");
301
+ aTCard[nTCard++] = mprintf("T *sym-%F *\n", gimport.zTrunkName);
288302
}
289303
qsort(aTCard, nTCard, sizeof(char *), string_cmp);
290304
for(i=0; i<nTCard; i++){
291305
if( i==0 || fossil_strcmp(aTCard[i-1], aTCard[i]) ){
292306
blob_appendf(&record, "%s", aTCard[i]);
@@ -313,11 +327,12 @@
313327
** This behavior seems like a bug in git-fast-export, but it is easier
314328
** to work around the problem than to fix git-fast-export.
315329
*/
316330
if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
317331
blob_appendf(&record, "D %s\n", gg.zDate);
318
- blob_appendf(&record, "T +sym-%F %s\n", gg.zBranch, gg.zPrevCheckin);
332
+ blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
333
+ gimport.zBranchSuf, gg.zPrevCheckin);
319334
blob_appendf(&record, "U %F\n", gg.zUser);
320335
md5sum_blob(&record, &cksum);
321336
blob_appendf(&record, "Z %b\n", &cksum);
322337
db_multi_exec(
323338
"INSERT OR REPLACE INTO xtag(tname, tcontent)"
@@ -749,11 +764,13 @@
749764
const char *zBranches; /* Name of branches folder in repo root */
750765
int lenBranches; /* String length of zBranches */
751766
const char *zTags; /* Name of tags folder in repo root */
752767
int lenTags; /* String length of zTags */
753768
Bag newBranches; /* Branches that were created in this revision */
754
- int incrFlag; /* Add svn-rev-nn tags on every checkin */
769
+ int revFlag; /* Add svn-rev-nn tags on every checkin */
770
+ const char *zRevPre; /* Prepended to revision tag names */
771
+ const char *zRevSuf; /* Appended to revision tag names */
755772
} gsvn;
756773
typedef struct {
757774
char *zKey;
758775
char *zVal;
759776
} KeyVal;
@@ -1018,47 +1035,57 @@
10181035
char *zParentBranch =
10191036
db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
10201037
parentBranch
10211038
);
10221039
blob_appendf(&manifest, "P %s\n", zParentUuid);
1023
- blob_appendf(&manifest, "T *branch * %F\n", zBranch);
1024
- blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
1025
- if( gsvn.incrFlag ){
1026
- blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
1040
+ blob_appendf(&manifest, "T *branch * %F%F%F\n", gimport.zBranchPre,
1041
+ zBranch, gimport.zBranchSuf);
1042
+ blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
1043
+ zBranch, gimport.zBranchSuf);
1044
+ if( gsvn.revFlag ){
1045
+ blob_appendf(&manifest, "T +sym-%Fr%d%F *\n", gimport.zTagPre,
1046
+ gsvn.rev, gimport.zTagSuf);
10271047
}
1028
- blob_appendf(&manifest, "T -sym-%F *\n", zParentBranch);
1048
+ blob_appendf(&manifest, "T -sym-%F%F%F *\n", gimport.zBranchPre,
1049
+ zParentBranch, gimport.zBranchSuf);
10291050
fossil_free(zParentBranch);
10301051
}else{
10311052
char *zMergeUuid = rid_to_uuid(mergeRid);
10321053
blob_appendf(&manifest, "P %s %s\n", zParentUuid, zMergeUuid);
1033
- if( gsvn.incrFlag ){
1034
- blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
1054
+ if( gsvn.revFlag ){
1055
+ blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
1056
+ gsvn.rev, gsvn.zRevSuf);
10351057
}
10361058
fossil_free(zMergeUuid);
10371059
}
10381060
fossil_free(zParentUuid);
10391061
}else{
1040
- blob_appendf(&manifest, "T *branch * %F\n", zBranch);
1041
- blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
1042
- if( gsvn.incrFlag ){
1043
- blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
1062
+ blob_appendf(&manifest, "T *branch * %F%F%F\n",
1063
+ gimport.zBranchPre, zBranch, gimport.zBranchSuf);
1064
+ blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
1065
+ zBranch, gimport.zBranchSuf);
1066
+ if( gsvn.revFlag ){
1067
+ blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre, gsvn.rev,
1068
+ gsvn.zRevSuf);
10441069
}
10451070
}
10461071
}else if( branchType==SVN_TAG ){
10471072
char *zParentUuid = rid_to_uuid(parentRid);
10481073
blob_reset(&manifest);
10491074
blob_appendf(&manifest, "D %s\n", gsvn.zDate);
1050
- blob_appendf(&manifest, "T +sym-%F %s\n", zBranch, zParentUuid);
1075
+ blob_appendf(&manifest, "T +sym-%F%F%F %s\n", gimport.zTagPre, zBranch,
1076
+ gimport.zTagSuf, zParentUuid);
10511077
fossil_free(zParentUuid);
10521078
}
10531079
}else{
10541080
char *zParentUuid = rid_to_uuid(parentRid);
10551081
blob_appendf(&manifest, "D %s\n", gsvn.zDate);
10561082
if( branchType!=SVN_TAG ){
10571083
blob_appendf(&manifest, "T +closed %s\n", zParentUuid);
10581084
}else{
1059
- blob_appendf(&manifest, "T -sym-%F %s\n", zBranch, zParentUuid);
1085
+ blob_appendf(&manifest, "T -sym-%F%F%F %s\n", gimport.zBranchPre,
1086
+ zBranch, gimport.zBranchSuf, zParentUuid);
10601087
}
10611088
fossil_free(zParentUuid);
10621089
}
10631090
if( gsvn.zUser ){
10641091
blob_appendf(&manifest, "U %F\n", gsvn.zUser);
@@ -1495,31 +1522,43 @@
14951522
**
14961523
** The following formats are currently understood by this command
14971524
**
14981525
** --git Import from the git-fast-export file format (default)
14991526
**
1500
-** --svn Import from the svnadmin-dump file format. The default
1527
+** --svn Import from the svnadmin-dump file format. The default
15011528
** behaviour (unless overridden by --flat) is to treat 3
15021529
** folders in the SVN root as special, following the
1503
-** common layout of SVN repositories. These are (by
1504
-** default) trunk/, branches/ and tags/
1530
+** common layout of SVN repositories. These are (by
1531
+** default) trunk/, branches/ and tags/. The SVN --deltas
1532
+** format is supported but not required.
15051533
** Options:
15061534
** --trunk FOLDER Name of trunk folder
15071535
** --branches FOLDER Name of branches folder
15081536
** --tags FOLDER Name of tags folder
15091537
** --base PATH Path to project root in repository
15101538
** --flat The whole dump is a single branch
1539
+** --rev-tags Tag each revision, implied by -i
1540
+** --no-rev-tags Disables tagging effect of -i
1541
+** --rename-rev PAT Rev tag names, default "svn-rev-%"
15111542
**
15121543
** Common Options:
1513
-** -i|--incremental allow importing into an existing repository
1514
-** -f|--force overwrite repository if already exists
1515
-** -q|--quiet omit progress output
1516
-** --no-rebuild skip the "rebuilding metadata" step
1517
-** --no-vacuum skip the final VACUUM of the database file
1544
+** -i|--incremental allow importing into an existing repository
1545
+** -f|--force overwrite repository if already exists
1546
+** -q|--quiet omit progress output
1547
+** --no-rebuild skip the "rebuilding metadata" step
1548
+** --no-vacuum skip the final VACUUM of the database file
1549
+** --rename-trunk NAME use NAME as name of imported trunk branch
1550
+** --rename-branch PAT rename all branch names using PAT pattern
1551
+** --rename-tag PAT rename all tag names using PAT pattern
15181552
**
15191553
** The --incremental option allows an existing repository to be extended
1520
-** with new content.
1554
+** with new content. The --rename-* options may be useful to avoid name
1555
+** conflicts when using the --incremental option.
1556
+**
1557
+** The argument to --rename-* contains one "%" character to be replaced
1558
+** with the original name. For example, "--rename-tag svn-%-tag" renames
1559
+** the tag called "release" to "svn-release-tag".
15211560
**
15221561
** See also: export
15231562
*/
15241563
void import_cmd(void){
15251564
char *zPassword;
@@ -1534,21 +1573,56 @@
15341573
int incrFlag = find_option("incremental", "i", 0)!=0;
15351574
15361575
/* Options for --svn only */
15371576
const char *zBase="";
15381577
int flatFlag=0;
1578
+
1579
+ /* Interpret --rename-* options. Use a table to avoid code duplication. */
1580
+ const struct {
1581
+ const char *zOpt, **varPre, *zDefaultPre, **varSuf, *zDefaultSuf;
1582
+ int format; /* 1=git, 2=svn, 3=any */
1583
+ } renOpts[] = {
1584
+ {"rename-branch", &gimport.zBranchPre, "", &gimport.zBranchSuf, "", 3},
1585
+ {"rename-tag" , &gimport.zTagPre , "", &gimport.zTagSuf , "", 3},
1586
+ {"rename-rev" , &gsvn.zRevPre, "svn-rev-", &gsvn.zRevSuf , "", 2},
1587
+ }, *renOpt = renOpts;
1588
+ int i;
1589
+ for( i = 0; i < sizeof(renOpts) / sizeof(*renOpts); ++i, ++renOpt ){
1590
+ if( 1 << svnFlag & renOpt->format ){
1591
+ const char *zArgument = find_option(renOpt->zOpt, 0, 1);
1592
+ if( zArgument ){
1593
+ const char *sep = strchr(zArgument, '%');
1594
+ if( !sep ){
1595
+ fossil_fatal("missing '%%' in argument to --%s", renOpt->zOpt);
1596
+ }else if( strchr(sep + 1, '%') ){
1597
+ fossil_fatal("multiple '%%' in argument to --%s", renOpt->zOpt);
1598
+ }
1599
+ *renOpt->varPre = fossil_malloc(sep - zArgument + 1);
1600
+ memcpy((char *)*renOpt->varPre, zArgument, sep - zArgument);
1601
+ ((char *)*renOpt->varPre)[sep - zArgument] = 0;
1602
+ *renOpt->varSuf = sep + 1;
1603
+ }else{
1604
+ *renOpt->varPre = renOpt->zDefaultPre;
1605
+ *renOpt->varSuf = renOpt->zDefaultSuf;
1606
+ }
1607
+ }
1608
+ }
1609
+ if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
1610
+ gimport.zTrunkName = "trunk";
1611
+ }
15391612
15401613
if( svnFlag ){
1541
- /* Get --svn related options here, so verify_all_options() fail when svn
1542
- * only option are specify with --git
1614
+ /* Get --svn related options here, so verify_all_options() fails when
1615
+ * svn-only options are specified with --git
15431616
*/
15441617
zBase = find_option("base", 0, 1);
15451618
flatFlag = find_option("flat", 0, 0)!=0;
15461619
gsvn.zTrunk = find_option("trunk", 0, 1);
15471620
gsvn.zBranches = find_option("branches", 0, 1);
15481621
gsvn.zTags = find_option("tags", 0, 1);
1549
- gsvn.incrFlag = incrFlag;
1622
+ gsvn.revFlag = find_option("rev-tags", 0, 0)
1623
+ || (incrFlag && !find_option("no-rev-tags", 0, 0));
15501624
}else{
15511625
find_option("git",0,0); /* Skip the --git option for now */
15521626
}
15531627
verify_all_options();
15541628
15551629
--- src/import.c
+++ src/import.c
@@ -34,10 +34,20 @@
34 char isExe; /* True if executable */
35 char isLink; /* True if symlink */
36 };
37 #endif
38
 
 
 
 
 
 
 
 
 
 
39
40 /*
41 ** State information about an on-going fast-import parse.
42 */
43 static struct {
@@ -198,11 +208,12 @@
198 static void finish_tag(void){
199 Blob record, cksum;
200 if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
201 blob_zero(&record);
202 blob_appendf(&record, "D %s\n", gg.zDate);
203 blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom);
 
204 blob_appendf(&record, "U %F\n", gg.zUser);
205 md5sum_blob(&record, &cksum);
206 blob_appendf(&record, "Z %b\n", &cksum);
207 fast_insert_content(&record, 0, 0, 1);
208 blob_reset(&cksum);
@@ -275,18 +286,21 @@
275
276 /* Add the required "T" cards to the manifest. Make sure they are added
277 ** in sorted order and without any duplicates. Otherwise, fossil will not
278 ** recognize the document as a valid manifest. */
279 if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
280 aTCard[nTCard++] = mprintf("T *branch * %F\n", gg.zBranch);
281 aTCard[nTCard++] = mprintf("T *sym-%F *\n", gg.zBranch);
 
 
282 if( zFromBranch ){
283 aTCard[nTCard++] = mprintf("T -sym-%F *\n", zFromBranch);
 
284 }
285 }
286 if( gg.zFrom==0 ){
287 aTCard[nTCard++] = mprintf("T *sym-trunk *\n");
288 }
289 qsort(aTCard, nTCard, sizeof(char *), string_cmp);
290 for(i=0; i<nTCard; i++){
291 if( i==0 || fossil_strcmp(aTCard[i-1], aTCard[i]) ){
292 blob_appendf(&record, "%s", aTCard[i]);
@@ -313,11 +327,12 @@
313 ** This behavior seems like a bug in git-fast-export, but it is easier
314 ** to work around the problem than to fix git-fast-export.
315 */
316 if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
317 blob_appendf(&record, "D %s\n", gg.zDate);
318 blob_appendf(&record, "T +sym-%F %s\n", gg.zBranch, gg.zPrevCheckin);
 
319 blob_appendf(&record, "U %F\n", gg.zUser);
320 md5sum_blob(&record, &cksum);
321 blob_appendf(&record, "Z %b\n", &cksum);
322 db_multi_exec(
323 "INSERT OR REPLACE INTO xtag(tname, tcontent)"
@@ -749,11 +764,13 @@
749 const char *zBranches; /* Name of branches folder in repo root */
750 int lenBranches; /* String length of zBranches */
751 const char *zTags; /* Name of tags folder in repo root */
752 int lenTags; /* String length of zTags */
753 Bag newBranches; /* Branches that were created in this revision */
754 int incrFlag; /* Add svn-rev-nn tags on every checkin */
 
 
755 } gsvn;
756 typedef struct {
757 char *zKey;
758 char *zVal;
759 } KeyVal;
@@ -1018,47 +1035,57 @@
1018 char *zParentBranch =
1019 db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
1020 parentBranch
1021 );
1022 blob_appendf(&manifest, "P %s\n", zParentUuid);
1023 blob_appendf(&manifest, "T *branch * %F\n", zBranch);
1024 blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
1025 if( gsvn.incrFlag ){
1026 blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
 
 
 
1027 }
1028 blob_appendf(&manifest, "T -sym-%F *\n", zParentBranch);
 
1029 fossil_free(zParentBranch);
1030 }else{
1031 char *zMergeUuid = rid_to_uuid(mergeRid);
1032 blob_appendf(&manifest, "P %s %s\n", zParentUuid, zMergeUuid);
1033 if( gsvn.incrFlag ){
1034 blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
 
1035 }
1036 fossil_free(zMergeUuid);
1037 }
1038 fossil_free(zParentUuid);
1039 }else{
1040 blob_appendf(&manifest, "T *branch * %F\n", zBranch);
1041 blob_appendf(&manifest, "T *sym-%F *\n", zBranch);
1042 if( gsvn.incrFlag ){
1043 blob_appendf(&manifest, "T +sym-svn-rev-%d *\n", gsvn.rev);
 
 
 
1044 }
1045 }
1046 }else if( branchType==SVN_TAG ){
1047 char *zParentUuid = rid_to_uuid(parentRid);
1048 blob_reset(&manifest);
1049 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
1050 blob_appendf(&manifest, "T +sym-%F %s\n", zBranch, zParentUuid);
 
1051 fossil_free(zParentUuid);
1052 }
1053 }else{
1054 char *zParentUuid = rid_to_uuid(parentRid);
1055 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
1056 if( branchType!=SVN_TAG ){
1057 blob_appendf(&manifest, "T +closed %s\n", zParentUuid);
1058 }else{
1059 blob_appendf(&manifest, "T -sym-%F %s\n", zBranch, zParentUuid);
 
1060 }
1061 fossil_free(zParentUuid);
1062 }
1063 if( gsvn.zUser ){
1064 blob_appendf(&manifest, "U %F\n", gsvn.zUser);
@@ -1495,31 +1522,43 @@
1495 **
1496 ** The following formats are currently understood by this command
1497 **
1498 ** --git Import from the git-fast-export file format (default)
1499 **
1500 ** --svn Import from the svnadmin-dump file format. The default
1501 ** behaviour (unless overridden by --flat) is to treat 3
1502 ** folders in the SVN root as special, following the
1503 ** common layout of SVN repositories. These are (by
1504 ** default) trunk/, branches/ and tags/
 
1505 ** Options:
1506 ** --trunk FOLDER Name of trunk folder
1507 ** --branches FOLDER Name of branches folder
1508 ** --tags FOLDER Name of tags folder
1509 ** --base PATH Path to project root in repository
1510 ** --flat The whole dump is a single branch
 
 
 
1511 **
1512 ** Common Options:
1513 ** -i|--incremental allow importing into an existing repository
1514 ** -f|--force overwrite repository if already exists
1515 ** -q|--quiet omit progress output
1516 ** --no-rebuild skip the "rebuilding metadata" step
1517 ** --no-vacuum skip the final VACUUM of the database file
 
 
 
1518 **
1519 ** The --incremental option allows an existing repository to be extended
1520 ** with new content.
 
 
 
 
 
1521 **
1522 ** See also: export
1523 */
1524 void import_cmd(void){
1525 char *zPassword;
@@ -1534,21 +1573,56 @@
1534 int incrFlag = find_option("incremental", "i", 0)!=0;
1535
1536 /* Options for --svn only */
1537 const char *zBase="";
1538 int flatFlag=0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1539
1540 if( svnFlag ){
1541 /* Get --svn related options here, so verify_all_options() fail when svn
1542 * only option are specify with --git
1543 */
1544 zBase = find_option("base", 0, 1);
1545 flatFlag = find_option("flat", 0, 0)!=0;
1546 gsvn.zTrunk = find_option("trunk", 0, 1);
1547 gsvn.zBranches = find_option("branches", 0, 1);
1548 gsvn.zTags = find_option("tags", 0, 1);
1549 gsvn.incrFlag = incrFlag;
 
1550 }else{
1551 find_option("git",0,0); /* Skip the --git option for now */
1552 }
1553 verify_all_options();
1554
1555
--- src/import.c
+++ src/import.c
@@ -34,10 +34,20 @@
34 char isExe; /* True if executable */
35 char isLink; /* True if symlink */
36 };
37 #endif
38
39 /*
40 ** State information common to all import types.
41 */
42 static struct {
43 const char *zTrunkName; /* Name of trunk branch */
44 const char *zBranchPre; /* Prepended to non-trunk branch names */
45 const char *zBranchSuf; /* Appended to non-trunk branch names */
46 const char *zTagPre; /* Prepended to non-trunk tag names */
47 const char *zTagSuf; /* Appended to non-trunk tag names */
48 } gimport;
49
50 /*
51 ** State information about an on-going fast-import parse.
52 */
53 static struct {
@@ -198,11 +208,12 @@
208 static void finish_tag(void){
209 Blob record, cksum;
210 if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
211 blob_zero(&record);
212 blob_appendf(&record, "D %s\n", gg.zDate);
213 blob_appendf(&record, "T +%F%F%F %s\n", gimport.zTagPre, gg.zTag,
214 gimport.zTagSuf, gg.zFrom);
215 blob_appendf(&record, "U %F\n", gg.zUser);
216 md5sum_blob(&record, &cksum);
217 blob_appendf(&record, "Z %b\n", &cksum);
218 fast_insert_content(&record, 0, 0, 1);
219 blob_reset(&cksum);
@@ -275,18 +286,21 @@
286
287 /* Add the required "T" cards to the manifest. Make sure they are added
288 ** in sorted order and without any duplicates. Otherwise, fossil will not
289 ** recognize the document as a valid manifest. */
290 if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
291 aTCard[nTCard++] = mprintf("T *branch * %F%F%F\n", gimport.zBranchPre,
292 gg.zBranch, gimport.zBranchSuf);
293 aTCard[nTCard++] = mprintf("T *sym-%F%F%F *\n", gimport.zBranchPre,
294 gg.zBranch, gimport.zBranchSuf);
295 if( zFromBranch ){
296 aTCard[nTCard++] = mprintf("T -sym-%F%F%F *\n", gimport.zBranchPre,
297 zFromBranch, gimport.zBranchSuf);
298 }
299 }
300 if( gg.zFrom==0 ){
301 aTCard[nTCard++] = mprintf("T *sym-%F *\n", gimport.zTrunkName);
302 }
303 qsort(aTCard, nTCard, sizeof(char *), string_cmp);
304 for(i=0; i<nTCard; i++){
305 if( i==0 || fossil_strcmp(aTCard[i-1], aTCard[i]) ){
306 blob_appendf(&record, "%s", aTCard[i]);
@@ -313,11 +327,12 @@
327 ** This behavior seems like a bug in git-fast-export, but it is easier
328 ** to work around the problem than to fix git-fast-export.
329 */
330 if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
331 blob_appendf(&record, "D %s\n", gg.zDate);
332 blob_appendf(&record, "T +sym-%F%F%F %s\n", gimport.zBranchPre, gg.zBranch,
333 gimport.zBranchSuf, gg.zPrevCheckin);
334 blob_appendf(&record, "U %F\n", gg.zUser);
335 md5sum_blob(&record, &cksum);
336 blob_appendf(&record, "Z %b\n", &cksum);
337 db_multi_exec(
338 "INSERT OR REPLACE INTO xtag(tname, tcontent)"
@@ -749,11 +764,13 @@
764 const char *zBranches; /* Name of branches folder in repo root */
765 int lenBranches; /* String length of zBranches */
766 const char *zTags; /* Name of tags folder in repo root */
767 int lenTags; /* String length of zTags */
768 Bag newBranches; /* Branches that were created in this revision */
769 int revFlag; /* Add svn-rev-nn tags on every checkin */
770 const char *zRevPre; /* Prepended to revision tag names */
771 const char *zRevSuf; /* Appended to revision tag names */
772 } gsvn;
773 typedef struct {
774 char *zKey;
775 char *zVal;
776 } KeyVal;
@@ -1018,47 +1035,57 @@
1035 char *zParentBranch =
1036 db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
1037 parentBranch
1038 );
1039 blob_appendf(&manifest, "P %s\n", zParentUuid);
1040 blob_appendf(&manifest, "T *branch * %F%F%F\n", gimport.zBranchPre,
1041 zBranch, gimport.zBranchSuf);
1042 blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
1043 zBranch, gimport.zBranchSuf);
1044 if( gsvn.revFlag ){
1045 blob_appendf(&manifest, "T +sym-%Fr%d%F *\n", gimport.zTagPre,
1046 gsvn.rev, gimport.zTagSuf);
1047 }
1048 blob_appendf(&manifest, "T -sym-%F%F%F *\n", gimport.zBranchPre,
1049 zParentBranch, gimport.zBranchSuf);
1050 fossil_free(zParentBranch);
1051 }else{
1052 char *zMergeUuid = rid_to_uuid(mergeRid);
1053 blob_appendf(&manifest, "P %s %s\n", zParentUuid, zMergeUuid);
1054 if( gsvn.revFlag ){
1055 blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
1056 gsvn.rev, gsvn.zRevSuf);
1057 }
1058 fossil_free(zMergeUuid);
1059 }
1060 fossil_free(zParentUuid);
1061 }else{
1062 blob_appendf(&manifest, "T *branch * %F%F%F\n",
1063 gimport.zBranchPre, zBranch, gimport.zBranchSuf);
1064 blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
1065 zBranch, gimport.zBranchSuf);
1066 if( gsvn.revFlag ){
1067 blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre, gsvn.rev,
1068 gsvn.zRevSuf);
1069 }
1070 }
1071 }else if( branchType==SVN_TAG ){
1072 char *zParentUuid = rid_to_uuid(parentRid);
1073 blob_reset(&manifest);
1074 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
1075 blob_appendf(&manifest, "T +sym-%F%F%F %s\n", gimport.zTagPre, zBranch,
1076 gimport.zTagSuf, zParentUuid);
1077 fossil_free(zParentUuid);
1078 }
1079 }else{
1080 char *zParentUuid = rid_to_uuid(parentRid);
1081 blob_appendf(&manifest, "D %s\n", gsvn.zDate);
1082 if( branchType!=SVN_TAG ){
1083 blob_appendf(&manifest, "T +closed %s\n", zParentUuid);
1084 }else{
1085 blob_appendf(&manifest, "T -sym-%F%F%F %s\n", gimport.zBranchPre,
1086 zBranch, gimport.zBranchSuf, zParentUuid);
1087 }
1088 fossil_free(zParentUuid);
1089 }
1090 if( gsvn.zUser ){
1091 blob_appendf(&manifest, "U %F\n", gsvn.zUser);
@@ -1495,31 +1522,43 @@
1522 **
1523 ** The following formats are currently understood by this command
1524 **
1525 ** --git Import from the git-fast-export file format (default)
1526 **
1527 ** --svn Import from the svnadmin-dump file format. The default
1528 ** behaviour (unless overridden by --flat) is to treat 3
1529 ** folders in the SVN root as special, following the
1530 ** common layout of SVN repositories. These are (by
1531 ** default) trunk/, branches/ and tags/. The SVN --deltas
1532 ** format is supported but not required.
1533 ** Options:
1534 ** --trunk FOLDER Name of trunk folder
1535 ** --branches FOLDER Name of branches folder
1536 ** --tags FOLDER Name of tags folder
1537 ** --base PATH Path to project root in repository
1538 ** --flat The whole dump is a single branch
1539 ** --rev-tags Tag each revision, implied by -i
1540 ** --no-rev-tags Disables tagging effect of -i
1541 ** --rename-rev PAT Rev tag names, default "svn-rev-%"
1542 **
1543 ** Common Options:
1544 ** -i|--incremental allow importing into an existing repository
1545 ** -f|--force overwrite repository if already exists
1546 ** -q|--quiet omit progress output
1547 ** --no-rebuild skip the "rebuilding metadata" step
1548 ** --no-vacuum skip the final VACUUM of the database file
1549 ** --rename-trunk NAME use NAME as name of imported trunk branch
1550 ** --rename-branch PAT rename all branch names using PAT pattern
1551 ** --rename-tag PAT rename all tag names using PAT pattern
1552 **
1553 ** The --incremental option allows an existing repository to be extended
1554 ** with new content. The --rename-* options may be useful to avoid name
1555 ** conflicts when using the --incremental option.
1556 **
1557 ** The argument to --rename-* contains one "%" character to be replaced
1558 ** with the original name. For example, "--rename-tag svn-%-tag" renames
1559 ** the tag called "release" to "svn-release-tag".
1560 **
1561 ** See also: export
1562 */
1563 void import_cmd(void){
1564 char *zPassword;
@@ -1534,21 +1573,56 @@
1573 int incrFlag = find_option("incremental", "i", 0)!=0;
1574
1575 /* Options for --svn only */
1576 const char *zBase="";
1577 int flatFlag=0;
1578
1579 /* Interpret --rename-* options. Use a table to avoid code duplication. */
1580 const struct {
1581 const char *zOpt, **varPre, *zDefaultPre, **varSuf, *zDefaultSuf;
1582 int format; /* 1=git, 2=svn, 3=any */
1583 } renOpts[] = {
1584 {"rename-branch", &gimport.zBranchPre, "", &gimport.zBranchSuf, "", 3},
1585 {"rename-tag" , &gimport.zTagPre , "", &gimport.zTagSuf , "", 3},
1586 {"rename-rev" , &gsvn.zRevPre, "svn-rev-", &gsvn.zRevSuf , "", 2},
1587 }, *renOpt = renOpts;
1588 int i;
1589 for( i = 0; i < sizeof(renOpts) / sizeof(*renOpts); ++i, ++renOpt ){
1590 if( 1 << svnFlag & renOpt->format ){
1591 const char *zArgument = find_option(renOpt->zOpt, 0, 1);
1592 if( zArgument ){
1593 const char *sep = strchr(zArgument, '%');
1594 if( !sep ){
1595 fossil_fatal("missing '%%' in argument to --%s", renOpt->zOpt);
1596 }else if( strchr(sep + 1, '%') ){
1597 fossil_fatal("multiple '%%' in argument to --%s", renOpt->zOpt);
1598 }
1599 *renOpt->varPre = fossil_malloc(sep - zArgument + 1);
1600 memcpy((char *)*renOpt->varPre, zArgument, sep - zArgument);
1601 ((char *)*renOpt->varPre)[sep - zArgument] = 0;
1602 *renOpt->varSuf = sep + 1;
1603 }else{
1604 *renOpt->varPre = renOpt->zDefaultPre;
1605 *renOpt->varSuf = renOpt->zDefaultSuf;
1606 }
1607 }
1608 }
1609 if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
1610 gimport.zTrunkName = "trunk";
1611 }
1612
1613 if( svnFlag ){
1614 /* Get --svn related options here, so verify_all_options() fails when
1615 * svn-only options are specified with --git
1616 */
1617 zBase = find_option("base", 0, 1);
1618 flatFlag = find_option("flat", 0, 0)!=0;
1619 gsvn.zTrunk = find_option("trunk", 0, 1);
1620 gsvn.zBranches = find_option("branches", 0, 1);
1621 gsvn.zTags = find_option("tags", 0, 1);
1622 gsvn.revFlag = find_option("rev-tags", 0, 0)
1623 || (incrFlag && !find_option("no-rev-tags", 0, 0));
1624 }else{
1625 find_option("git",0,0); /* Skip the --git option for now */
1626 }
1627 verify_all_options();
1628
1629

Keyboard Shortcuts

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