Fossil

Check-in [e25884d4]
Login

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

Overview
Comment:Export works for Fossil and SQLite repositories. Does not yet export tags. Also need to add incremental export.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: e25884d44f59221a6ab89404db8206d6863b16a2
User & Date: drh 2010-11-08 23:26:48
Original Comment: Export works for Fossil and SQLite repositories. Does not yet export tags. Also need to add incremental export.
Context
2010-11-09
11:05
Merge the import/export changes into trunk. Even though they are incomplete, they do not threaten the correctness of other commands and can be developed in trunk. check-in: 0f024d3e user: drh tags: trunk
2010-11-08
23:26
Export works for Fossil and SQLite repositories. Does not yet export tags. Also need to add incremental export. Closed-Leaf check-in: e25884d4 user: drh tags: experimental
20:07
Merge in the [696668aa4ec88213c] fix, which is necessary to successfully export the Fossil self-hosting repository. check-in: 95f709cd user: drh tags: experimental
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/export.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
..
94
95
96
97
98
99
100



101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
...
129
130
131
132
133
134
135

136
137

138

139




140



141
142
143
144

145
146



147
148
149
150

151

152

153
154
155
156
157
158
159


160
#include "config.h"
#include "export.h"
#include <assert.h>

/*
** Output a "committer" record for the given user.
*/
static void print_committer(const char *zUser){
  static Stmt q;
  const char *zContact;
  char *zName;
  char *zEmail;
  int i, j;

  if( zUser==0 ){
    printf("committer unknown <unknown>");
    return;
  }
  db_static_prepare(&q, "SELECT info FROM user WHERE login=:user");
  db_bind_text(&q, ":user", zUser);
  if( db_step(&q)!=SQLITE_ROW ){
    db_reset(&q);
    for(i=0; zUser[i] && zUser[i]!='>' && zUser[i]!='<'; i++){}
    if( zUser[i]==0 ){
      printf("committer %s <unknown>", zUser);
      return;
    }
    zName = mprintf("%s", zUser);
    for(i=j=0; zName[i]; i++){
      if( zName[i]!='<' && zName[i]!='>' ){
        zName[j++] = zName[i];
      }
    }
    zName[j] = 0;
    printf("committer %s <unknown>", zName);
    free(zName);
    return;
  }
  zContact = db_column_text(&q, 0);
  for(i=0; zContact[i] && zContact[i]!='>' && zContact[i]!='<'; i++){}
  if( zContact[i]==0 ){
    printf("committer %s <unknown>", zContact);
    db_reset(&q);
    return;
  }
  if( zContact[i]=='<' ){
    zEmail = mprintf("%s", &zContact[i]);
    for(i=0; zEmail[i] && zEmail[i]!='>'; i++){}
    if( zEmail[i]=='>' ) zEmail[i+1] = 0;
  }else{
    zEmail = mprintf("<unknown");
  }
  zName = mprintf("%.*s", i, zContact);
  for(i=j=0; zName[i]; i++){
    if( zName[i]!='"' ) zName[j++] = zName[i];
  }
  zName[j] = 0;
  printf("committer %s %s", zName, zEmail);
  free(zName);
  free(zEmail);
  db_reset(&q);
}


