Fossil SCM

Partial implementation of the "fossil import" command. It is incomplete and does not work.

drh 2010-11-09 18:15 trunk
Commit ba837f5e88d182411e613be5408a94446d137274
1 file changed +326 -1
+326 -1
--- src/import.c
+++ src/import.c
@@ -20,10 +20,309 @@
2020
*/
2121
#include "config.h"
2222
#include "import.h"
2323
#include <assert.h>
2424
25
+/*
26
+** State information about an on-going fast-import parse.
27
+*/
28
+static struct {
29
+ void (*xFinish)(void); /* Function to finish a prior record */
30
+ int nData; /* Bytes of data */
31
+ char *zTag; /* Name of a tag */
32
+ char *zBranch; /* Name of a branch for a commit */
33
+ char *aData; /* Data content */
34
+ char *zMark; /* The current mark */
35
+ char *zDate; /* Date/time stamp */
36
+ char *zUser; /* User name */
37
+ char *zComment; /* Comment of a commit */
38
+ char *zFrom; /* from value */
39
+ int nMerge; /* Number of merge values */
40
+ int nMergeAlloc; /* Number of slots in azMerge[] */
41
+ char **azMerge; /* Merge values */
42
+ int nFile; /* Number of aFile values */
43
+ int nFileAlloc; /* Number of slots in aFile[] */
44
+ ManifestFile *aFile; /* Information about files in a commit */
45
+} gg;
46
+
47
+/*
48
+** A no-op "xFinish" method
49
+*/
50
+static void finish_noop(void){}
51
+
52
+/*
53
+** Deallocate the state information.
54
+**
55
+** The azMerge[] and aFile[] arrays are zeroed by allocated space is
56
+** retained unless the freeAll flag is set.
57
+*/
58
+static void import_reset(int freeAll){
59
+ int i;
60
+ gg.xFinish = 0;
61
+ fossil_free(gg.zTag); gg.zTag = 0;
62
+ fossil_free(gg.zBranch); gg.zBranch = 0;
63
+ fossil_free(gg.aData); gg.aData = 0;
64
+ fossil_free(gg.zMark); gg.zMark = 0;
65
+ fossil_free(gg.zDate); gg.zDate = 0;
66
+ fossil_free(gg.zUser); gg.zUser = 0;
67
+ fossil_free(gg.zComment); gg.zComment = 0;
68
+ fossil_free(gg.zFrom); gg.zFrom = 0;
69
+ for(i=0; i<gg.nMerge; i++){
70
+ fossil_free(gg.azMerge[i]); gg.azMerge[i] = 0;
71
+ }
72
+ gg.nMerge = 0;
73
+ for(i=0; i<gg.nFile; i++){
74
+ fossil_free(gg.aFile[i].zName);
75
+ fossil_free(gg.aFile[i].zUuid);
76
+ fossil_free(gg.aFile[i].zPerm);
77
+ fossil_free(gg.aFile[i].zPrior);
78
+ }
79
+ memset(gg.aFile, 0, gg.nFile*sizeof(gg.aFile[0]));
80
+ gg.nFile = 0;
81
+ if( freeAll ){
82
+ fossil_free(gg.azMerge);
83
+ fossil_free(gg.aFile);
84
+ memset(&gg, 0, sizeof(gg));
85
+ }
86
+ gg.xFinish = finish_noop;
87
+}
88
+
89
+/*
90
+** Insert an artifact into the BLOB table if it isn't there already.
91
+** If zMark is not zero, create a cross-reference from that mark back
92
+** to the newly inserted artifact.
93
+*/
94
+static int fast_insert_content(Blob *pContent, const char *zMark){
95
+ Blob hash;
96
+ Blob cmpr;
97
+ int rid;
98
+
99
+ sha1sum_blob(pContent, &hash);
100
+ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &hash);
101
+ if( rid==0 ){
102
+ static Stmt ins;
103
+ db_static_prepare(&ins,
104
+ "INSERT INTO blob(uuid, size, content) VALUES(:uuid, :size, :content)"
105
+ );
106
+ db_bind_text(&ins, ":uuid", blob_str(&hash));
107
+ db_bind_int(&ins, ":size", gg.nData);
108
+ blob_compress(pContent, &cmpr);
109
+ db_bind_blob(&ins, ":content", &cmpr);
110
+ db_step(&ins);
111
+ db_reset(&ins);
112
+ blob_reset(&cmpr);
113
+ rid = db_last_insert_rowid();
114
+ }
115
+ if( zMark ){
116
+ db_multi_exec(
117
+ "INSERT INTO xtag(tname, trid, tuuid)"
118
+ "VALUES(%Q,%d,%B)",
119
+ zMark, rid, &hash
120
+ );
121
+ db_multi_exec(
122
+ "INSERT INTO xtag(tname, trid, tuuid)"
123
+ "VALUES(%B,%d,%B)",
124
+ &hash, rid, &hash
125
+ );
126
+ }
127
+ blob_reset(&hash);
128
+ return rid;
129
+}
130
+
131
+/*
132
+** Use data accumulated in gg from a "blob" record to add a new file
133
+** to the BLOB table.
134
+*/
135
+static void finish_blob(void){
136
+ Blob content;
137
+
138
+ if( gg.nData>0 ){
139
+ blob_init(&content, gg.aData, gg.nData);
140
+ fast_insert_content(&content, gg.zMark);
141
+ blob_reset(&content);
142
+ }
143
+ import_reset(0);
144
+}
145
+
146
+/*
147
+** Use data accumulated in gg from a "tag" record to add a new
148
+** control artifact to the BLOB table.
149
+*/
150
+static void finish_tag(void){
151
+ Blob record, cksum;
152
+ if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
153
+ blob_zero(&record);
154
+ blob_appendf(&record, "D %z\n", gg.zDate);
155
+ blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom);
156
+ blob_appendf(&record, "U %F\n", gg.zUser);
157
+ md5sum_blob(&record, &cksum);
158
+ blob_appendf(&record, "Z %b\n", &cksum);
159
+ fast_insert_content(&record, 0);
160
+ blob_reset(&record);
161
+ blob_reset(&cksum);
162
+ }
163
+ import_reset(0);
164
+}
165
+
166
+/*
167
+** Use data accumulated in gg from a "commit" record to add a new
168
+** manifest artifact to the BLOB table.
169
+*/
170
+static void finish_commit(void){
171
+ /* TBD... */
172
+ import_reset(0);
173
+}
174
+
175
+
176
+/*
177
+** Turn the first \n in the input string into a \000
178
+*/
179
+static void trim_newline(char *z){
180
+ while( z[0] && z[0]!='\n' ){ z++; }
181
+ z[0] = 0;
182
+}
183
+
184
+/*
185
+** Convert a "mark" or "committish" into the UUID.
186
+*/
187
+static char *resolve_committish(const char *zCommittish){
188
+ char *zRes;
189
+
190
+ zRes = db_text(0, "SELECT tuuid FROM xtag WHERE tname=%Q", zCommittish);
191
+ return zRes;
192
+}
193
+
194
+
195
+/*
196
+** Read the git-fast-import format from pIn and insert the corresponding
197
+** content into the database.
198
+*/
199
+static void git_fast_import(FILE *pIn){
200
+ char zLine[1000];
201
+ gg.xFinish = finish_noop;
202
+ while( fgets(zLine, sizeof(zLine), pIn) ){
203
+ if( zLine[0]=='\n' || zLine[0]=='#' ) continue;
204
+ if( memcmp(zLine, "blob", 4)==0 ){
205
+ gg.xFinish();
206
+ gg.xFinish = finish_blob;
207
+ }else
208
+ if( memcmp(zLine, "commit ", 7)==0 ){
209
+ gg.xFinish();
210
+ gg.xFinish = finish_commit;
211
+ trim_newline(&zLine[7]);
212
+ gg.zBranch = mprintf("%s", &zLine[7]);
213
+ }else
214
+ if( memcmp(zLine, "tag ", 4)==0 ){
215
+ gg.xFinish();
216
+ gg.xFinish = finish_tag;
217
+ trim_newline(&zLine[4]);
218
+ gg.zTag = mprintf("%s", &zLine[4]);
219
+ }else
220
+ if( memcmp(zLine, "reset ", 4)==0 ){
221
+ gg.xFinish();
222
+ }else
223
+ if( memcmp(zLine, "checkpoint", 10)==0 ){
224
+ gg.xFinish();
225
+ }else
226
+ if( memcmp(zLine, "feature", 7)==0 ){
227
+ gg.xFinish();
228
+ }else
229
+ if( memcmp(zLine, "option", 6)==0 ){
230
+ gg.xFinish();
231
+ }else
232
+ if( memcmp(zLine, "progress ", 9)==0 ){
233
+ gg.xFinish();
234
+ trim_newline(&zLine[9]);
235
+ printf("%s\n", &zLine[9]);
236
+ fflush(stdout);
237
+ }else
238
+ if( memcmp(zLine, "data ", 5)==0 ){
239
+ fossil_free(gg.aData); gg.aData = 0;
240
+ gg.nData = atoi(&zLine[5]);
241
+ if( gg.nData ){
242
+ int got;
243
+ gg.aData = fossil_malloc( gg.nData+1 );
244
+ got = fread(gg.aData, 1, gg.nData, pIn);
245
+ if( got!=gg.nData ){
246
+ fossil_fatal("short read: got %d of %d bytes", got, gg.nData);
247
+ }
248
+ if( gg.zComment==0 && gg.xFinish==finish_commit ){
249
+ gg.zComment = gg.aData;
250
+ gg.aData = 0;
251
+ gg.nData = 0;
252
+ }
253
+ }
254
+ }else
255
+ if( memcmp(zLine, "author ", 7)==0 ){
256
+ /* No-op */
257
+ }else
258
+ if( memcmp(zLine, "mark ", 5)==0 ){
259
+ trim_newline(&zLine[5]);
260
+ fossil_free(gg.zMark);
261
+ gg.zMark = mprintf("%s", &zLine[5]);
262
+ }else
263
+ if( memcmp(zLine, "tagger ", 7)==0 || memcmp(zLine, "committer ",9)==0 ){
264
+ int i;
265
+ char *z;
266
+ sqlite3_int64 secSince1970;
267
+
268
+ for(i=0; zLine[i] && zLine[i]!='<'; i++){}
269
+ if( zLine[i]==0 ) goto malformed_line;
270
+ z = &zLine[i+1];
271
+ for(i=i+1; zLine[i] && zLine[i]!='>'; i++){}
272
+ if( zLine[i]==0 ) goto malformed_line;
273
+ zLine[i] = 0;
274
+ fossil_free(gg.zUser);
275
+ gg.zUser = mprintf("%s", z);
276
+ secSince1970 = 0;
277
+ for(i=i+1; fossil_isdigit(zLine[i]); i++){
278
+ secSince1970 = secSince1970*10 + zLine[i] - '0';
279
+ }
280
+ fossil_free(gg.zDate);
281
+ gg.zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", secSince1970);
282
+ gg.zDate[10] = 'T';
283
+ }else
284
+ if( memcmp(zLine, "from ", 5)==0 ){
285
+ trim_newline(&zLine[5]);
286
+ fossil_free(gg.zFrom);
287
+ gg.zFrom = resolve_committish(&zLine[5]);
288
+ }else
289
+ if( memcmp(zLine, "merge ", 6)==0 ){
290
+ trim_newline(&zLine[6]);
291
+ if( gg.nMerge>=gg.nMergeAlloc ){
292
+ gg.nMergeAlloc = gg.nMergeAlloc*2 + 10;
293
+ gg.azMerge = fossil_realloc(gg.azMerge, gg.nMergeAlloc*sizeof(char*));
294
+ }
295
+ gg.azMerge[gg.nMerge] = resolve_committish(&zLine[5]);
296
+ if( gg.azMerge[gg.nMerge] ) gg.nMerge++;
297
+ }else
298
+ if( memcmp(zLine, "M ", 2)==0 ){
299
+ }else
300
+ if( memcmp(zLine, "D ", 2)==0 ){
301
+ }else
302
+ if( memcmp(zLine, "C ", 2)==0 ){
303
+ }else
304
+ if( memcmp(zLine, "R ", 2)==0 ){
305
+ }else
306
+ if( memcmp(zLine, "deleteall", 9)==0 ){
307
+ }else
308
+ if( memcmp(zLine, "N ", 2)==0 ){
309
+ }else
310
+
311
+ {
312
+ goto malformed_line;
313
+ }
314
+ }
315
+ gg.xFinish();
316
+ import_reset(1);
317
+ return;
318
+
319
+malformed_line:
320
+ trim_newline(zLine);
321
+ fossil_fatal("bad fast-import line: [%s]", zLine);
322
+ return;
323
+}
25324
26325
/*
27326
** COMMAND: import
28327
**
29328
** Usage: %fossil import NEW-REPOSITORY
@@ -31,7 +330,33 @@
31330
** Read text generated by the git-fast-export command and use it to
32331
** construct a new Fossil repository named by the NEW-REPOSITORY
33332
** argument. The get-fast-export text is read from standard input.
34333
*/
35334
void git_import_cmd(void){
36
- fossil_fatal("not yet implemented....");
335
+ char *zPassword;
336
+ fossil_fatal("this command is still under development....");
337
+ if( g.argc!=3 ){
338
+ usage("REPOSITORY-NAME");
339
+ }
340
+ db_create_repository(g.argv[2]);
341
+ db_open_repository(g.argv[2]);
342
+ db_open_config(0);
343
+ db_multi_exec(
344
+ "ATTACH ':memory:' AS mem1;"
345
+ "CREATE TABLE mem1.xtag(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
346
+ );
347
+ db_begin_transaction();
348
+ db_initial_setup(0, 0, 1);
349
+ git_fast_import(stdin);
350
+ db_end_transaction(0);
351
+ db_begin_transaction();
352
+ printf("Rebuilding repository meta-data...\n");
353
+ rebuild_db(0, 1);
354
+ printf("Vacuuming..."); fflush(stdout);
355
+ db_multi_exec("VACUUM");
356
+ printf(" ok\n");
357
+ printf("project-id: %s\n", db_get("project-code", 0));
358
+ printf("server-id: %s\n", db_get("server-code", 0));
359
+ zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
360
+ printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
361
+ db_end_transaction(0);
37362
}
38363
--- src/import.c
+++ src/import.c
@@ -20,10 +20,309 @@
20 */
21 #include "config.h"
22 #include "import.h"
23 #include <assert.h>
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
26 /*
27 ** COMMAND: import
28 **
29 ** Usage: %fossil import NEW-REPOSITORY
@@ -31,7 +330,33 @@
31 ** Read text generated by the git-fast-export command and use it to
32 ** construct a new Fossil repository named by the NEW-REPOSITORY
33 ** argument. The get-fast-export text is read from standard input.
34 */
35 void git_import_cmd(void){
36 fossil_fatal("not yet implemented....");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37 }
38
--- src/import.c
+++ src/import.c
@@ -20,10 +20,309 @@
20 */
21 #include "config.h"
22 #include "import.h"
23 #include <assert.h>
24
25 /*
26 ** State information about an on-going fast-import parse.
27 */
28 static struct {
29 void (*xFinish)(void); /* Function to finish a prior record */
30 int nData; /* Bytes of data */
31 char *zTag; /* Name of a tag */
32 char *zBranch; /* Name of a branch for a commit */
33 char *aData; /* Data content */
34 char *zMark; /* The current mark */
35 char *zDate; /* Date/time stamp */
36 char *zUser; /* User name */
37 char *zComment; /* Comment of a commit */
38 char *zFrom; /* from value */
39 int nMerge; /* Number of merge values */
40 int nMergeAlloc; /* Number of slots in azMerge[] */
41 char **azMerge; /* Merge values */
42 int nFile; /* Number of aFile values */
43 int nFileAlloc; /* Number of slots in aFile[] */
44 ManifestFile *aFile; /* Information about files in a commit */
45 } gg;
46
47 /*
48 ** A no-op "xFinish" method
49 */
50 static void finish_noop(void){}
51
52 /*
53 ** Deallocate the state information.
54 **
55 ** The azMerge[] and aFile[] arrays are zeroed by allocated space is
56 ** retained unless the freeAll flag is set.
57 */
58 static void import_reset(int freeAll){
59 int i;
60 gg.xFinish = 0;
61 fossil_free(gg.zTag); gg.zTag = 0;
62 fossil_free(gg.zBranch); gg.zBranch = 0;
63 fossil_free(gg.aData); gg.aData = 0;
64 fossil_free(gg.zMark); gg.zMark = 0;
65 fossil_free(gg.zDate); gg.zDate = 0;
66 fossil_free(gg.zUser); gg.zUser = 0;
67 fossil_free(gg.zComment); gg.zComment = 0;
68 fossil_free(gg.zFrom); gg.zFrom = 0;
69 for(i=0; i<gg.nMerge; i++){
70 fossil_free(gg.azMerge[i]); gg.azMerge[i] = 0;
71 }
72 gg.nMerge = 0;
73 for(i=0; i<gg.nFile; i++){
74 fossil_free(gg.aFile[i].zName);
75 fossil_free(gg.aFile[i].zUuid);
76 fossil_free(gg.aFile[i].zPerm);
77 fossil_free(gg.aFile[i].zPrior);
78 }
79 memset(gg.aFile, 0, gg.nFile*sizeof(gg.aFile[0]));
80 gg.nFile = 0;
81 if( freeAll ){
82 fossil_free(gg.azMerge);
83 fossil_free(gg.aFile);
84 memset(&gg, 0, sizeof(gg));
85 }
86 gg.xFinish = finish_noop;
87 }
88
89 /*
90 ** Insert an artifact into the BLOB table if it isn't there already.
91 ** If zMark is not zero, create a cross-reference from that mark back
92 ** to the newly inserted artifact.
93 */
94 static int fast_insert_content(Blob *pContent, const char *zMark){
95 Blob hash;
96 Blob cmpr;
97 int rid;
98
99 sha1sum_blob(pContent, &hash);
100 rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &hash);
101 if( rid==0 ){
102 static Stmt ins;
103 db_static_prepare(&ins,
104 "INSERT INTO blob(uuid, size, content) VALUES(:uuid, :size, :content)"
105 );
106 db_bind_text(&ins, ":uuid", blob_str(&hash));
107 db_bind_int(&ins, ":size", gg.nData);
108 blob_compress(pContent, &cmpr);
109 db_bind_blob(&ins, ":content", &cmpr);
110 db_step(&ins);
111 db_reset(&ins);
112 blob_reset(&cmpr);
113 rid = db_last_insert_rowid();
114 }
115 if( zMark ){
116 db_multi_exec(
117 "INSERT INTO xtag(tname, trid, tuuid)"
118 "VALUES(%Q,%d,%B)",
119 zMark, rid, &hash
120 );
121 db_multi_exec(
122 "INSERT INTO xtag(tname, trid, tuuid)"
123 "VALUES(%B,%d,%B)",
124 &hash, rid, &hash
125 );
126 }
127 blob_reset(&hash);
128 return rid;
129 }
130
131 /*
132 ** Use data accumulated in gg from a "blob" record to add a new file
133 ** to the BLOB table.
134 */
135 static void finish_blob(void){
136 Blob content;
137
138 if( gg.nData>0 ){
139 blob_init(&content, gg.aData, gg.nData);
140 fast_insert_content(&content, gg.zMark);
141 blob_reset(&content);
142 }
143 import_reset(0);
144 }
145
146 /*
147 ** Use data accumulated in gg from a "tag" record to add a new
148 ** control artifact to the BLOB table.
149 */
150 static void finish_tag(void){
151 Blob record, cksum;
152 if( gg.zDate && gg.zTag && gg.zFrom && gg.zUser ){
153 blob_zero(&record);
154 blob_appendf(&record, "D %z\n", gg.zDate);
155 blob_appendf(&record, "T +%F %s\n", gg.zTag, gg.zFrom);
156 blob_appendf(&record, "U %F\n", gg.zUser);
157 md5sum_blob(&record, &cksum);
158 blob_appendf(&record, "Z %b\n", &cksum);
159 fast_insert_content(&record, 0);
160 blob_reset(&record);
161 blob_reset(&cksum);
162 }
163 import_reset(0);
164 }
165
166 /*
167 ** Use data accumulated in gg from a "commit" record to add a new
168 ** manifest artifact to the BLOB table.
169 */
170 static void finish_commit(void){
171 /* TBD... */
172 import_reset(0);
173 }
174
175
176 /*
177 ** Turn the first \n in the input string into a \000
178 */
179 static void trim_newline(char *z){
180 while( z[0] && z[0]!='\n' ){ z++; }
181 z[0] = 0;
182 }
183
184 /*
185 ** Convert a "mark" or "committish" into the UUID.
186 */
187 static char *resolve_committish(const char *zCommittish){
188 char *zRes;
189
190 zRes = db_text(0, "SELECT tuuid FROM xtag WHERE tname=%Q", zCommittish);
191 return zRes;
192 }
193
194
195 /*
196 ** Read the git-fast-import format from pIn and insert the corresponding
197 ** content into the database.
198 */
199 static void git_fast_import(FILE *pIn){
200 char zLine[1000];
201 gg.xFinish = finish_noop;
202 while( fgets(zLine, sizeof(zLine), pIn) ){
203 if( zLine[0]=='\n' || zLine[0]=='#' ) continue;
204 if( memcmp(zLine, "blob", 4)==0 ){
205 gg.xFinish();
206 gg.xFinish = finish_blob;
207 }else
208 if( memcmp(zLine, "commit ", 7)==0 ){
209 gg.xFinish();
210 gg.xFinish = finish_commit;
211 trim_newline(&zLine[7]);
212 gg.zBranch = mprintf("%s", &zLine[7]);
213 }else
214 if( memcmp(zLine, "tag ", 4)==0 ){
215 gg.xFinish();
216 gg.xFinish = finish_tag;
217 trim_newline(&zLine[4]);
218 gg.zTag = mprintf("%s", &zLine[4]);
219 }else
220 if( memcmp(zLine, "reset ", 4)==0 ){
221 gg.xFinish();
222 }else
223 if( memcmp(zLine, "checkpoint", 10)==0 ){
224 gg.xFinish();
225 }else
226 if( memcmp(zLine, "feature", 7)==0 ){
227 gg.xFinish();
228 }else
229 if( memcmp(zLine, "option", 6)==0 ){
230 gg.xFinish();
231 }else
232 if( memcmp(zLine, "progress ", 9)==0 ){
233 gg.xFinish();
234 trim_newline(&zLine[9]);
235 printf("%s\n", &zLine[9]);
236 fflush(stdout);
237 }else
238 if( memcmp(zLine, "data ", 5)==0 ){
239 fossil_free(gg.aData); gg.aData = 0;
240 gg.nData = atoi(&zLine[5]);
241 if( gg.nData ){
242 int got;
243 gg.aData = fossil_malloc( gg.nData+1 );
244 got = fread(gg.aData, 1, gg.nData, pIn);
245 if( got!=gg.nData ){
246 fossil_fatal("short read: got %d of %d bytes", got, gg.nData);
247 }
248 if( gg.zComment==0 && gg.xFinish==finish_commit ){
249 gg.zComment = gg.aData;
250 gg.aData = 0;
251 gg.nData = 0;
252 }
253 }
254 }else
255 if( memcmp(zLine, "author ", 7)==0 ){
256 /* No-op */
257 }else
258 if( memcmp(zLine, "mark ", 5)==0 ){
259 trim_newline(&zLine[5]);
260 fossil_free(gg.zMark);
261 gg.zMark = mprintf("%s", &zLine[5]);
262 }else
263 if( memcmp(zLine, "tagger ", 7)==0 || memcmp(zLine, "committer ",9)==0 ){
264 int i;
265 char *z;
266 sqlite3_int64 secSince1970;
267
268 for(i=0; zLine[i] && zLine[i]!='<'; i++){}
269 if( zLine[i]==0 ) goto malformed_line;
270 z = &zLine[i+1];
271 for(i=i+1; zLine[i] && zLine[i]!='>'; i++){}
272 if( zLine[i]==0 ) goto malformed_line;
273 zLine[i] = 0;
274 fossil_free(gg.zUser);
275 gg.zUser = mprintf("%s", z);
276 secSince1970 = 0;
277 for(i=i+1; fossil_isdigit(zLine[i]); i++){
278 secSince1970 = secSince1970*10 + zLine[i] - '0';
279 }
280 fossil_free(gg.zDate);
281 gg.zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", secSince1970);
282 gg.zDate[10] = 'T';
283 }else
284 if( memcmp(zLine, "from ", 5)==0 ){
285 trim_newline(&zLine[5]);
286 fossil_free(gg.zFrom);
287 gg.zFrom = resolve_committish(&zLine[5]);
288 }else
289 if( memcmp(zLine, "merge ", 6)==0 ){
290 trim_newline(&zLine[6]);
291 if( gg.nMerge>=gg.nMergeAlloc ){
292 gg.nMergeAlloc = gg.nMergeAlloc*2 + 10;
293 gg.azMerge = fossil_realloc(gg.azMerge, gg.nMergeAlloc*sizeof(char*));
294 }
295 gg.azMerge[gg.nMerge] = resolve_committish(&zLine[5]);
296 if( gg.azMerge[gg.nMerge] ) gg.nMerge++;
297 }else
298 if( memcmp(zLine, "M ", 2)==0 ){
299 }else
300 if( memcmp(zLine, "D ", 2)==0 ){
301 }else
302 if( memcmp(zLine, "C ", 2)==0 ){
303 }else
304 if( memcmp(zLine, "R ", 2)==0 ){
305 }else
306 if( memcmp(zLine, "deleteall", 9)==0 ){
307 }else
308 if( memcmp(zLine, "N ", 2)==0 ){
309 }else
310
311 {
312 goto malformed_line;
313 }
314 }
315 gg.xFinish();
316 import_reset(1);
317 return;
318
319 malformed_line:
320 trim_newline(zLine);
321 fossil_fatal("bad fast-import line: [%s]", zLine);
322 return;
323 }
324
325 /*
326 ** COMMAND: import
327 **
328 ** Usage: %fossil import NEW-REPOSITORY
@@ -31,7 +330,33 @@
330 ** Read text generated by the git-fast-export command and use it to
331 ** construct a new Fossil repository named by the NEW-REPOSITORY
332 ** argument. The get-fast-export text is read from standard input.
333 */
334 void git_import_cmd(void){
335 char *zPassword;
336 fossil_fatal("this command is still under development....");
337 if( g.argc!=3 ){
338 usage("REPOSITORY-NAME");
339 }
340 db_create_repository(g.argv[2]);
341 db_open_repository(g.argv[2]);
342 db_open_config(0);
343 db_multi_exec(
344 "ATTACH ':memory:' AS mem1;"
345 "CREATE TABLE mem1.xtag(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
346 );
347 db_begin_transaction();
348 db_initial_setup(0, 0, 1);
349 git_fast_import(stdin);
350 db_end_transaction(0);
351 db_begin_transaction();
352 printf("Rebuilding repository meta-data...\n");
353 rebuild_db(0, 1);
354 printf("Vacuuming..."); fflush(stdout);
355 db_multi_exec("VACUUM");
356 printf(" ok\n");
357 printf("project-id: %s\n", db_get("project-code", 0));
358 printf("server-id: %s\n", db_get("server-code", 0));
359 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
360 printf("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
361 db_end_transaction(0);
362 }
363

Keyboard Shortcuts

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