Fossil

Check-in [01e4de6b]
Login

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

Overview
Comment:Fix the manifest generator for check-ins so that when a partial commit is done and some of the uncommitted files have been renamed, the rows of the check-in manifest are ordered by the original, unchanged names of the uncommitted renamed files.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 01e4de6b8ae936b551bd215cce1e5a0826fe4a56
User & Date: drh 2012-06-29 12:48:28.297
References
2012-06-29
23:45
Fix a bug in the manifest generator that was introduced by check-in [01e4de6b8ae936b]. ... (check-in: 5f3a0681 user: drh tags: trunk)
Context
2012-06-29
19:35
Remove redundant include argument from the compilation steps of several source files. ... (check-in: 8a18e7fb user: mistachkin tags: trunk)
15:47
Merge in the trunk changes. ... (check-in: 0315f3f0 user: drh tags: sqlite4)
12:48
Fix the manifest generator for check-ins so that when a partial commit is done and some of the uncommitted files have been renamed, the rows of the check-in manifest are ordered by the original, unchanged names of the uncommitted renamed files. ... (check-in: 01e4de6b user: drh tags: trunk)
11:05
Update the test-parse-manifest test command so that it reports parse failures on standard output. ... (check-in: 4113f588 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/checkin.c.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  Stmt q;
  int nPrefix = strlen(zPrefix);
  int nErr = 0;
  Blob rewrittenPathname;
  db_prepare(&q, 
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE file_is_selected(id)"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  Stmt q;
  int nPrefix = strlen(zPrefix);
  int nErr = 0;
  Blob rewrittenPathname;
  db_prepare(&q, 
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id)"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);
680
681
682
683
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
  }
  blob_appendf(pOut, "C %F\n", blob_str(pComment));
  zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
  blob_appendf(pOut, "D %s\n", zDate);
  zDate[10] = ' ';
  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
    "       file_is_selected(vfile.id)"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
    " WHERE (NOT deleted OR NOT file_is_selected(vfile.id))"
    "   AND vfile.vid=%d"
    " ORDER BY 1", vid);

  blob_zero(&filename);
  blob_appendf(&filename, "%s", g.zLocalRoot);
  nBasename = blob_size(&filename);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zOrig = db_column_text(&q, 2);







|

|

