On 09/02/2017 15:06, Joerg Sonnenberger wrote: > On Thu, Feb 09, 2017 at 01:47:43PM +0000, Roy Marples wrote: >> Hi List! >> >> In fossil I have this: branch-1.7, tag-1.2 >> But when I export I get this: branch_1_7, tag_1_2 >> >> Why is the name mangled like so? Surely the original names should be >> preserved. > > It's currently preserving only alphanumeric characters. Noone ever > implemented the full sanitation requirement of git.
Attached is a patch with implements sanity checking as per https://git-scm.com/docs/git-check-ref-format Applies with my prior patch. Roy
Index: src/export.c ================================================================== --- src/export.c +++ src/export.c @@ -161,10 +161,68 @@ printf(" %s <%s>", zName, zEmail); free(zName); free(zEmail); db_reset(&q); } + +#define REFREPLACEMENT '_' + +/* +** Output a sanitized git named reference. +** https://git-scm.com/docs/git-check-ref-format +** This implementation assumes we are only printing +** the branch or tag part of the reference. +*/ +static void print_ref(const char *zRef){ + char *zEncoded = mprintf("%s", zRef); + int i, w; + if (zEncoded[0]=='@' && zEncoded[1]=='\0'){ + putchar(REFREPLACEMENT); + return; + } + for(i=0, w=0; zEncoded[i]; i++, w++){ + if( i!=0 ){ /* Two letter tests */ + if( (zEncoded[i-1]=='.' && zEncoded[i]=='.') || + (zEncoded[i-1]=='@' && zEncoded[i]=='{') ){ + zEncoded[w]=zEncoded[w-1]=REFREPLACEMENT; + continue; + } + if( zEncoded[i-1]=='/' && zEncoded[i]=='/' ){ + w--; /* Normalise to a single / by rolling back w */ + continue; + } + } + /* No control characters */ + if( (unsigned)zEncoded[i]<0x20 || zEncoded[i]==0x7f ){ + zEncoded[w]=REFREPLACEMENT; + continue; + } + switch( zEncoded[i] ){ + case ' ': + case '^': + case ':': + case '?': + case '*': + case '[': + case '\\': + zEncoded[w]=REFREPLACEMENT; + break; + } + } + /* Cannot begin with a . or / */ + if( zEncoded[0]=='.' || zEncoded[0] == '/' ) zEncoded[0]=REFREPLACEMENT; + if( i>0 ){ + i--; w--; + /* Or end with a . or / */ + if( zEncoded[i]=='.' || zEncoded[i] == '/' ) zEncoded[w]=REFREPLACEMENT; + /* Cannot end with .lock */ + if ( i>4 && strcmp((zEncoded+i)-5, ".lock")==0 ) + memset((zEncoded+w)-5, REFREPLACEMENT, 5); + } + printf("%s", zEncoded); + free(zEncoded); +} #define BLOBMARK(rid) ((rid) * 2) #define COMMITMARK(rid) ((rid) * 2 + 1) /* @@ -547,26 +605,22 @@ const char *zSecondsSince1970 = db_column_text(&q, 0); int ckinId = db_column_int(&q, 1); const char *zComment = db_column_text(&q, 2); const char *zUser = db_column_text(&q, 3); const char *zBranch = db_column_text(&q, 4); - char *zBr; char *zMark; bag_insert(&vers, ckinId); db_bind_int(&q2, ":rid", ckinId); db_step(&q2); db_reset(&q2); if( zBranch==0 ) zBranch = "trunk"; - zBr = mprintf("%s", zBranch); - for(i=0; zBr[i]; i++){ - if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_'; - } zMark = mark_name_from_rid(ckinId, &unused_mark); - printf("commit refs/heads/%s\nmark %s\n", zBr, zMark); + printf("commit refs/heads/"); + print_ref(zBranch); + printf("\nmark %s\n", zMark); free(zMark); - free(zBr); printf("committer"); print_person(zUser); printf(" %s +0000\n", zSecondsSince1970); if( zComment==0 ) zComment = "null comment"; printf("data %d\n%s\n", (int)strlen(zComment), zComment); @@ -637,30 +691,24 @@ " FROM tagxref JOIN tag USING(tagid)" " WHERE tagtype=1 AND tagname GLOB 'sym-*'" ); while( db_step(&q)==SQLITE_ROW ){ const char *zTagname = db_column_text(&q, 0); - char *zEncoded = 0; int rid = db_column_int(&q, 1); char *zMark = mark_name_from_rid(rid, &unused_mark); const char *zSecSince1970 = db_column_text(&q, 2); const char *zUser = db_column_text(&q, 3); - int i; if( rid==0 || !bag_find(&vers, rid) ) continue; zTagname += 4; - zEncoded = mprintf("%s", zTagname); - for(i=0; zEncoded[i]; i++){ - if( !fossil_isalnum(zEncoded[i]) ) zEncoded[i] = '_'; - } - printf("tag %s\n", zEncoded); - printf("from %s\n", zMark); + printf("tag "); + print_ref(zTagname); + printf("\nfrom %s\n", zMark); free(zMark); printf("tagger"); print_person(zUser); printf(" %s +0000\n", zSecSince1970); printf("data 0\n"); - fossil_free(zEncoded); } db_finalize(&q); if( markfile_out!=0 ){ FILE *f;
_______________________________________________ fossil-users mailing list fossil-users@lists.fossil-scm.org http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users