Fossil SCM

merge trunk

bharder 2011-02-16 22:55 bch merge
Commit 0eaf7528b160d4d6492ff884cc42e943600e8cab
+2 -2
--- src/add.c
+++ src/add.c
@@ -188,12 +188,12 @@
188188
}else if( file_isfile(zPath) ){
189189
db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath);
190190
}
191191
blob_resize(&path, origSize);
192192
}
193
+ closedir(d);
193194
}
194
- closedir(d);
195195
blob_reset(&path);
196196
}
197197
198198
/*
199199
** Add all content of a directory.
@@ -321,12 +321,12 @@
321321
}
322322
blob_reset(&pathname);
323323
}
324324
blob_resize(&path, origSize);
325325
}
326
+ closedir(d);
326327
}
327
- closedir(d);
328328
blob_reset(&path);
329329
}
330330
331331
/*
332332
** COMMAND: rm
333333
--- src/add.c
+++ src/add.c
@@ -188,12 +188,12 @@
188 }else if( file_isfile(zPath) ){
189 db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath);
190 }
191 blob_resize(&path, origSize);
192 }
 
193 }
194 closedir(d);
195 blob_reset(&path);
196 }
197
198 /*
199 ** Add all content of a directory.
@@ -321,12 +321,12 @@
321 }
322 blob_reset(&pathname);
323 }
324 blob_resize(&path, origSize);
325 }
 
326 }
327 closedir(d);
328 blob_reset(&path);
329 }
330
331 /*
332 ** COMMAND: rm
333
--- src/add.c
+++ src/add.c
@@ -188,12 +188,12 @@
188 }else if( file_isfile(zPath) ){
189 db_multi_exec("INSERT INTO sfile VALUES(%Q)", zPath);
190 }
191 blob_resize(&path, origSize);
192 }
193 closedir(d);
194 }
 
195 blob_reset(&path);
196 }
197
198 /*
199 ** Add all content of a directory.
@@ -321,12 +321,12 @@
321 }
322 blob_reset(&pathname);
323 }
324 blob_resize(&path, origSize);
325 }
326 closedir(d);
327 }
 
328 blob_reset(&path);
329 }
330
331 /*
332 ** COMMAND: rm
333
--- src/http_transport.c
+++ src/http_transport.c
@@ -109,19 +109,19 @@
109109
** and run an SSH command to talk to the remote machine.
110110
*/
111111
const char *zSsh; /* The base SSH command */
112112
Blob zCmd; /* The SSH command */
113113
char *zHost; /* The host name to contact */
114
- char zIn[200]; /* An input line received back from remote */
114
+ char *zIn; /* An input line received back from remote */
115115
116116
zSsh = db_get("ssh-command", zDefaultSshCmd);
117117
blob_init(&zCmd, zSsh, -1);
118118
if( g.urlPort!=g.urlDfltPort ){
119119
#ifdef __MINGW32__
120
- blob_appendf(&zCmd, " -P %d", g.urlPort);
120
+ blob_appendf(&zCmd, " -T -P %d", g.urlPort);
121121
#else
122
- blob_appendf(&zCmd, " -p %d", g.urlPort);
122
+ blob_appendf(&zCmd, " -e none -T -p %d", g.urlPort);
123123
#endif
124124
}
125125
if( g.urlUser && g.urlUser[0] ){
126126
zHost = mprintf("%s@%s", g.urlUser, g.urlName);
127127
#ifdef __MINGW32__
@@ -146,11 +146,11 @@
146146
zHost = mprintf("%s", g.urlName);
147147
}
148148
blob_append(&zCmd, " ", 1);
149149
shell_escape(&zCmd, zHost);
150150
free(zHost);
151
- /* printf("%s\n", blob_str(&zCmd)); */
151
+ /* printf("%s\n", blob_str(&zCmd)); */
152152
popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
153153
if( sshPid==0 ){
154154
fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
155155
}
156156
blob_reset(&zCmd);
@@ -158,15 +158,17 @@
158158
/* Send an "echo" command to the other side to make sure that the
159159
** connection is up and working.
160160
*/
161161
fprintf(sshOut, "echo test\n");
162162
fflush(sshOut);
163
- sshin_read(zIn, sizeof(zIn));
163
+ zIn = fossil_malloc(16000);
164
+ sshin_read(zIn, 16000);
164165
if( memcmp(zIn, "test", 4)!=0 ){
165166
pclose2(sshIn, sshOut, sshPid);
166167
fossil_fatal("ssh connection failed: [%s]", zIn);
167168
}
169
+ fossil_free(zIn);
168170
}
169171
}
170172
171173
/*
172174
** Open a connection to the server. The server is defined by the following
@@ -185,11 +187,11 @@
185187
Blob cmd;
186188
blob_zero(&cmd);
187189
shell_escape(&cmd, g.urlFossil);
188190
blob_append(&cmd, " test-http ", -1);
189191
shell_escape(&cmd, g.urlPath);
190
- /* fprintf(stdout, "%s\n", blob_str(&cmd)); */
192
+ /* printf("%s\n", blob_str(&cmd)); fflush(stdout); */
191193
fprintf(sshOut, "%s\n", blob_str(&cmd));
192194
fflush(sshOut);
193195
blob_reset(&cmd);
194196
}else if( g.urlIsHttps ){
195197
#ifdef FOSSIL_ENABLE_SSL
@@ -339,10 +341,11 @@
339341
int got;
340342
if( sshIn ){
341343
int x;
342344
int wanted = N;
343345
got = 0;
346
+ /* printf("want %d bytes...\n", wanted); fflush(stdout); */
344347
while( wanted>0 ){
345348
x = read(sshIn, &zBuf[got], wanted);
346349
if( x<=0 ) break;
347350
got += x;
348351
wanted -= x;
@@ -356,11 +359,11 @@
356359
}else if( g.urlIsFile ){
357360
got = fread(zBuf, 1, N, transport.pFile);
358361
}else{
359362
got = socket_receive(0, zBuf, N);
360363
}
361
- /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
364
+ /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
362365
if( transport.pLog ){
363366
fwrite(zBuf, 1, got, transport.pLog);
364367
fflush(transport.pLog);
365368
}
366369
return got;
@@ -373,11 +376,11 @@
373376
int transport_receive(char *zBuf, int N){
374377
int onHand; /* Bytes current held in the transport buffer */
375378
int nByte = 0; /* Bytes of content received */
376379
377380
onHand = transport.nUsed - transport.iCursor;
378
- /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
381
+ /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
379382
if( onHand>0 ){
380383
int toMove = onHand;
381384
if( toMove>N ) toMove = N;
382385
/* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
383386
memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -447,11 +450,11 @@
447450
int iStart;
448451
449452
i = iStart = transport.iCursor;
450453
while(1){
451454
if( i >= transport.nUsed ){
452
- transport_load_buffer(1000);
455
+ transport_load_buffer(g.urlIsSsh ? 2 : 1000);
453456
i -= iStart;
454457
iStart = 0;
455458
if( i >= transport.nUsed ){
456459
transport.pBuf[i] = 0;
457460
transport.iCursor = i;
@@ -466,11 +469,11 @@
466469
}
467470
break;
468471
}
469472
i++;
470473
}
471
- /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
474
+ /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
472475
return &transport.pBuf[iStart];
473476
}
474477
475478
void transport_global_shutdown(void){
476479
if( g.urlIsSsh && sshPid ){
477480
--- src/http_transport.c
+++ src/http_transport.c
@@ -109,19 +109,19 @@
109 ** and run an SSH command to talk to the remote machine.
110 */
111 const char *zSsh; /* The base SSH command */
112 Blob zCmd; /* The SSH command */
113 char *zHost; /* The host name to contact */
114 char zIn[200]; /* An input line received back from remote */
115
116 zSsh = db_get("ssh-command", zDefaultSshCmd);
117 blob_init(&zCmd, zSsh, -1);
118 if( g.urlPort!=g.urlDfltPort ){
119 #ifdef __MINGW32__
120 blob_appendf(&zCmd, " -P %d", g.urlPort);
121 #else
122 blob_appendf(&zCmd, " -p %d", g.urlPort);
123 #endif
124 }
125 if( g.urlUser && g.urlUser[0] ){
126 zHost = mprintf("%s@%s", g.urlUser, g.urlName);
127 #ifdef __MINGW32__
@@ -146,11 +146,11 @@
146 zHost = mprintf("%s", g.urlName);
147 }
148 blob_append(&zCmd, " ", 1);
149 shell_escape(&zCmd, zHost);
150 free(zHost);
151 /* printf("%s\n", blob_str(&zCmd)); */
152 popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
153 if( sshPid==0 ){
154 fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
155 }
156 blob_reset(&zCmd);
@@ -158,15 +158,17 @@
158 /* Send an "echo" command to the other side to make sure that the
159 ** connection is up and working.
160 */
161 fprintf(sshOut, "echo test\n");
162 fflush(sshOut);
163 sshin_read(zIn, sizeof(zIn));
 
164 if( memcmp(zIn, "test", 4)!=0 ){
165 pclose2(sshIn, sshOut, sshPid);
166 fossil_fatal("ssh connection failed: [%s]", zIn);
167 }
 
168 }
169 }
170
171 /*
172 ** Open a connection to the server. The server is defined by the following
@@ -185,11 +187,11 @@
185 Blob cmd;
186 blob_zero(&cmd);
187 shell_escape(&cmd, g.urlFossil);
188 blob_append(&cmd, " test-http ", -1);
189 shell_escape(&cmd, g.urlPath);
190 /* fprintf(stdout, "%s\n", blob_str(&cmd)); */
191 fprintf(sshOut, "%s\n", blob_str(&cmd));
192 fflush(sshOut);
193 blob_reset(&cmd);
194 }else if( g.urlIsHttps ){
195 #ifdef FOSSIL_ENABLE_SSL
@@ -339,10 +341,11 @@
339 int got;
340 if( sshIn ){
341 int x;
342 int wanted = N;
343 got = 0;
 
344 while( wanted>0 ){
345 x = read(sshIn, &zBuf[got], wanted);
346 if( x<=0 ) break;
347 got += x;
348 wanted -= x;
@@ -356,11 +359,11 @@
356 }else if( g.urlIsFile ){
357 got = fread(zBuf, 1, N, transport.pFile);
358 }else{
359 got = socket_receive(0, zBuf, N);
360 }
361 /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
362 if( transport.pLog ){
363 fwrite(zBuf, 1, got, transport.pLog);
364 fflush(transport.pLog);
365 }
366 return got;
@@ -373,11 +376,11 @@
373 int transport_receive(char *zBuf, int N){
374 int onHand; /* Bytes current held in the transport buffer */
375 int nByte = 0; /* Bytes of content received */
376
377 onHand = transport.nUsed - transport.iCursor;
378 /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
379 if( onHand>0 ){
380 int toMove = onHand;
381 if( toMove>N ) toMove = N;
382 /* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
383 memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -447,11 +450,11 @@
447 int iStart;
448
449 i = iStart = transport.iCursor;
450 while(1){
451 if( i >= transport.nUsed ){
452 transport_load_buffer(1000);
453 i -= iStart;
454 iStart = 0;
455 if( i >= transport.nUsed ){
456 transport.pBuf[i] = 0;
457 transport.iCursor = i;
@@ -466,11 +469,11 @@
466 }
467 break;
468 }
469 i++;
470 }
471 /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
472 return &transport.pBuf[iStart];
473 }
474
475 void transport_global_shutdown(void){
476 if( g.urlIsSsh && sshPid ){
477
--- src/http_transport.c
+++ src/http_transport.c
@@ -109,19 +109,19 @@
109 ** and run an SSH command to talk to the remote machine.
110 */
111 const char *zSsh; /* The base SSH command */
112 Blob zCmd; /* The SSH command */
113 char *zHost; /* The host name to contact */
114 char *zIn; /* An input line received back from remote */
115
116 zSsh = db_get("ssh-command", zDefaultSshCmd);
117 blob_init(&zCmd, zSsh, -1);
118 if( g.urlPort!=g.urlDfltPort ){
119 #ifdef __MINGW32__
120 blob_appendf(&zCmd, " -T -P %d", g.urlPort);
121 #else
122 blob_appendf(&zCmd, " -e none -T -p %d", g.urlPort);
123 #endif
124 }
125 if( g.urlUser && g.urlUser[0] ){
126 zHost = mprintf("%s@%s", g.urlUser, g.urlName);
127 #ifdef __MINGW32__
@@ -146,11 +146,11 @@
146 zHost = mprintf("%s", g.urlName);
147 }
148 blob_append(&zCmd, " ", 1);
149 shell_escape(&zCmd, zHost);
150 free(zHost);
151 /* printf("%s\n", blob_str(&zCmd)); */
152 popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
153 if( sshPid==0 ){
154 fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
155 }
156 blob_reset(&zCmd);
@@ -158,15 +158,17 @@
158 /* Send an "echo" command to the other side to make sure that the
159 ** connection is up and working.
160 */
161 fprintf(sshOut, "echo test\n");
162 fflush(sshOut);
163 zIn = fossil_malloc(16000);
164 sshin_read(zIn, 16000);
165 if( memcmp(zIn, "test", 4)!=0 ){
166 pclose2(sshIn, sshOut, sshPid);
167 fossil_fatal("ssh connection failed: [%s]", zIn);
168 }
169 fossil_free(zIn);
170 }
171 }
172
173 /*
174 ** Open a connection to the server. The server is defined by the following
@@ -185,11 +187,11 @@
187 Blob cmd;
188 blob_zero(&cmd);
189 shell_escape(&cmd, g.urlFossil);
190 blob_append(&cmd, " test-http ", -1);
191 shell_escape(&cmd, g.urlPath);
192 /* printf("%s\n", blob_str(&cmd)); fflush(stdout); */
193 fprintf(sshOut, "%s\n", blob_str(&cmd));
194 fflush(sshOut);
195 blob_reset(&cmd);
196 }else if( g.urlIsHttps ){
197 #ifdef FOSSIL_ENABLE_SSL
@@ -339,10 +341,11 @@
341 int got;
342 if( sshIn ){
343 int x;
344 int wanted = N;
345 got = 0;
346 /* printf("want %d bytes...\n", wanted); fflush(stdout); */
347 while( wanted>0 ){
348 x = read(sshIn, &zBuf[got], wanted);
349 if( x<=0 ) break;
350 got += x;
351 wanted -= x;
@@ -356,11 +359,11 @@
359 }else if( g.urlIsFile ){
360 got = fread(zBuf, 1, N, transport.pFile);
361 }else{
362 got = socket_receive(0, zBuf, N);
363 }
364 /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
365 if( transport.pLog ){
366 fwrite(zBuf, 1, got, transport.pLog);
367 fflush(transport.pLog);
368 }
369 return got;
@@ -373,11 +376,11 @@
376 int transport_receive(char *zBuf, int N){
377 int onHand; /* Bytes current held in the transport buffer */
378 int nByte = 0; /* Bytes of content received */
379
380 onHand = transport.nUsed - transport.iCursor;
381 /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
382 if( onHand>0 ){
383 int toMove = onHand;
384 if( toMove>N ) toMove = N;
385 /* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
386 memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -447,11 +450,11 @@
450 int iStart;
451
452 i = iStart = transport.iCursor;
453 while(1){
454 if( i >= transport.nUsed ){
455 transport_load_buffer(g.urlIsSsh ? 2 : 1000);
456 i -= iStart;
457 iStart = 0;
458 if( i >= transport.nUsed ){
459 transport.pBuf[i] = 0;
460 transport.iCursor = i;
@@ -466,11 +469,11 @@
469 }
470 break;
471 }
472 i++;
473 }
474 /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
475 return &transport.pBuf[iStart];
476 }
477
478 void transport_global_shutdown(void){
479 if( g.urlIsSsh && sshPid ){
480
+86 -6
--- src/import.c
+++ src/import.c
@@ -58,10 +58,11 @@
5858
char **azMerge; /* Merge values */
5959
int nFile; /* Number of aFile values */
6060
int nFileAlloc; /* Number of slots in aFile[] */
6161
ImportFile *aFile; /* Information about files in a commit */
6262
int fromLoaded; /* True zFrom content loaded into aFile[] */
63
+ int tagCommit; /* True if the commit adds a tag */
6364
} gg;
6465
6566
/*
6667
** Duplicate a string.
6768
*/
@@ -148,16 +149,16 @@
148149
blob_reset(&cmpr);
149150
rid = db_last_insert_rowid();
150151
}
151152
if( zMark ){
152153
db_multi_exec(
153
- "INSERT OR IGNORE INTO xtag(tname, trid, tuuid)"
154
+ "INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
154155
"VALUES(%Q,%d,%B)",
155156
zMark, rid, &hash
156157
);
157158
db_multi_exec(
158
- "INSERT OR IGNORE INTO xtag(tname, trid, tuuid)"
159
+ "INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
159160
"VALUES(%B,%d,%B)",
160161
&hash, rid, &hash
161162
);
162163
}
163164
if( saveUuid ){
@@ -244,29 +245,54 @@
244245
zFromBranch = db_text(0, "SELECT brnm FROM xbranch WHERE tname=%Q",
245246
gg.zFromMark);
246247
}else{
247248
zFromBranch = 0;
248249
}
249
- if( fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
250
+ if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
250251
blob_appendf(&record, "T *branch * %F\n", gg.zBranch);
251252
blob_appendf(&record, "T *sym-%F *\n", gg.zBranch);
252253
if( zFromBranch ){
253254
blob_appendf(&record, "T -sym-%F *\n", zFromBranch);
254255
}
255256
}
256257
free(zFromBranch);
257258
if( gg.zFrom==0 ){
258
- blob_appendf(&record, "T +sym-trunk *\n");
259
+ blob_appendf(&record, "T *sym-trunk *\n");
259260
}
260261
db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)",
261262
gg.zMark, gg.zBranch);
262263
blob_appendf(&record, "U %F\n", gg.zUser);
263264
md5sum_blob(&record, &cksum);
264265
blob_appendf(&record, "Z %b\n", &cksum);
265266
fast_insert_content(&record, gg.zMark, 1);
266267
blob_reset(&record);
267268
blob_reset(&cksum);
269
+
270
+ /* The "git fast-export" command might output multiple "commit" lines
271
+ ** that reference a tag using "refs/tags/TAGNAME". The tag should only
272
+ ** be applied to the last commit that is output. The problem is we do not
273
+ ** know at this time if the current commit is the last one to hold this
274
+ ** tag or not. So make an entry in the XTAG table to record this tag
275
+ ** but overwrite that entry if a later instance of the same tag appears.
276
+ **
277
+ ** This behavior seems like a bug in git-fast-export, but it is easier
278
+ ** to work around the problem than to fix git-fast-export.
279
+ */
280
+ if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
281
+ blob_appendf(&record, "D %s\n", gg.zDate);
282
+ blob_appendf(&record, "T +sym-%F %s\n", gg.zBranch, gg.zPrevCheckin);
283
+ blob_appendf(&record, "U %F\n", gg.zUser);
284
+ md5sum_blob(&record, &cksum);
285
+ blob_appendf(&record, "Z %b\n", &cksum);
286
+ db_multi_exec(
287
+ "INSERT OR REPLACE INTO xtag(tname, tcontent)"
288
+ " VALUES(%Q,%Q)", gg.zBranch, blob_str(&record)
289
+ );
290
+ blob_reset(&record);
291
+ blob_reset(&cksum);
292
+ }
293
+
268294
fossil_free(gg.zPrevBranch);
269295
gg.zPrevBranch = gg.zBranch;
270296
gg.zBranch = 0;
271297
import_reset(0);
272298
}
@@ -326,11 +352,11 @@
326352
** Convert a "mark" or "committish" into the UUID.
327353
*/
328354
static char *resolve_committish(const char *zCommittish){
329355
char *zRes;
330356
331
- zRes = db_text(0, "SELECT tuuid FROM xtag WHERE tname=%Q", zCommittish);
357
+ zRes = db_text(0, "SELECT tuuid FROM xmark WHERE tname=%Q", zCommittish);
332358
return zRes;
333359
}
334360
335361
/*
336362
** Create a new entry in the gg.aFile[] array
@@ -424,12 +450,33 @@
424450
if( memcmp(zLine, "commit ", 7)==0 ){
425451
gg.xFinish();
426452
gg.xFinish = finish_commit;
427453
trim_newline(&zLine[7]);
428454
z = &zLine[7];
455
+
456
+ /* The argument to the "commit" line might match either of these
457
+ ** patterns:
458
+ **
459
+ ** (A) refs/heads/BRANCHNAME
460
+ ** (B) refs/tags/TAGNAME
461
+ **
462
+ ** If pattern A is used, then the branchname used is as shown.
463
+ ** Except, the "master" branch which is the default branch name in
464
+ ** Git is changed to "trunk" which is the default name in Fossil.
465
+ ** If the pattern is B, then the new commit should be on the same
466
+ ** branch as its parent. And, we might need to add the TAGNAME
467
+ ** tag to the new commit. However, if there are multiple instances
468
+ ** of pattern B with the same TAGNAME, then only put the tag on the
469
+ ** last commit that holds that tag.
470
+ **
471
+ ** None of the above is explained in the git-fast-export
472
+ ** documentation. We had to figure it out via trial and error.
473
+ */
429474
for(i=strlen(z)-1; i>=0 && z[i]!='/'; i--){}
475
+ gg.tagCommit = memcmp(&z[i-4], "tags", 4)==0; /* True for pattern B */
430476
if( z[i+1]!=0 ) z += i+1;
477
+ if( fossil_strcmp(z, "master")==0 ) z = "trunk";
431478
gg.zBranch = fossil_strdup(z);
432479
gg.fromLoaded = 0;
433480
}else
434481
if( memcmp(zLine, "tag ", 4)==0 ){
435482
gg.xFinish();
@@ -631,11 +678,13 @@
631678
** in the future.
632679
*/
633680
void git_import_cmd(void){
634681
char *zPassword;
635682
FILE *pIn;
683
+ Stmt q;
636684
int forceFlag = find_option("force", "f", 0)!=0;
685
+
637686
find_option("git",0,0); /* Skip the --git option for now */
638687
verify_all_options();
639688
if( g.argc!=3 && g.argc!=4 ){
640689
usage("REPOSITORY-NAME");
641690
}
@@ -647,17 +696,48 @@
647696
}
648697
if( forceFlag ) unlink(g.argv[2]);
649698
db_create_repository(g.argv[2]);
650699
db_open_repository(g.argv[2]);
651700
db_open_config(0);
701
+
702
+ /* The following temp-tables are used to hold information needed for
703
+ ** the import.
704
+ **
705
+ ** The XMARK table provides a mapping from fast-import "marks" and symbols
706
+ ** into artifact ids (UUIDs - the 40-byte hex SHA1 hash of artifacts).
707
+ ** Given any valid fast-import symbol, the corresponding fossil rid and
708
+ ** uuid can found by searching against the xmark.tname field.
709
+ **
710
+ ** The XBRANCH table maps commit marks and symbols into the branch those
711
+ ** commits belong to. If xbranch.tname is a fast-import symbol for a
712
+ ** checkin then xbranch.brnm is the branch that checkin is part of.
713
+ **
714
+ ** The XTAG table records information about tags that need to be applied
715
+ ** to various branches after the import finishes. The xtag.tcontent field
716
+ ** contains the text of an artifact that will add a tag to a check-in.
717
+ ** The git-fast-export file format might specify the same tag multiple
718
+ ** times but only the last tag should be used. And we do not know which
719
+ ** occurrence of the tag is the last until the import finishes.
720
+ */
652721
db_multi_exec(
653
- "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
722
+ "CREATE TEMP TABLE xmark(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
654723
"CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
724
+ "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
655725
);
726
+
727
+
656728
db_begin_transaction();
657729
db_initial_setup(0, 0, 1);
658730
git_fast_import(pIn);
731
+ db_prepare(&q, "SELECT tcontent FROM xtag");
732
+ while( db_step(&q)==SQLITE_ROW ){
733
+ Blob record;
734
+ db_ephemeral_blob(&q, 0, &record);
735
+ fast_insert_content(&record, 0, 0);
736
+ import_reset(0);
737
+ }
738
+ db_finalize(&q);
659739
db_end_transaction(0);
660740
db_begin_transaction();
661741
printf("Rebuilding repository meta-data...\n");
662742
rebuild_db(0, 1, 1);
663743
verify_cancel();
664744
--- src/import.c
+++ src/import.c
@@ -58,10 +58,11 @@
58 char **azMerge; /* Merge values */
59 int nFile; /* Number of aFile values */
60 int nFileAlloc; /* Number of slots in aFile[] */
61 ImportFile *aFile; /* Information about files in a commit */
62 int fromLoaded; /* True zFrom content loaded into aFile[] */
 
63 } gg;
64
65 /*
66 ** Duplicate a string.
67 */
@@ -148,16 +149,16 @@
148 blob_reset(&cmpr);
149 rid = db_last_insert_rowid();
150 }
151 if( zMark ){
152 db_multi_exec(
153 "INSERT OR IGNORE INTO xtag(tname, trid, tuuid)"
154 "VALUES(%Q,%d,%B)",
155 zMark, rid, &hash
156 );
157 db_multi_exec(
158 "INSERT OR IGNORE INTO xtag(tname, trid, tuuid)"
159 "VALUES(%B,%d,%B)",
160 &hash, rid, &hash
161 );
162 }
163 if( saveUuid ){
@@ -244,29 +245,54 @@
244 zFromBranch = db_text(0, "SELECT brnm FROM xbranch WHERE tname=%Q",
245 gg.zFromMark);
246 }else{
247 zFromBranch = 0;
248 }
249 if( fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
250 blob_appendf(&record, "T *branch * %F\n", gg.zBranch);
251 blob_appendf(&record, "T *sym-%F *\n", gg.zBranch);
252 if( zFromBranch ){
253 blob_appendf(&record, "T -sym-%F *\n", zFromBranch);
254 }
255 }
256 free(zFromBranch);
257 if( gg.zFrom==0 ){
258 blob_appendf(&record, "T +sym-trunk *\n");
259 }
260 db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)",
261 gg.zMark, gg.zBranch);
262 blob_appendf(&record, "U %F\n", gg.zUser);
263 md5sum_blob(&record, &cksum);
264 blob_appendf(&record, "Z %b\n", &cksum);
265 fast_insert_content(&record, gg.zMark, 1);
266 blob_reset(&record);
267 blob_reset(&cksum);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268 fossil_free(gg.zPrevBranch);
269 gg.zPrevBranch = gg.zBranch;
270 gg.zBranch = 0;
271 import_reset(0);
272 }
@@ -326,11 +352,11 @@
326 ** Convert a "mark" or "committish" into the UUID.
327 */
328 static char *resolve_committish(const char *zCommittish){
329 char *zRes;
330
331 zRes = db_text(0, "SELECT tuuid FROM xtag WHERE tname=%Q", zCommittish);
332 return zRes;
333 }
334
335 /*
336 ** Create a new entry in the gg.aFile[] array
@@ -424,12 +450,33 @@
424 if( memcmp(zLine, "commit ", 7)==0 ){
425 gg.xFinish();
426 gg.xFinish = finish_commit;
427 trim_newline(&zLine[7]);
428 z = &zLine[7];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429 for(i=strlen(z)-1; i>=0 && z[i]!='/'; i--){}
 
430 if( z[i+1]!=0 ) z += i+1;
 
431 gg.zBranch = fossil_strdup(z);
432 gg.fromLoaded = 0;
433 }else
434 if( memcmp(zLine, "tag ", 4)==0 ){
435 gg.xFinish();
@@ -631,11 +678,13 @@
631 ** in the future.
632 */
633 void git_import_cmd(void){
634 char *zPassword;
635 FILE *pIn;
 
636 int forceFlag = find_option("force", "f", 0)!=0;
 
637 find_option("git",0,0); /* Skip the --git option for now */
638 verify_all_options();
639 if( g.argc!=3 && g.argc!=4 ){
640 usage("REPOSITORY-NAME");
641 }
@@ -647,17 +696,48 @@
647 }
648 if( forceFlag ) unlink(g.argv[2]);
649 db_create_repository(g.argv[2]);
650 db_open_repository(g.argv[2]);
651 db_open_config(0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652 db_multi_exec(
653 "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
654 "CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
 
655 );
 
 
656 db_begin_transaction();
657 db_initial_setup(0, 0, 1);
658 git_fast_import(pIn);
 
 
 
 
 
 
 
 
659 db_end_transaction(0);
660 db_begin_transaction();
661 printf("Rebuilding repository meta-data...\n");
662 rebuild_db(0, 1, 1);
663 verify_cancel();
664
--- src/import.c
+++ src/import.c
@@ -58,10 +58,11 @@
58 char **azMerge; /* Merge values */
59 int nFile; /* Number of aFile values */
60 int nFileAlloc; /* Number of slots in aFile[] */
61 ImportFile *aFile; /* Information about files in a commit */
62 int fromLoaded; /* True zFrom content loaded into aFile[] */
63 int tagCommit; /* True if the commit adds a tag */
64 } gg;
65
66 /*
67 ** Duplicate a string.
68 */
@@ -148,16 +149,16 @@
149 blob_reset(&cmpr);
150 rid = db_last_insert_rowid();
151 }
152 if( zMark ){
153 db_multi_exec(
154 "INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
155 "VALUES(%Q,%d,%B)",
156 zMark, rid, &hash
157 );
158 db_multi_exec(
159 "INSERT OR IGNORE INTO xmark(tname, trid, tuuid)"
160 "VALUES(%B,%d,%B)",
161 &hash, rid, &hash
162 );
163 }
164 if( saveUuid ){
@@ -244,29 +245,54 @@
245 zFromBranch = db_text(0, "SELECT brnm FROM xbranch WHERE tname=%Q",
246 gg.zFromMark);
247 }else{
248 zFromBranch = 0;
249 }
250 if( !gg.tagCommit && fossil_strcmp(zFromBranch, gg.zBranch)!=0 ){
251 blob_appendf(&record, "T *branch * %F\n", gg.zBranch);
252 blob_appendf(&record, "T *sym-%F *\n", gg.zBranch);
253 if( zFromBranch ){
254 blob_appendf(&record, "T -sym-%F *\n", zFromBranch);
255 }
256 }
257 free(zFromBranch);
258 if( gg.zFrom==0 ){
259 blob_appendf(&record, "T *sym-trunk *\n");
260 }
261 db_multi_exec("INSERT INTO xbranch(tname, brnm) VALUES(%Q,%Q)",
262 gg.zMark, gg.zBranch);
263 blob_appendf(&record, "U %F\n", gg.zUser);
264 md5sum_blob(&record, &cksum);
265 blob_appendf(&record, "Z %b\n", &cksum);
266 fast_insert_content(&record, gg.zMark, 1);
267 blob_reset(&record);
268 blob_reset(&cksum);
269
270 /* The "git fast-export" command might output multiple "commit" lines
271 ** that reference a tag using "refs/tags/TAGNAME". The tag should only
272 ** be applied to the last commit that is output. The problem is we do not
273 ** know at this time if the current commit is the last one to hold this
274 ** tag or not. So make an entry in the XTAG table to record this tag
275 ** but overwrite that entry if a later instance of the same tag appears.
276 **
277 ** This behavior seems like a bug in git-fast-export, but it is easier
278 ** to work around the problem than to fix git-fast-export.
279 */
280 if( gg.tagCommit && gg.zDate && gg.zUser && gg.zFrom ){
281 blob_appendf(&record, "D %s\n", gg.zDate);
282 blob_appendf(&record, "T +sym-%F %s\n", gg.zBranch, gg.zPrevCheckin);
283 blob_appendf(&record, "U %F\n", gg.zUser);
284 md5sum_blob(&record, &cksum);
285 blob_appendf(&record, "Z %b\n", &cksum);
286 db_multi_exec(
287 "INSERT OR REPLACE INTO xtag(tname, tcontent)"
288 " VALUES(%Q,%Q)", gg.zBranch, blob_str(&record)
289 );
290 blob_reset(&record);
291 blob_reset(&cksum);
292 }
293
294 fossil_free(gg.zPrevBranch);
295 gg.zPrevBranch = gg.zBranch;
296 gg.zBranch = 0;
297 import_reset(0);
298 }
@@ -326,11 +352,11 @@
352 ** Convert a "mark" or "committish" into the UUID.
353 */
354 static char *resolve_committish(const char *zCommittish){
355 char *zRes;
356
357 zRes = db_text(0, "SELECT tuuid FROM xmark WHERE tname=%Q", zCommittish);
358 return zRes;
359 }
360
361 /*
362 ** Create a new entry in the gg.aFile[] array
@@ -424,12 +450,33 @@
450 if( memcmp(zLine, "commit ", 7)==0 ){
451 gg.xFinish();
452 gg.xFinish = finish_commit;
453 trim_newline(&zLine[7]);
454 z = &zLine[7];
455
456 /* The argument to the "commit" line might match either of these
457 ** patterns:
458 **
459 ** (A) refs/heads/BRANCHNAME
460 ** (B) refs/tags/TAGNAME
461 **
462 ** If pattern A is used, then the branchname used is as shown.
463 ** Except, the "master" branch which is the default branch name in
464 ** Git is changed to "trunk" which is the default name in Fossil.
465 ** If the pattern is B, then the new commit should be on the same
466 ** branch as its parent. And, we might need to add the TAGNAME
467 ** tag to the new commit. However, if there are multiple instances
468 ** of pattern B with the same TAGNAME, then only put the tag on the
469 ** last commit that holds that tag.
470 **
471 ** None of the above is explained in the git-fast-export
472 ** documentation. We had to figure it out via trial and error.
473 */
474 for(i=strlen(z)-1; i>=0 && z[i]!='/'; i--){}
475 gg.tagCommit = memcmp(&z[i-4], "tags", 4)==0; /* True for pattern B */
476 if( z[i+1]!=0 ) z += i+1;
477 if( fossil_strcmp(z, "master")==0 ) z = "trunk";
478 gg.zBranch = fossil_strdup(z);
479 gg.fromLoaded = 0;
480 }else
481 if( memcmp(zLine, "tag ", 4)==0 ){
482 gg.xFinish();
@@ -631,11 +678,13 @@
678 ** in the future.
679 */
680 void git_import_cmd(void){
681 char *zPassword;
682 FILE *pIn;
683 Stmt q;
684 int forceFlag = find_option("force", "f", 0)!=0;
685
686 find_option("git",0,0); /* Skip the --git option for now */
687 verify_all_options();
688 if( g.argc!=3 && g.argc!=4 ){
689 usage("REPOSITORY-NAME");
690 }
@@ -647,17 +696,48 @@
696 }
697 if( forceFlag ) unlink(g.argv[2]);
698 db_create_repository(g.argv[2]);
699 db_open_repository(g.argv[2]);
700 db_open_config(0);
701
702 /* The following temp-tables are used to hold information needed for
703 ** the import.
704 **
705 ** The XMARK table provides a mapping from fast-import "marks" and symbols
706 ** into artifact ids (UUIDs - the 40-byte hex SHA1 hash of artifacts).
707 ** Given any valid fast-import symbol, the corresponding fossil rid and
708 ** uuid can found by searching against the xmark.tname field.
709 **
710 ** The XBRANCH table maps commit marks and symbols into the branch those
711 ** commits belong to. If xbranch.tname is a fast-import symbol for a
712 ** checkin then xbranch.brnm is the branch that checkin is part of.
713 **
714 ** The XTAG table records information about tags that need to be applied
715 ** to various branches after the import finishes. The xtag.tcontent field
716 ** contains the text of an artifact that will add a tag to a check-in.
717 ** The git-fast-export file format might specify the same tag multiple
718 ** times but only the last tag should be used. And we do not know which
719 ** occurrence of the tag is the last until the import finishes.
720 */
721 db_multi_exec(
722 "CREATE TEMP TABLE xmark(tname TEXT UNIQUE, trid INT, tuuid TEXT);"
723 "CREATE TEMP TABLE xbranch(tname TEXT UNIQUE, brnm TEXT);"
724 "CREATE TEMP TABLE xtag(tname TEXT UNIQUE, tcontent TEXT);"
725 );
726
727
728 db_begin_transaction();
729 db_initial_setup(0, 0, 1);
730 git_fast_import(pIn);
731 db_prepare(&q, "SELECT tcontent FROM xtag");
732 while( db_step(&q)==SQLITE_ROW ){
733 Blob record;
734 db_ephemeral_blob(&q, 0, &record);
735 fast_insert_content(&record, 0, 0);
736 import_reset(0);
737 }
738 db_finalize(&q);
739 db_end_transaction(0);
740 db_begin_transaction();
741 printf("Rebuilding repository meta-data...\n");
742 rebuild_db(0, 1, 1);
743 verify_cancel();
744
--- src/rebuild.c
+++ src/rebuild.c
@@ -602,10 +602,11 @@
602602
blob_reset(&aContent);
603603
free(zSubpath);
604604
printf("\r%d", ++nFileRead);
605605
fflush(stdout);
606606
}
607
+ closedir(d);
607608
}else {
608609
fossil_panic("encountered error %d while trying to open \"%s\".",
609610
errno, g.argv[3]);
610611
}
611612
}
612613
--- src/rebuild.c
+++ src/rebuild.c
@@ -602,10 +602,11 @@
602 blob_reset(&aContent);
603 free(zSubpath);
604 printf("\r%d", ++nFileRead);
605 fflush(stdout);
606 }
 
