Fossil SCM

The mirror command is now able to export all of Fossil itself, though tags are still not exported.

drh 2019-03-14 20:16 UTC mirror-cmd
Commit a3471a5eef0b4764e316f15d478d990d0b176956e68857db03a94d999b398413
1 file changed +54 -9
+54 -9
--- src/export.c
+++ src/export.c
@@ -867,10 +867,49 @@
867867
|| (i>0 && zu[i-1]=='.')) ){
868868
zu[i] = '_';
869869
}
870870
}
871871
}
872
+
873
+/*
874
+** Quote a filename as a C-style string using \\ and \" if necessary.
875
+** If quoting is not necessary, just return a copy of the input string.
876
+**
877
+** The return value is a held in memory obtained from fossil_malloc()
878
+** and must be freed by the caller.
879
+*/
880
+static char *mirror_quote_filename_if_needed(const char *zIn){
881
+ int i, j;
882
+ char c;
883
+ int nSpecial = 0;
884
+ char *zOut;
885
+ for(i=0; (c = zIn[i])!=0; i++){
886
+ if( c=='\\' || c=='"' || c=='\n' ){
887
+ nSpecial++;
888
+ }
889
+ }
890
+ if( nSpecial==0 ){
891
+ return fossil_strdup(zIn);
892
+ }
893
+ zOut = fossil_malloc( i+nSpecial+3 );
894
+ zOut[0] = '"';
895
+ for(i=0, j=1; (c = zIn[i])!=0; i++){
896
+ if( c=='\\' || c=='"' || c=='\n' ){
897
+ zOut[j++] = '\\';
898
+ if( c=='\n' ){
899
+ zOut[j++] = 'n';
900
+ }else{
901
+ zOut[j++] = c;
902
+ }
903
+ }else{
904
+ zOut[j++] = c;
905
+ }
906
+ }
907
+ zOut[j++] = '"';
908
+ zOut[j] = 0;
909
+ return zOut;
910
+}
872911
873912
/*
874913
** Transfer a tag over to the mirror. "rid" is the BLOB.RID value for
875914
** the record that describes the tag.
876915
**
@@ -948,16 +987,18 @@
948987
FILE *xCmd, /* Write fast-import text on this pipe */
949988
int rid, /* BLOB.RID for the check-in to export */
950989
const char *zUuid, /* BLOB.UUID for the check-in to export */
951990
int *pnLimit /* Stop when the counter reaches zero */
952991
){
953
- Manifest *pMan;
954
- int i, iParent;
955
- Stmt q;
956
- char *zBranch;
957
- int iMark;
958
- Blob sql;
992
+ Manifest *pMan; /* The check-in to be output */
993
+ int i; /* Loop counter */
994
+ int iParent; /* Which immediate ancestor is primary. -1 for none */
995
+ Stmt q; /* An SQL query */
996
+ char *zBranch; /* The branch of the check-in */
997
+ int iMark; /* The mark for the check-in */
998
+ Blob sql; /* String of SQL for part of the query */
999
+ char *zCom; /* The check-in comment */
9591000
9601001
pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
9611002
if( pMan==0 ){
9621003
/* Must be a phantom. Return without doing anything, and in particular
9631004
** without creating a mark for this check-in. */
@@ -1012,12 +1053,13 @@
10121053
fprintf(xCmd, "mark :%d\n", iMark);
10131054
fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n",
10141055
pMan->zUser, pMan->zUser,
10151056
(sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
10161057
);
1017
- fprintf(xCmd, "data %d\n", (int)strlen(pMan->zComment));
1018
- fprintf(xCmd, "%s\n", pMan->zComment);
1058
+ zCom = pMan->zComment;
1059
+ if( zCom==0 ) zCom = "(no comment)";
1060
+ fprintf(xCmd, "data %d\n%s\n", (int)strlen(zCom), zCom);
10191061
iParent = -1; /* Which ancestor is the primary parent */
10201062
for(i=0; i<pMan->nParent; i++){
10211063
int iOther = mirror_find_mark(pMan->azParent[i], 0);
10221064
if( iOther==0 ) continue;
10231065
if( iParent<0 ){
@@ -1057,15 +1099,18 @@
10571099
while( db_step(&q)==SQLITE_ROW ){
10581100
const char *zFilename = db_column_text(&q,0);
10591101
const char *zMode = db_column_text(&q,1);
10601102
int iMark = db_column_int(&q,2);
10611103
const char *zGitMode = "100644";
1104
+ char *zFNQuoted = 0;
10621105
if( zMode ){
10631106
if( strchr(zMode,'x') ) zGitMode = "100755";
10641107
if( strchr(zMode,'l') ) zGitMode = "120000";
10651108
}
1066
- fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFilename);
1109
+ zFNQuoted = mirror_quote_filename_if_needed(zFilename);
1110
+ fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFNQuoted);
1111
+ fossil_free(zFNQuoted);
10671112
}
10681113
db_finalize(&q);
10691114
10701115
/* The check-in is finished, so decrement the counter */
10711116
(*pnLimit)--;
10721117
--- src/export.c
+++ src/export.c
@@ -867,10 +867,49 @@
867 || (i>0 && zu[i-1]=='.')) ){
868 zu[i] = '_';
869 }
870 }
871 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
872
873 /*
874 ** Transfer a tag over to the mirror. "rid" is the BLOB.RID value for
875 ** the record that describes the tag.
876 **
@@ -948,16 +987,18 @@
948 FILE *xCmd, /* Write fast-import text on this pipe */
949 int rid, /* BLOB.RID for the check-in to export */
950 const char *zUuid, /* BLOB.UUID for the check-in to export */
951 int *pnLimit /* Stop when the counter reaches zero */
952 ){
953 Manifest *pMan;
954 int i, iParent;
955 Stmt q;
956 char *zBranch;
957 int iMark;
958 Blob sql;
 
 
959
960 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
961 if( pMan==0 ){
962 /* Must be a phantom. Return without doing anything, and in particular
963 ** without creating a mark for this check-in. */
@@ -1012,12 +1053,13 @@
1012 fprintf(xCmd, "mark :%d\n", iMark);
1013 fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n",
1014 pMan->zUser, pMan->zUser,
1015 (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
1016 );
1017 fprintf(xCmd, "data %d\n", (int)strlen(pMan->zComment));
1018 fprintf(xCmd, "%s\n", pMan->zComment);
 
1019 iParent = -1; /* Which ancestor is the primary parent */
1020 for(i=0; i<pMan->nParent; i++){
1021 int iOther = mirror_find_mark(pMan->azParent[i], 0);
1022 if( iOther==0 ) continue;
1023 if( iParent<0 ){
@@ -1057,15 +1099,18 @@
1057 while( db_step(&q)==SQLITE_ROW ){
1058 const char *zFilename = db_column_text(&q,0);
1059 const char *zMode = db_column_text(&q,1);
1060 int iMark = db_column_int(&q,2);
1061 const char *zGitMode = "100644";
 
1062 if( zMode ){
1063 if( strchr(zMode,'x') ) zGitMode = "100755";
1064 if( strchr(zMode,'l') ) zGitMode = "120000";
1065 }
1066 fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFilename);
 
 
1067 }
1068 db_finalize(&q);
1069
1070 /* The check-in is finished, so decrement the counter */
1071 (*pnLimit)--;
1072
--- src/export.c
+++ src/export.c
@@ -867,10 +867,49 @@
867 || (i>0 && zu[i-1]=='.')) ){
868 zu[i] = '_';
869 }
870 }
871 }
872
873 /*
874 ** Quote a filename as a C-style string using \\ and \" if necessary.
875 ** If quoting is not necessary, just return a copy of the input string.
876 **
877 ** The return value is a held in memory obtained from fossil_malloc()
878 ** and must be freed by the caller.
879 */
880 static char *mirror_quote_filename_if_needed(const char *zIn){
881 int i, j;
882 char c;
883 int nSpecial = 0;
884 char *zOut;
885 for(i=0; (c = zIn[i])!=0; i++){
886 if( c=='\\' || c=='"' || c=='\n' ){
887 nSpecial++;
888 }
889 }
890 if( nSpecial==0 ){
891 return fossil_strdup(zIn);
892 }
893 zOut = fossil_malloc( i+nSpecial+3 );
894 zOut[0] = '"';
895 for(i=0, j=1; (c = zIn[i])!=0; i++){
896 if( c=='\\' || c=='"' || c=='\n' ){
897 zOut[j++] = '\\';
898 if( c=='\n' ){
899 zOut[j++] = 'n';
900 }else{
901 zOut[j++] = c;
902 }
903 }else{
904 zOut[j++] = c;
905 }
906 }
907 zOut[j++] = '"';
908 zOut[j] = 0;
909 return zOut;
910 }
911
912 /*
913 ** Transfer a tag over to the mirror. "rid" is the BLOB.RID value for
914 ** the record that describes the tag.
915 **
@@ -948,16 +987,18 @@
987 FILE *xCmd, /* Write fast-import text on this pipe */
988 int rid, /* BLOB.RID for the check-in to export */
989 const char *zUuid, /* BLOB.UUID for the check-in to export */
990 int *pnLimit /* Stop when the counter reaches zero */
991 ){
992 Manifest *pMan; /* The check-in to be output */
993 int i; /* Loop counter */
994 int iParent; /* Which immediate ancestor is primary. -1 for none */
995 Stmt q; /* An SQL query */
996 char *zBranch; /* The branch of the check-in */
997 int iMark; /* The mark for the check-in */
998 Blob sql; /* String of SQL for part of the query */
999 char *zCom; /* The check-in comment */
1000
1001 pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
1002 if( pMan==0 ){
1003 /* Must be a phantom. Return without doing anything, and in particular
1004 ** without creating a mark for this check-in. */
@@ -1012,12 +1053,13 @@
1053 fprintf(xCmd, "mark :%d\n", iMark);
1054 fprintf(xCmd, "committer %s <%[email protected]> %lld +0000\n",
1055 pMan->zUser, pMan->zUser,
1056 (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
1057 );
1058 zCom = pMan->zComment;
1059 if( zCom==0 ) zCom = "(no comment)";
1060 fprintf(xCmd, "data %d\n%s\n", (int)strlen(zCom), zCom);
1061 iParent = -1; /* Which ancestor is the primary parent */
1062 for(i=0; i<pMan->nParent; i++){
1063 int iOther = mirror_find_mark(pMan->azParent[i], 0);
1064 if( iOther==0 ) continue;
1065 if( iParent<0 ){
@@ -1057,15 +1099,18 @@
1099 while( db_step(&q)==SQLITE_ROW ){
1100 const char *zFilename = db_column_text(&q,0);
1101 const char *zMode = db_column_text(&q,1);
1102 int iMark = db_column_int(&q,2);
1103 const char *zGitMode = "100644";
1104 char *zFNQuoted = 0;
1105 if( zMode ){
1106 if( strchr(zMode,'x') ) zGitMode = "100755";
1107 if( strchr(zMode,'l') ) zGitMode = "120000";
1108 }
1109 zFNQuoted = mirror_quote_filename_if_needed(zFilename);
1110 fprintf(xCmd,"M %s :%d %s\n", zGitMode, iMark, zFNQuoted);
1111 fossil_free(zFNQuoted);
1112 }
1113 db_finalize(&q);
1114
1115 /* The check-in is finished, so decrement the counter */
1116 (*pnLimit)--;
1117

Keyboard Shortcuts

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