|
>







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
  }
  blob_appendf(pOut, "C %F\n", blob_str(pComment));
  zDate = date_in_standard_format(zDateOvrd ? zDateOvrd : "now");
  blob_appendf(pOut, "D %s\n", zDate);
  zDate[10] = ' ';
  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid, isexe, islink,"
    "       is_selected(vfile.id)"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
    " WHERE (NOT deleted OR NOT is_selected(vfile.id))"
    "   AND vfile.vid=%d"
    " ORDER BY if_selected(vfile.id, pathname, origname)",
    vid);
  blob_zero(&filename);
  blob_appendf(&filename, "%s", g.zLocalRoot);
  nBasename = blob_size(&filename);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zOrig = db_column_text(&q, 2);
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
  */
  if( g.aCommitFile ){
    Blob unmodified;
    memset(&unmodified, 0, sizeof(Blob));
    blob_init(&unmodified, 0, 0);
    db_blob(&unmodified, 
      "SELECT pathname FROM vfile"
      " WHERE chnged = 0 AND origname IS NULL AND file_is_selected(id)"
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_fatal("file %s has not changed", blob_str(&unmodified));
    }
  }

  /*







|







1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
  */
  if( g.aCommitFile ){
    Blob unmodified;
    memset(&unmodified, 0, sizeof(Blob));
    blob_init(&unmodified, 0, 0);
    db_blob(&unmodified, 
      "SELECT pathname FROM vfile"
      " WHERE chnged = 0 AND origname IS NULL AND is_selected(id)"
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_fatal("file %s has not changed", blob_str(&unmodified));
    }
  }

  /*
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163

  /* Step 1: Insert records for all modified files into the blob 
  ** table. If there were arguments passed to this command, only
  ** the identified fils are inserted (if they have been modified).
  */
  db_prepare(&q,
    "SELECT id, %Q || pathname, mrid, %s FROM vfile "
    "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)",
    g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob",""))
  );
  while( db_step(&q)==SQLITE_ROW ){
    int id, rid;
    const char *zFullname;
    Blob content;
    int crnlOk;







|







1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

  /* Step 1: Insert records for all modified files into the blob 
  ** table. If there were arguments passed to this command, only
  ** the identified fils are inserted (if they have been modified).
  */
  db_prepare(&q,
    "SELECT id, %Q || pathname, mrid, %s FROM vfile "
    "WHERE chnged==1 AND NOT deleted AND is_selected(id)",
    g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob",""))
  );
  while( db_step(&q)==SQLITE_ROW ){
    int id, rid;
    const char *zFullname;
    Blob content;
    int crnlOk;
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
    free(zManifestFile);
    blob_reset(&muuid);
  }

  
  /* Update the vfile and vmerge tables */
  db_multi_exec(
    "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
    "DELETE FROM vmerge;"
    "UPDATE vfile SET vid=%d;"
    "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
    " WHERE file_is_selected(id);"
    , vid, nvid
  );
  db_lset_int("checkout", nvid);

  if( useCksum ){
    /* Verify that the repository checksum matches the expected checksum
    ** calculated before the checkin started (and stored as the R record







|



|







1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
    free(zManifestFile);
    blob_reset(&muuid);
  }

  
  /* Update the vfile and vmerge tables */
  db_multi_exec(
    "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND is_selected(id);"
    "DELETE FROM vmerge;"
    "UPDATE vfile SET vid=%d;"
    "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
    " WHERE is_selected(id);"
    , vid, nvid
  );
  db_lset_int("checkout", nvid);

  if( useCksum ){
    /* Verify that the repository checksum matches the expected checksum
    ** calculated before the checkin started (and stored as the R record
Changes to src/db.c.
1360
1361
1362
1363
1364
1365
1366
1367
1368


1369




1370

1371
1372

1373

1374
1375
1376
1377
1378
1379
1380


1381
1382
1383
1384
1385
1386
1387
1388
1389
1390




1391
1392


1393
1394
1395
1396
1397
1398
1399
1400
  }else if( argc==2 ){
    zP = (const char*)sqlite3_value_text(argv[1]);
    if( zP ) sqlite3_result_text(context, zP, -1, SQLITE_TRANSIENT);
  }
}

/*
** This is used by the [commit] command.
**


** Return true if either:




**

**     a) Global.aCommitFile is NULL, or
**     b) Global.aCommitFile contains the integer passed as an argument.

**

** Otherwise return false.
*/
static void file_is_selected(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){


  assert(argc==1);
  if( g.aCommitFile ){
    int iId = sqlite3_value_int(argv[0]);
    int ii;
    for(ii=0; g.aCommitFile[ii]; ii++){
      if( iId==g.aCommitFile[ii] ){
        sqlite3_result_int(context, 1);
        return;
      }
    }




    sqlite3_result_int(context, 0);
  }else{


    sqlite3_result_int(context, 1);
  }
}

/*
** Convert the input string into an SHA1.  Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.







|

>
>
|
>
>
>
>

>
|
|
>

>
|






>
>
|





|
|


>
>
>
>
|

>
>
|







1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
  }else if( argc==2 ){
    zP = (const char*)sqlite3_value_text(argv[1]);
    if( zP ) sqlite3_result_text(context, zP, -1, SQLITE_TRANSIENT);
  }
}

/*
** SQL function:
**
**       is_selected(id)
**       if_selected(id, X, Y)
**
** On the commit command, when filenames are specified (in order to do
** a partial commit) the vfile.id values for the named files are loaded
** into the g.aCommitFile[] array.  This function looks at that array
** to see if a file is named on the command-line.
**
** In the first form (1 argument) return TRUE if either no files are
** named on the command line (g.aCommitFile is NULL meaning that all
** changes are to be committed) or if id is found in g.aCommitFile[]
** (meaning that id was named on the command-line).
**
** In the second form (3 arguments) return argument X if true and Y
** if false.
*/
static void file_is_selected(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int rc = 0;

  assert(argc==1 || argc==3);
  if( g.aCommitFile ){
    int iId = sqlite3_value_int(argv[0]);
    int ii;
    for(ii=0; g.aCommitFile[ii]; ii++){
      if( iId==g.aCommitFile[ii] ){
        rc = 1;
        break;
      }
    }
  }else{
    rc = 1;
  }
  if( argc==1 ){
    sqlite3_result_int(context, rc);
  }else{
    assert( argc==3 );
    assert( rc==0 || rc==1 );
    sqlite3_result_value(context, argv[2-rc]);
  }
}

/*
** Convert the input string into an SHA1.  Make a notation in the
** CONCEALED table so that the hash can be undo using the db_reveal()
** function at some later time.
1459
1460
1461
1462
1463
1464
1465
1466



1467
1468
1469
1470
1471
1472
1473
LOCAL void db_connection_init(void){
  sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
  sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
  sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
  sqlite3_create_function(
    g.db, "file_is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0



  );
  if( g.fSqlTrace ){
    sqlite3_trace(g.db, db_sql_trace, 0);
  }
}

/*







|
>
>
>







1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
LOCAL void db_connection_init(void){
  sqlite3_exec(g.db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
  sqlite3_create_function(g.db, "user", 0, SQLITE_ANY, 0, db_sql_user, 0, 0);
  sqlite3_create_function(g.db, "cgi", 1, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(g.db, "cgi", 2, SQLITE_ANY, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(g.db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
  sqlite3_create_function(
    g.db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
  );
  sqlite3_create_function(
    g.db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
  );
  if( g.fSqlTrace ){
    sqlite3_trace(g.db, db_sql_trace, 0);
  }
}

/*
Changes to src/vfile.c.
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
void vfile_aggregate_checksum_disk(int vid, Blob *pOut){
  FILE *in;
  Stmt q;
  char zBuf[4096];

  db_must_be_within_tree();
  db_prepare(&q, 
      "SELECT %Q || pathname, pathname, origname, file_is_selected(id), rid"
      "  FROM vfile"
      " WHERE (NOT deleted OR NOT file_is_selected(id)) AND vid=%d"
      " ORDER BY pathname /*scan*/",
      g.zLocalRoot, vid
  );
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFullpath = db_column_text(&q, 0);
    const char *zName = db_column_text(&q, 1);
    int isSelected = db_column_int(&q, 3);







|

|
|







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
void vfile_aggregate_checksum_disk(int vid, Blob *pOut){
  FILE *in;
  Stmt q;
  char zBuf[4096];

  db_must_be_within_tree();
  db_prepare(&q, 
      "SELECT %Q || pathname, pathname, origname, is_selected(id), rid"
      "  FROM vfile"
      " WHERE (NOT deleted OR NOT is_selected(id)) AND vid=%d"
      " ORDER BY if_selected(id, pathname, origname) /*scan*/",
      g.zLocalRoot, vid
  );
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFullpath = db_column_text(&q, 0);
    const char *zName = db_column_text(&q, 1);
    int isSelected = db_column_int(&q, 3);
563
564
565
566
567
568
569
570

571
572
573
574
575
576
577
  Stmt q;
  Blob disk, repo;
  char *zOut;
  
  db_must_be_within_tree();
  db_prepare(&q, 
      "SELECT %Q || pathname, pathname, rid FROM vfile"
      " WHERE NOT deleted AND vid=%d AND file_is_selected(id)",

      g.zLocalRoot, vid
  );
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFullpath = db_column_text(&q, 0);
    const char *zName = db_column_text(&q, 1);
    int rid = db_column_int(&q, 2);







|
>







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  Stmt q;
  Blob disk, repo;
  char *zOut;
  
  db_must_be_within_tree();
  db_prepare(&q, 
      "SELECT %Q || pathname, pathname, rid FROM vfile"
      " WHERE NOT deleted AND vid=%d AND is_selected(id)"
      " ORDER BY if_selected(id, pathname, origname) /*scan*/",
      g.zLocalRoot, vid
  );
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zFullpath = db_column_text(&q, 0);
    const char *zName = db_column_text(&q, 1);
    int rid = db_column_int(&q, 2);
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
void vfile_aggregate_checksum_repository(int vid, Blob *pOut){
  Blob file;
  Stmt q;
  char zBuf[100];

  db_must_be_within_tree();
 
  db_prepare(&q, "SELECT pathname, origname, rid, file_is_selected(id)"
                 " FROM vfile"
                 " WHERE (NOT deleted OR NOT file_is_selected(id))"
                 "   AND rid>0 AND vid=%d"
                 " ORDER BY pathname /*scan*/",
                 vid);
  blob_zero(&file);
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zOrigName = db_column_text(&q, 1);
    int rid = db_column_int(&q, 2);







|

|

|







626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
void vfile_aggregate_checksum_repository(int vid, Blob *pOut){
  Blob file;
  Stmt q;
  char zBuf[100];

  db_must_be_within_tree();
 
  db_prepare(&q, "SELECT pathname, origname, rid, is_selected(id)"
                 " FROM vfile"
                 " WHERE (NOT deleted OR NOT is_selected(id))"
                 "   AND rid>0 AND vid=%d"
                 " ORDER BY if_selected(id,pathname,origname) /*scan*/",
                 vid);
  blob_zero(&file);
  md5sum_init();
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    const char *zOrigName = db_column_text(&q, 1);
    int rid = db_column_int(&q, 2);