607 }else {
608 fossil_panic("encountered error %d while trying to open \"%s\".",
609 errno, g.argv[3]);
610 }
611 }
612
--- src/rebuild.c
+++ src/rebuild.c
@@ -602,10 +602,11 @@
602 blob_reset(&aContent);
603 free(zSubpath);
604 printf("\r%d", ++nFileRead);
605 fflush(stdout);
606 }
607 closedir(d);
608 }else {
609 fossil_panic("encountered error %d while trying to open \"%s\".",
610 errno, g.argv[3]);
611 }
612 }
613
+1 -1
--- src/setup.c
+++ src/setup.c
@@ -610,11 +610,11 @@
610610
@
611611
@ <li><p>
612612
@ The <span class="capability">EMail</span> privilege allows the display of
613613
@ sensitive information such as the email address of users and contact
614614
@ information on tickets. Recommended OFF for
615
- @ <span class="usertype">anonymousy</span> and for
615
+ @ <span class="usertype">anonymous</span> and for
616616
@ <span class="usertype">nobody</span> but ON for
617617
@ <span class="usertype">developer</span>.
618618
@ </p></li>
619619
@
620620
@ <li><p>
621621
--- src/setup.c
+++ src/setup.c
@@ -610,11 +610,11 @@
610 @
611 @ <li><p>
612 @ The <span class="capability">EMail</span> privilege allows the display of
613 @ sensitive information such as the email address of users and contact
614 @ information on tickets. Recommended OFF for
615 @ <span class="usertype">anonymousy</span> and for
616 @ <span class="usertype">nobody</span> but ON for
617 @ <span class="usertype">developer</span>.
618 @ </p></li>
619 @
620 @ <li><p>
621
--- src/setup.c
+++ src/setup.c
@@ -610,11 +610,11 @@
610 @
611 @ <li><p>
612 @ The <span class="capability">EMail</span> privilege allows the display of
613 @ sensitive information such as the email address of users and contact
614 @ information on tickets. Recommended OFF for
615 @ <span class="usertype">anonymous</span> and for
616 @ <span class="usertype">nobody</span> but ON for
617 @ <span class="usertype">developer</span>.
618 @ </p></li>
619 @
620 @ <li><p>
621
+1 -1
--- src/vfile.c
+++ src/vfile.c
@@ -310,12 +310,12 @@
310310
}else if( file_isfile(zPath) && !db_exists(zSql, &zPath[nPrefix+1]) ){
311311
db_multi_exec("INSERT INTO sfile VALUES(%Q)", &zPath[nPrefix+1]);
312312
}
313313
blob_resize(pPath, origSize);
314314
}
315
+ closedir(d);
315316
}
316
- closedir(d);
317317
}
318318
319319
/*
320320
** Compute an aggregate MD5 checksum over the disk image of every
321321
** file in vid. The file names are part of the checksum. The resulting
322322
--- src/vfile.c
+++ src/vfile.c
@@ -310,12 +310,12 @@
310 }else if( file_isfile(zPath) && !db_exists(zSql, &zPath[nPrefix+1]) ){
311 db_multi_exec("INSERT INTO sfile VALUES(%Q)", &zPath[nPrefix+1]);
312 }
313 blob_resize(pPath, origSize);
314 }
 
315 }
316 closedir(d);
317 }
318
319 /*
320 ** Compute an aggregate MD5 checksum over the disk image of every
321 ** file in vid. The file names are part of the checksum. The resulting
322
--- src/vfile.c
+++ src/vfile.c
@@ -310,12 +310,12 @@
310 }else if( file_isfile(zPath) && !db_exists(zSql, &zPath[nPrefix+1]) ){
311 db_multi_exec("INSERT INTO sfile VALUES(%Q)", &zPath[nPrefix+1]);
312 }
313 blob_resize(pPath, origSize);
314 }
315 closedir(d);
316 }
 
317 }
318
319 /*
320 ** Compute an aggregate MD5 checksum over the disk image of every
321 ** file in vid. The file names are part of the checksum. The resulting
322

Keyboard Shortcuts

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