Fossil

Check-in [4a480954]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix the export so that it is able to handle phantom check-ins.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | mirror-cmd
Files: files | file ages | folders
SHA3-256: 4a480954e7335eeab0e8dfa7c3b481d92cba718f987dfdcf555d1f0f5fc9dec4
User & Date: drh 2019-03-14 19:43:04.926
Context
2019-03-14
20:16
The mirror command is now able to export all of Fossil itself, though tags are still not exported. ... (check-in: a3471a5e user: drh tags: mirror-cmd)
19:43
Fix the export so that it is able to handle phantom check-ins. ... (check-in: 4a480954 user: drh tags: mirror-cmd)
18:55
Sanitize branch names to conform to Git restrictions. ... (check-in: 11bcc4eb user: drh tags: mirror-cmd)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/export.c.
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963

964
965
966
967
968
969
970
971
972
static void mirror_send_checkin(
  FILE *xCmd,           /* Write fast-import text on this pipe */
  int rid,              /* BLOB.RID for the check-in to export */
  const char *zUuid,    /* BLOB.UUID for the check-in to export */
  int *pnLimit          /* Stop when the counter reaches zero */
){
  Manifest *pMan;
  int i;
  Blob err;
  Stmt q;
  char *zBranch;
  int iMark;
  Blob sql;

  blob_init(&err, 0, 0);
  pMan = manifest_get(rid, CFTYPE_MANIFEST, &err);
  if( pMan==0 ){

    fossil_fatal("cannot fetch manifest for check-in %d: %s", rid, 
                 blob_str(&err));
  }

  /* Check to see if any parent logins have not yet been processed, and
  ** if so, create them */
  for(i=0; i<pMan->nParent; i++){
    int iMark = mirror_find_mark(pMan->azParent[i], 0);
    if( iMark<=0 ){







|
<





<
|

>
|
|







947
948
949
950
951
952
953
954

955
956
957
958
959

960
961
962
963
964
965
966
967
968
969
970
971
static void mirror_send_checkin(
  FILE *xCmd,           /* Write fast-import text on this pipe */
  int rid,              /* BLOB.RID for the check-in to export */
  const char *zUuid,    /* BLOB.UUID for the check-in to export */
  int *pnLimit          /* Stop when the counter reaches zero */
){
  Manifest *pMan;
  int i, iParent;

  Stmt q;
  char *zBranch;
  int iMark;
  Blob sql;


  pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( pMan==0 ){
    /* Must be a phantom.  Return without doing anything, and in particular
    ** without creating a mark for this check-in. */
    return;
  }

  /* Check to see if any parent logins have not yet been processed, and
  ** if so, create them */
  for(i=0; i<pMan->nParent; i++){
    int iMark = mirror_find_mark(pMan->azParent[i], 0);
    if( iMark<=0 ){
996
997
998
999
1000
1001
1002


1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017

1018
1019

1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
  zBranch = db_text(0,
    "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
    TAG_BRANCH, rid
  );
  if( fossil_strcmp(zBranch,"trunk")==0 ){
    fossil_free(zBranch);
    zBranch = mprintf("master");


  }else{
    mirror_sanitize_git_name(zBranch);
  }

  /* Export the check-in */
  fprintf(xCmd, "commit refs/head/%s\n", zBranch);
  fossil_free(zBranch);
  iMark = mirror_find_mark(zUuid, 1);
  fprintf(xCmd, "mark :%d\n", iMark);
  fprintf(xCmd, "committer %s <%s@noemail.net> %lld +0000\n",
     pMan->zUser, pMan->zUser, 
     (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
  );
  fprintf(xCmd, "data %d\n", (int)strlen(pMan->zComment));
  fprintf(xCmd, "%s\n", pMan->zComment);

  for(i=0; i<pMan->nParent; i++){
    int iOther = mirror_find_mark(pMan->azParent[i], 0);

    if( i==0 ){

      fprintf(xCmd, "from :%d\n", iOther);
    }else{
      fprintf(xCmd, "merge :%d\n", iOther);
    }
  }
  if( pMan->nParent ){
    db_prepare(&q,
      "SELECT filename FROM files_of_checkin(%Q)"
      " EXCEPT SELECT filename FROM files_of_checkin(%Q)",
      pMan->azParent[0], zUuid
    );
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(xCmd, "D %s\n", db_column_text(&q,0));
    }
    db_finalize(&q);
  }
  blob_init(&sql, 0, 0);







>
>















>


>
|
>





|



|







995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
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
  zBranch = db_text(0,
    "SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
    TAG_BRANCH, rid
  );
  if( fossil_strcmp(zBranch,"trunk")==0 ){
    fossil_free(zBranch);
    zBranch = mprintf("master");
  }else if( zBranch==0 ){
    zBranch = mprintf("unknown");
  }else{
    mirror_sanitize_git_name(zBranch);
  }

  /* Export the check-in */
  fprintf(xCmd, "commit refs/head/%s\n", zBranch);
  fossil_free(zBranch);
  iMark = mirror_find_mark(zUuid, 1);
  fprintf(xCmd, "mark :%d\n", iMark);
  fprintf(xCmd, "committer %s <%s@noemail.net> %lld +0000\n",
     pMan->zUser, pMan->zUser, 
     (sqlite3_int64)((pMan->rDate-2440587.5)*86400.0)
  );
  fprintf(xCmd, "data %d\n", (int)strlen(pMan->zComment));
  fprintf(xCmd, "%s\n", pMan->zComment);
  iParent = -1;  /* Which ancestor is the primary parent */
  for(i=0; i<pMan->nParent; i++){
    int iOther = mirror_find_mark(pMan->azParent[i], 0);
    if( iOther==0 ) continue;
    if( iParent<0 ){
      iParent = i;
      fprintf(xCmd, "from :%d\n", iOther);
    }else{
      fprintf(xCmd, "merge :%d\n", iOther);
    }
  }
  if( iParent>=0 ){
    db_prepare(&q,
      "SELECT filename FROM files_of_checkin(%Q)"
      " EXCEPT SELECT filename FROM files_of_checkin(%Q)",
      pMan->azParent[iParent], zUuid
    );
    while( db_step(&q)==SQLITE_ROW ){
      fprintf(xCmd, "D %s\n", db_column_text(&q,0));
    }
    db_finalize(&q);
  }
  blob_init(&sql, 0, 0);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
  FILE *xCmd;
  FILE *pIn, *pOut;
  Stmt q;
  char zLine[200];

  find_option("git", 0, 0);   /* Ignore the --git option for now */
  zDebug = find_option("debug",0,1);
  db_find_and_open_repository(0, 2);
  zLimit = find_option("limit", 0, 1);
  if( zLimit ){
    nLimit = (unsigned int)atoi(zLimit);
    if( nLimit<=0 ) fossil_fatal("--limit must be positive");
  }
  verify_all_options();
  if( g.argc!=3 ){ usage("--git MIRROR"); }







|







1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
  FILE *xCmd;
  FILE *pIn, *pOut;
  Stmt q;
  char zLine[200];

  find_option("git", 0, 0);   /* Ignore the --git option for now */
  zDebug = find_option("debug",0,1);
  db_find_and_open_repository(0, 0);
  zLimit = find_option("limit", 0, 1);
  if( zLimit ){
    nLimit = (unsigned int)atoi(zLimit);
    if( nLimit<=0 ) fossil_fatal("--limit must be positive");
  }
  verify_all_options();
  if( g.argc!=3 ){ usage("--git MIRROR"); }