/*
................................................................................
**
** Only check-ins are exported.  Git does not support tickets or wiki
** or events or attachments, so none of that is exported.
*/
void export_cmd(void){
  Stmt q;
  int i;




  db_find_and_open_repository(1);

  /* Step 1:  Generate "blob" records for every artifact that is part
  ** of a check-in 
  */
  db_prepare(&q, "SELECT DISTINCT fid FROM mlink");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    Blob content;
    content_get(rid, &content);
    printf("blob\nmark :%d\ndata %d\n", rid, blob_size(&content));

    fwrite(blob_buffer(&content), 1, blob_size(&content), stdout);
    printf("\n");
    blob_reset(&content);
  }
  db_finalize(&q);

  /* Output the commit records.
................................................................................
  );
  while( db_step(&q)==SQLITE_ROW ){
    sqlite3_int64 secondsSince1970 = db_column_int64(&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);

    Manifest *p;
    ManifestFile *pFile;



    if( zBranch==0 ) zBranch = "trunk";




    printf("commit refs/heads/%s\nmark :%d\n", zBranch, ckinId);



    print_committer(zUser); printf(" %lld +0000\n", secondsSince1970);
    if( zComment==0 ) zComment = "null comment";
    printf("data %d\n%s\n", strlen(zComment), zComment);
    p = manifest_get(ckinId, CFTYPE_ANY);

    for(i=0; i<p->nParent; i++){
      printf("%s :%d\n", (i?"merge":"from"), fast_uuid_to_rid(p->azParent[i]));



    }
    printf("deleteall\n");
    manifest_file_rewind(p);
    while( (pFile=manifest_file_next(p, 0))!=0 ){

      const char *zPerm = "100644";

      if( pFile->zPerm && strstr(pFile->zPerm,"x") ) zPerm = "100755";

      printf("M %s :%d %s\n",
             zPerm, fast_uuid_to_rid(pFile->zUuid), pFile->zName);
    }
    manifest_destroy(p);
    printf("\n");
  }
  db_finalize(&q);


}







|







|








|









|






|








|






|







 







>
>
>






|





>







 







>


>

>

>
>
>
>
|
>
>
>
|



>

|
>
>
>




>

>

>
|
<





>
>

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182
#include "config.h"
#include "export.h"
#include <assert.h>

/*
** Output a "committer" record for the given user.
*/
static void print_person(const char *zUser){
  static Stmt q;
  const char *zContact;
  char *zName;
  char *zEmail;
  int i, j;

  if( zUser==0 ){
    printf(" <unknown>");
    return;
  }
  db_static_prepare(&q, "SELECT info FROM user WHERE login=:user");
  db_bind_text(&q, ":user", zUser);
  if( db_step(&q)!=SQLITE_ROW ){
    db_reset(&q);
    for(i=0; zUser[i] && zUser[i]!='>' && zUser[i]!='<'; i++){}
    if( zUser[i]==0 ){
      printf(" <%s>", zUser);
      return;
    }
    zName = mprintf("%s", zUser);
    for(i=j=0; zName[i]; i++){
      if( zName[i]!='<' && zName[i]!='>' ){
        zName[j++] = zName[i];
      }
    }
    zName[j] = 0;
    printf(" %s <%s>", zName, zUser);
    free(zName);
    return;
  }
  zContact = db_column_text(&q, 0);
  for(i=0; zContact[i] && zContact[i]!='>' && zContact[i]!='<'; i++){}
  if( zContact[i]==0 ){
    printf(" %s <%s>", zContact, zUser);
    db_reset(&q);
    return;
  }
  if( zContact[i]=='<' ){
    zEmail = mprintf("%s", &zContact[i]);
    for(i=0; zEmail[i] && zEmail[i]!='>'; i++){}
    if( zEmail[i]=='>' ) zEmail[i+1] = 0;
  }else{
    zEmail = mprintf("<%s>", zUser);
  }
  zName = mprintf("%.*s", i, zContact);
  for(i=j=0; zName[i]; i++){
    if( zName[i]!='"' ) zName[j++] = zName[i];
  }
  zName[j] = 0;
  printf(" %s %s", zName, zEmail);
  free(zName);
  free(zEmail);
  db_reset(&q);
}


/*
................................................................................
**
** Only check-ins are exported.  Git does not support tickets or wiki
** or events or attachments, so none of that is exported.
*/
void export_cmd(void){
  Stmt q;
  int i;
  Bag blobs, vers;
  bag_init(&blobs);
  bag_init(&vers);

  db_find_and_open_repository(1);

  /* Step 1:  Generate "blob" records for every artifact that is part
  ** of a check-in 
  */
  db_prepare(&q, "SELECT DISTINCT fid FROM mlink WHERE fid>0");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    Blob content;
    content_get(rid, &content);
    printf("blob\nmark :%d\ndata %d\n", rid, blob_size(&content));
    bag_insert(&blobs, rid);
    fwrite(blob_buffer(&content), 1, blob_size(&content), stdout);
    printf("\n");
    blob_reset(&content);
  }
  db_finalize(&q);

  /* Output the commit records.
................................................................................
  );
  while( db_step(&q)==SQLITE_ROW ){
    sqlite3_int64 secondsSince1970 = db_column_int64(&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;
    Manifest *p;
    ManifestFile *pFile;
    const char *zFromType;

    bag_insert(&vers, ckinId);
    if( zBranch==0 ) zBranch = "trunk";
    zBr = mprintf("%s", zBranch);
    for(i=0; zBr[i]; i++){
      if( !fossil_isalnum(zBr[i]) ) zBr[i] = '_';
    }
    printf("commit refs/heads/%s\nmark :%d\n", zBr, ckinId);
    free(zBr);
    printf("committer");
    print_person(zUser);
    printf(" %lld +0000\n", secondsSince1970);
    if( zComment==0 ) zComment = "null comment";
    printf("data %d\n%s\n", strlen(zComment), zComment);
    p = manifest_get(ckinId, CFTYPE_ANY);
    zFromType = "from";
    for(i=0; i<p->nParent; i++){
      int pid = fast_uuid_to_rid(p->azParent[i]);
      if( pid==0 || !bag_find(&vers, pid) ) continue;
      printf("%s :%d\n", zFromType, fast_uuid_to_rid(p->azParent[i]));
      zFromType = "merge";
    }
    printf("deleteall\n");
    manifest_file_rewind(p);
    while( (pFile=manifest_file_next(p, 0))!=0 ){
      int fid = fast_uuid_to_rid(pFile->zUuid);
      const char *zPerm = "100644";
      if( fid==0 ) continue;
      if( pFile->zPerm && strstr(pFile->zPerm,"x") ) zPerm = "100755";
      if( !bag_find(&blobs, fid) ) continue;
      printf("M %s :%d %s\n", zPerm, fid, pFile->zName);

    }
    manifest_destroy(p);
    printf("\n");
  }
  db_finalize(&q);
  bag_clear(&blobs);
  bag_clear(&vers);
}