Fossil SCM

Further enhancements to "fossil git export" to fix a memory leak and to improve the operation of --mainbranch.

drh 2021-01-06 21:18 trunk
Commit 953fac2b9b19692c292e5b2cd4887bfd90210fe8a3d0615ba65dc5de84623285
1 file changed +83 -9
+83 -9
--- src/export.c
+++ src/export.c
@@ -1144,10 +1144,11 @@
11441144
** export */
11451145
if( nErr ){
11461146
gitmirror_message(VERB_ERROR,
11471147
"export of %s abandoned due to missing files\n", zUuid);
11481148
*pnLimit = 0;
1149
+ manifest_destroy(pMan);
11491150
return 1;
11501151
}
11511152
11521153
/* Figure out which branch this check-in is a member of */
11531154
zBranch = db_text(0,
@@ -1271,10 +1272,12 @@
12711272
zFNQuoted = gitmirror_quote_filename_if_needed(zFilename);
12721273
fprintf(xCmd,"M %s %s %s\n", zGitMode, zMark, zFNQuoted);
12731274
fossil_free(zFNQuoted);
12741275
}
12751276
db_finalize(&q);
1277
+ manifest_destroy(pMan);
1278
+ pMan = 0;
12761279
12771280
/* Include Fossil-generated auxiliary files in the check-in */
12781281
if( fManifest & MFESTFLG_RAW ){
12791282
Blob manifest;
12801283
content_get(rid, &manifest);
@@ -1298,10 +1301,78 @@
12981301
/* The check-in is finished, so decrement the counter */
12991302
(*pnLimit)--;
13001303
return 0;
13011304
}
13021305
1306
+/*
1307
+** Create a new Git repository at zMirror to use as the mirror.
1308
+** Try to make zMainBr be the main branch for the new repository.
1309
+**
1310
+** A side-effect of this routine is that current-working directory
1311
+** is changed to zMirror.
1312
+**
1313
+** If zMainBr is initially NULL, then the return value will be the
1314
+** name of the default branch to be used by Git. If zMainBr is
1315
+** initially non-NULL, then the return value will be a copy of zMainBr.
1316
+*/
1317
+static char *gitmirror_init(
1318
+ const char *zMirror,
1319
+ char *zMainBr
1320
+){
1321
+ char *zCmd;
1322
+ int rc;
1323
+
1324
+ /* Create a new Git repository at zMirror */
1325
+ zCmd = mprintf("git init %$", zMirror);
1326
+ gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1327
+ rc = fossil_system(zCmd);
1328
+ if( rc ){
1329
+ fossil_fatal("cannot initialize git repository using: %s\n", zCmd);
1330
+ }
1331
+ fossil_free(zCmd);
1332
+
1333
+ /* Must be in the new Git repository directory for subsequent commands */
1334
+ rc = file_chdir(zMirror, 0);
1335
+ if( rc ){
1336
+ fossil_fatal("cannot change to directory \"%s\"", zMirror);
1337
+ }
1338
+
1339
+ if( zMainBr ){
1340
+ /* Set the current branch to zMainBr */
1341
+ zCmd = mprintf("git symbolic-ref HEAD refs/heads/%s", zMainBr);
1342
+ gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1343
+ rc = fossil_system(zCmd);
1344
+ if( rc ){
1345
+ fossil_fatal("git command failed: %s", zCmd);
1346
+ }
1347
+ fossil_free(zCmd);
1348
+ }else{
1349
+ /* If zMainBr is not specified, then check to see what branch
1350
+ ** name Git chose for itself */
1351
+ char *z;
1352
+ char zLine[1000];
1353
+ FILE *xCmd;
1354
+ int i;
1355
+ zCmd = "git symbolic-ref --short HEAD";
1356
+ gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1357
+ xCmd = popen(zCmd, "r");
1358
+ if( xCmd==0 ){
1359
+ fossil_fatal("git command failed: %s", zCmd);
1360
+ }
1361
+
1362
+ z = fgets(zLine, sizeof(zLine), xCmd);
1363
+ pclose(xCmd);
1364
+ if( z==0 ){
1365
+ fossil_fatal("no output from \"%s\"", zCmd);
1366
+ }
1367
+ for(i=0; z[i] && !fossil_isspace(z[i]); i++){}
1368
+ z[i] = 0;
1369
+ zMainBr = fossil_strdup(z);
1370
+ }
1371
+ return zMainBr;
1372
+}
1373
+
13031374
/*
13041375
** Implementation of the "fossil git export" command.
13051376
*/
13061377
void gitmirror_export_command(void){
13071378
const char *zLimit; /* Text of the --limit flag */
@@ -1310,11 +1381,11 @@
13101381
char *zMirror; /* Name of the mirror */
13111382
char *z; /* Generic string */
13121383
char *zCmd; /* git command to run as a subprocess */
13131384
const char *zDebug = 0; /* Value of the --debug flag */
13141385
const char *zAutoPush = 0; /* Value of the --autopush flag */
1315
- const char *zMainBr = 0; /* Value of the --mainbranch flag */
1386
+ char *zMainBr = 0; /* Value of the --mainbranch flag */
13161387
char *zPushUrl; /* URL to sync the mirror to */
13171388
double rEnd; /* time of most recent export */
13181389
int rc; /* Result code */
13191390
int bForce; /* Do the export and sync even if no changes*/
13201391
int bNeedRepack = 0; /* True if we should run repack at the end */
@@ -1331,11 +1402,11 @@
13311402
if( zLimit ){
13321403
nLimit = (unsigned int)atoi(zLimit);
13331404
if( nLimit<=0 ) fossil_fatal("--limit must be positive");
13341405
}
13351406
zAutoPush = find_option("autopush",0,1);
1336
- zMainBr = find_option("mainbranch",0,1);
1407
+ zMainBr = (char*)find_option("mainbranch",0,1);
13371408
bForce = find_option("force","f",0)!=0;
13381409
bIfExists = find_option("if-mirrored",0,0)!=0;
13391410
gitmirror_verbosity = VERB_NORMAL;
13401411
while( find_option("quiet","q",0)!=0 ){ gitmirror_verbosity--; }
13411412
while( find_option("verbose","v",0)!=0 ){ gitmirror_verbosity++; }
@@ -1350,25 +1421,28 @@
13501421
zMirror = db_get("last-git-export-repo", 0);
13511422
if( zMirror==0 ){
13521423
if( bIfExists ) return;
13531424
fossil_fatal("no Git repository specified");
13541425
}
1426
+
1427
+ if( zMainBr ){
1428
+ z = fossil_strdup(zMainBr);
1429
+ gitmirror_sanitize_name(z);
1430
+ if( strcmp(z, zMainBr) ){
1431
+ fossil_fatal("\"%s\" is not a legal branch name for Git", zMainBr);
1432
+ }
1433
+ fossil_free(z);
1434
+ }
13551435
13561436
/* Make sure the GIT repository directory exists */
13571437
rc = file_mkdir(zMirror, ExtFILE, 0);
13581438
if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror);
13591439
13601440
/* Make sure GIT has been initialized */
13611441
z = mprintf("%s/.git", zMirror);
13621442
if( !file_isdir(z, ExtFILE) ){
1363
- zCmd = mprintf("git init %$",zMirror);
1364
- gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1365
- rc = fossil_system(zCmd);
1366
- if( rc ){
1367
- fossil_fatal("cannot initialize the git repository using: \"%s\"", zCmd);
1368
- }
1369
- fossil_free(zCmd);
1443
+ zMainBr = gitmirror_init(zMirror, zMainBr);
13701444
bNeedRepack = 1;
13711445
}
13721446
fossil_free(z);
13731447
13741448
/* Make sure the .mirror_state subdirectory exists */
13751449
--- src/export.c
+++ src/export.c
@@ -1144,10 +1144,11 @@
1144 ** export */
1145 if( nErr ){
1146 gitmirror_message(VERB_ERROR,
1147 "export of %s abandoned due to missing files\n", zUuid);
1148 *pnLimit = 0;
 
1149 return 1;
1150 }
1151
1152 /* Figure out which branch this check-in is a member of */
1153 zBranch = db_text(0,
@@ -1271,10 +1272,12 @@
1271 zFNQuoted = gitmirror_quote_filename_if_needed(zFilename);
1272 fprintf(xCmd,"M %s %s %s\n", zGitMode, zMark, zFNQuoted);
1273 fossil_free(zFNQuoted);
1274 }
1275 db_finalize(&q);
 
 
1276
1277 /* Include Fossil-generated auxiliary files in the check-in */
1278 if( fManifest & MFESTFLG_RAW ){
1279 Blob manifest;
1280 content_get(rid, &manifest);
@@ -1298,10 +1301,78 @@
1298 /* The check-in is finished, so decrement the counter */
1299 (*pnLimit)--;
1300 return 0;
1301 }
1302
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1303 /*
1304 ** Implementation of the "fossil git export" command.
1305 */
1306 void gitmirror_export_command(void){
1307 const char *zLimit; /* Text of the --limit flag */
@@ -1310,11 +1381,11 @@
1310 char *zMirror; /* Name of the mirror */
1311 char *z; /* Generic string */
1312 char *zCmd; /* git command to run as a subprocess */
1313 const char *zDebug = 0; /* Value of the --debug flag */
1314 const char *zAutoPush = 0; /* Value of the --autopush flag */
1315 const char *zMainBr = 0; /* Value of the --mainbranch flag */
1316 char *zPushUrl; /* URL to sync the mirror to */
1317 double rEnd; /* time of most recent export */
1318 int rc; /* Result code */
1319 int bForce; /* Do the export and sync even if no changes*/
1320 int bNeedRepack = 0; /* True if we should run repack at the end */
@@ -1331,11 +1402,11 @@
1331 if( zLimit ){
1332 nLimit = (unsigned int)atoi(zLimit);
1333 if( nLimit<=0 ) fossil_fatal("--limit must be positive");
1334 }
1335 zAutoPush = find_option("autopush",0,1);
1336 zMainBr = find_option("mainbranch",0,1);
1337 bForce = find_option("force","f",0)!=0;
1338 bIfExists = find_option("if-mirrored",0,0)!=0;
1339 gitmirror_verbosity = VERB_NORMAL;
1340 while( find_option("quiet","q",0)!=0 ){ gitmirror_verbosity--; }
1341 while( find_option("verbose","v",0)!=0 ){ gitmirror_verbosity++; }
@@ -1350,25 +1421,28 @@
1350 zMirror = db_get("last-git-export-repo", 0);
1351 if( zMirror==0 ){
1352 if( bIfExists ) return;
1353 fossil_fatal("no Git repository specified");
1354 }
 
 
 
 
 
 
 
 
 
1355
1356 /* Make sure the GIT repository directory exists */
1357 rc = file_mkdir(zMirror, ExtFILE, 0);
1358 if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror);
1359
1360 /* Make sure GIT has been initialized */
1361 z = mprintf("%s/.git", zMirror);
1362 if( !file_isdir(z, ExtFILE) ){
1363 zCmd = mprintf("git init %$",zMirror);
1364 gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1365 rc = fossil_system(zCmd);
1366 if( rc ){
1367 fossil_fatal("cannot initialize the git repository using: \"%s\"", zCmd);
1368 }
1369 fossil_free(zCmd);
1370 bNeedRepack = 1;
1371 }
1372 fossil_free(z);
1373
1374 /* Make sure the .mirror_state subdirectory exists */
1375
--- src/export.c
+++ src/export.c
@@ -1144,10 +1144,11 @@
1144 ** export */
1145 if( nErr ){
1146 gitmirror_message(VERB_ERROR,
1147 "export of %s abandoned due to missing files\n", zUuid);
1148 *pnLimit = 0;
1149 manifest_destroy(pMan);
1150 return 1;
1151 }
1152
1153 /* Figure out which branch this check-in is a member of */
1154 zBranch = db_text(0,
@@ -1271,10 +1272,12 @@
1272 zFNQuoted = gitmirror_quote_filename_if_needed(zFilename);
1273 fprintf(xCmd,"M %s %s %s\n", zGitMode, zMark, zFNQuoted);
1274 fossil_free(zFNQuoted);
1275 }
1276 db_finalize(&q);
1277 manifest_destroy(pMan);
1278 pMan = 0;
1279
1280 /* Include Fossil-generated auxiliary files in the check-in */
1281 if( fManifest & MFESTFLG_RAW ){
1282 Blob manifest;
1283 content_get(rid, &manifest);
@@ -1298,10 +1301,78 @@
1301 /* The check-in is finished, so decrement the counter */
1302 (*pnLimit)--;
1303 return 0;
1304 }
1305
1306 /*
1307 ** Create a new Git repository at zMirror to use as the mirror.
1308 ** Try to make zMainBr be the main branch for the new repository.
1309 **
1310 ** A side-effect of this routine is that current-working directory
1311 ** is changed to zMirror.
1312 **
1313 ** If zMainBr is initially NULL, then the return value will be the
1314 ** name of the default branch to be used by Git. If zMainBr is
1315 ** initially non-NULL, then the return value will be a copy of zMainBr.
1316 */
1317 static char *gitmirror_init(
1318 const char *zMirror,
1319 char *zMainBr
1320 ){
1321 char *zCmd;
1322 int rc;
1323
1324 /* Create a new Git repository at zMirror */
1325 zCmd = mprintf("git init %$", zMirror);
1326 gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1327 rc = fossil_system(zCmd);
1328 if( rc ){
1329 fossil_fatal("cannot initialize git repository using: %s\n", zCmd);
1330 }
1331 fossil_free(zCmd);
1332
1333 /* Must be in the new Git repository directory for subsequent commands */
1334 rc = file_chdir(zMirror, 0);
1335 if( rc ){
1336 fossil_fatal("cannot change to directory \"%s\"", zMirror);
1337 }
1338
1339 if( zMainBr ){
1340 /* Set the current branch to zMainBr */
1341 zCmd = mprintf("git symbolic-ref HEAD refs/heads/%s", zMainBr);
1342 gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1343 rc = fossil_system(zCmd);
1344 if( rc ){
1345 fossil_fatal("git command failed: %s", zCmd);
1346 }
1347 fossil_free(zCmd);
1348 }else{
1349 /* If zMainBr is not specified, then check to see what branch
1350 ** name Git chose for itself */
1351 char *z;
1352 char zLine[1000];
1353 FILE *xCmd;
1354 int i;
1355 zCmd = "git symbolic-ref --short HEAD";
1356 gitmirror_message(VERB_NORMAL, "%s\n", zCmd);
1357 xCmd = popen(zCmd, "r");
1358 if( xCmd==0 ){
1359 fossil_fatal("git command failed: %s", zCmd);
1360 }
1361
1362 z = fgets(zLine, sizeof(zLine), xCmd);
1363 pclose(xCmd);
1364 if( z==0 ){
1365 fossil_fatal("no output from \"%s\"", zCmd);
1366 }
1367 for(i=0; z[i] && !fossil_isspace(z[i]); i++){}
1368 z[i] = 0;
1369 zMainBr = fossil_strdup(z);
1370 }
1371 return zMainBr;
1372 }
1373
1374 /*
1375 ** Implementation of the "fossil git export" command.
1376 */
1377 void gitmirror_export_command(void){
1378 const char *zLimit; /* Text of the --limit flag */
@@ -1310,11 +1381,11 @@
1381 char *zMirror; /* Name of the mirror */
1382 char *z; /* Generic string */
1383 char *zCmd; /* git command to run as a subprocess */
1384 const char *zDebug = 0; /* Value of the --debug flag */
1385 const char *zAutoPush = 0; /* Value of the --autopush flag */
1386 char *zMainBr = 0; /* Value of the --mainbranch flag */
1387 char *zPushUrl; /* URL to sync the mirror to */
1388 double rEnd; /* time of most recent export */
1389 int rc; /* Result code */
1390 int bForce; /* Do the export and sync even if no changes*/
1391 int bNeedRepack = 0; /* True if we should run repack at the end */
@@ -1331,11 +1402,11 @@
1402 if( zLimit ){
1403 nLimit = (unsigned int)atoi(zLimit);
1404 if( nLimit<=0 ) fossil_fatal("--limit must be positive");
1405 }
1406 zAutoPush = find_option("autopush",0,1);
1407 zMainBr = (char*)find_option("mainbranch",0,1);
1408 bForce = find_option("force","f",0)!=0;
1409 bIfExists = find_option("if-mirrored",0,0)!=0;
1410 gitmirror_verbosity = VERB_NORMAL;
1411 while( find_option("quiet","q",0)!=0 ){ gitmirror_verbosity--; }
1412 while( find_option("verbose","v",0)!=0 ){ gitmirror_verbosity++; }
@@ -1350,25 +1421,28 @@
1421 zMirror = db_get("last-git-export-repo", 0);
1422 if( zMirror==0 ){
1423 if( bIfExists ) return;
1424 fossil_fatal("no Git repository specified");
1425 }
1426
1427 if( zMainBr ){
1428 z = fossil_strdup(zMainBr);
1429 gitmirror_sanitize_name(z);
1430 if( strcmp(z, zMainBr) ){
1431 fossil_fatal("\"%s\" is not a legal branch name for Git", zMainBr);
1432 }
1433 fossil_free(z);
1434 }
1435
1436 /* Make sure the GIT repository directory exists */
1437 rc = file_mkdir(zMirror, ExtFILE, 0);
1438 if( rc ) fossil_fatal("cannot create directory \"%s\"", zMirror);
1439
1440 /* Make sure GIT has been initialized */
1441 z = mprintf("%s/.git", zMirror);
1442 if( !file_isdir(z, ExtFILE) ){
1443 zMainBr = gitmirror_init(zMirror, zMainBr);
 
 
 
 
 
 
1444 bNeedRepack = 1;
1445 }
1446 fossil_free(z);
1447
1448 /* Make sure the .mirror_state subdirectory exists */
1449

Keyboard Shortcuts

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