Fossil Forum

thebondo 2 weeks, 3 days ago

Post: Subversion import question

I have a subversion repository that I am working on importing into Fossil. The original repository is simple, there are no branches, just a single line of development with a single user commiting in a long linear sequence. So I am importing using the --flat option. The full command I use is

fossil import --svn --flat --base "path/prefix/" /new/fossil/repo /svn/dump/file

This works as expected. However, when reviewing the manifests of the checkins, I noticed something strange. The first checkin has T cards that set the branch to trunk. This makes sense to me.

T *branch * trunk
T *sym-trunk *

But then the next checkin has T cards like this

T *branch * trunk
T *sym-trunk *
T -sym-trunk *

This does not make sense to me. All of the checkins after the first one have this same set of T cards in the manifest. If I understand how tags work correctly, the T cards on all the checkins but the first are not necessary here, since they are effectively a no-op.

Assuming that is true, I looked into the source (from this checkin) and found the relevant code in the function svn_finish_revision of src/import.c (lines 1103 to 1130):

          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%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%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.revFlag ){
              blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
                  gsvn.rev, gsvn.zRevSuf);
            }
            fossil_free(zMergeUuid);
          }
          fossil_free(zParentUuid);

For my case, mergeRid is 0 for all the SVN revisions, so the first branch of if( parentRid==mergeRid || mergeRid==0){ is taken. Inside that branch, the T cards are unconditionally added. It seems like this could benefit from checking for branchId != parentBranch to conditionally add the T cards, like this:

          char *zParentUuid = rid_to_uuid(parentRid);
          if( parentRid==mergeRid || mergeRid==0){
            blob_appendf(&manifest, "P %s\n", zParentUuid);
            if (branchId != parentBranch) {
              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);
            }
            if (branchId != parentBranch) {
              char *zParentBranch =
                db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
                        parentBranch
                );
              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.revFlag ){
              blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
                  gsvn.rev, gsvn.zRevSuf);
            }
            fossil_free(zMergeUuid);
          }
          fossil_free(zParentUuid);

I am not fully aware of the meaning of parentRid and mergeRid here, so I am unsure if this is an appropriate change for more complex SVN repositories. My SVN repository has no merges. However, these changes works for me and the resulting fossil repository manifests do not have any superfluous T cards, just the required ones on the first checkin.

If it is helpful, I have attached a diff created using fossil diff -i.

thebondo 2 weeks, 3 days ago

I have a subversion repository that I am working on importing into Fossil. The original repository is simple, there are no branches, just a single line of development with a single user commiting in a long linear sequence. So I am importing using the --flat option. The full command I use is

fossil import --svn --flat --base "path/prefix/" /new/fossil/repo /svn/dump/file

This works as expected. However, when reviewing the manifests of the checkins, I noticed something strange. The first checkin has T cards that set the branch to trunk. This makes sense to me.

T *branch * trunk
T *sym-trunk *

But then the next checkin has T cards like this

T *branch * trunk
T *sym-trunk *
T -sym-trunk *

This does not make sense to me. All of the checkins after the first one have this same set of T cards in the manifest. If I understand how tags work correctly, the T cards on all the checkins but the first are not necessary here, since they are effectively a no-op.

Assuming that is true, I looked into the source (from this checkin) and found the relevant code in the function svn_finish_revision of src/import.c (lines 1103 to 1130):

          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%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%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.revFlag ){
              blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
                  gsvn.rev, gsvn.zRevSuf);
            }
            fossil_free(zMergeUuid);
          }
          fossil_free(zParentUuid);

For my case, mergeRid is 0 for all the SVN revisions, so the first branch of if( parentRid==mergeRid || mergeRid==0){ is taken. Inside that branch, the T cards are unconditionally added. It seems like this could benefit from checking for branchId != parentBranch to conditionally add the T cards, like this:

          char *zParentUuid = rid_to_uuid(parentRid);
          if( parentRid==mergeRid || mergeRid==0){
            blob_appendf(&manifest, "P %s\n", zParentUuid);
            if (branchId != parentBranch) {
              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);
            }
            if (branchId != parentBranch) {
              char *zParentBranch =
                db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
                        parentBranch
                );
              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.revFlag ){
              blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,
                  gsvn.rev, gsvn.zRevSuf);
            }
            fossil_free(zMergeUuid);
          }
          fossil_free(zParentUuid);

I am not fully aware of the meaning of parentRid and mergeRid here, so I am unsure if this is an appropriate change for more complex SVN repositories. My SVN repository has no merges. However, these changes works for me and the resulting fossil repository manifests do not have any superfluous T cards, just the required ones on the first checkin.

If it is helpful, here is a patch created using fossil diff -i.

Index: src/import.c
==================================================================
--- src/import.c
+++ src/import.c
@@ -1100,26 +1100,30 @@
       db_reset(&getFiles);
       if( !sameAsParent ){
         if( parentRid>0 ){
           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%F%F\n", gimport.zBranchPre,
-                zBranch, gimport.zBranchSuf);
-            blob_appendf(&manifest, "T *sym-%F%F%F *\n", gimport.zBranchPre,
-                zBranch, gimport.zBranchSuf);
+            if (branchId != parentBranch) {
+              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%F%F *\n", gimport.zBranchPre,
-                zParentBranch, gimport.zBranchSuf);
-            fossil_free(zParentBranch);
+            if (branchId != parentBranch) {
+              char *zParentBranch =
+                db_text(0, "SELECT tname FROM xbranches WHERE tid=%d",
+                        parentBranch
+                );
+              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.revFlag ){
               blob_appendf(&manifest, "T +sym-%F%d%F *\n", gsvn.zRevPre,

Keyboard Shortcuts

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