Fossil

Check-in [8d6bdd1e]
Login

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

Overview
Comment:Add support for the "l" flag to the "manifest" setting to enable creation of a file "manifest.symlinks" which lists the names of all symlinks
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | enhanced-symlink
Files: files | file ages | folders
SHA3-256: 8d6bdd1e00cf2cf8bc7fd101fcff023a915428e13e7f64bb8dde201a416f7aae
User & Date: andygoth 2017-09-29 00:53:31
Context
2017-10-14
19:28
Merge trunk check-in: 057645a9 user: andygoth tags: enhanced-symlink
2017-09-29
00:53
Add support for the "l" flag to the "manifest" setting to enable creation of a file "manifest.symlinks" which lists the names of all symlinks check-in: 8d6bdd1e user: andygoth tags: enhanced-symlink
2017-09-28
18:18
Fix indentation of unanalyzed lines on /annotate and /blame screens. check-in: 00ced6df user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/add.c.

76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
  /* Possible names of auxiliary files generated when the "manifest" property
  ** is used
  */
  static const struct {
    const char *fname;
    int flg;
  }aManifestflags[] = {
    { "manifest",      MFESTFLG_RAW },
    { "manifest.uuid", MFESTFLG_UUID },
    { "manifest.tags", MFESTFLG_TAGS }

  };
  static const char *azManifests[3];

  /*
  ** Names of repository files, if they exist in the checkout.
  */
  static const char *azRepo[4] = { 0, 0, 0, 0 };

  /* Cached setting "manifest" */







|
|
|
>

|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  /* Possible names of auxiliary files generated when the "manifest" property
  ** is used
  */
  static const struct {
    const char *fname;
    int flg;
  }aManifestflags[] = {
    { "manifest",          MFESTFLG_RAW },
    { "manifest.uuid",     MFESTFLG_UUID },
    { "manifest.tags",     MFESTFLG_TAGS },
    { "manifest.symlinks", MFESTFLG_SYMLINKS }
  };
  static const char *azManifests[4];

  /*
  ** Names of repository files, if they exist in the checkout.
  */
  static const char *azRepo[4] = { 0, 0, 0, 0 };

  /* Cached setting "manifest" */

Changes to src/checkin.c.

2611
2612
2613
2614
2615
2616
2617










2618
2619
2620
2621
2622
2623
2624
2625
    zManifestFile = mprintf("%smanifest.tags", g.zLocalRoot);
    blob_zero(&tagslist);
    get_checkin_taglist(nvid, &tagslist);
    blob_write_to_file(&tagslist, zManifestFile);
    blob_reset(&tagslist);
    free(zManifestFile);
  }











  if( !g.markPrivate ){
    autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}







>
>
>
>
>
>
>
>
>
>








2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
    zManifestFile = mprintf("%smanifest.tags", g.zLocalRoot);
    blob_zero(&tagslist);
    get_checkin_taglist(nvid, &tagslist);
    blob_write_to_file(&tagslist, zManifestFile);
    blob_reset(&tagslist);
    free(zManifestFile);
  }

  if( outputManifest & MFESTFLG_SYMLINKS ){
    Blob symlinkslist;
    zManifestFile = mprintf("%smanifest.symlinks", g.zLocalRoot);
    blob_zero(&symlinkslist);
    get_checkin_symlinklist(nvid, &symlinkslist);
    blob_write_to_file(&symlinkslist, zManifestFile);
    blob_reset(&symlinkslist);
    free(zManifestFile);
  }

  if( !g.markPrivate ){
    autosync_loop(SYNC_PUSH|SYNC_PULL, db_get_int("autosync-tries", 1), 0);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}

Changes to src/checkout.c.

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
...
180
181
182
183
184
185
186














187
188
189
190
191
192
193
...
214
215
216
217
218
219
220

















221
222
223
224
225
226
227
  db_bind_text(&s, ":path", zFilename);
  db_step(&s);
  db_reset(&s);
}

/*
** Set or clear the execute permission bit (as appropriate) for all
** files in the current check-out, and replace files that have
** symlink bit with actual symlinks.
*/
void checkout_set_all_exe(int vid){
  Blob filename;
  int baseLen;
  Manifest *pManifest;
  ManifestFile *pFile;

................................................................................


/*
** If the "manifest" setting is true, then automatically generate
** files named "manifest" and "manifest.uuid" containing, respectively,
** the text of the manifest and the artifact ID of the manifest.
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
  char *zManFile;
  Blob manifest;
  Blob taglist;

  int flg;

  flg = db_get_manifest_setting();

  if( flg & MFESTFLG_RAW ){
    blob_zero(&manifest);
    content_get(vid, &manifest);
................................................................................
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
      zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }














}

/*
** Find the branch name and all symbolic tags for a particular check-in
** identified by "rid".
**
** The branch name is actually only extracted if this procedure is run
................................................................................
    zName = db_column_text(&stmt, 0);
    blob_appendf(pOut, "tag %s\n", zName);
  }
  db_reset(&stmt);
  db_finalize(&stmt);
}



















/*
** COMMAND: checkout*
** COMMAND: co*
**
** Usage: %fossil checkout ?VERSION | --latest? ?OPTIONS?
**    or: %fossil co ?VERSION | --latest? ?OPTIONS?







|
<







 







|
|





>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
  db_bind_text(&s, ":path", zFilename);
  db_step(&s);
  db_reset(&s);
}

/*
** Set or clear the execute permission bit (as appropriate) for all
** files in the current check-out.

*/
void checkout_set_all_exe(int vid){
  Blob filename;
  int baseLen;
  Manifest *pManifest;
  ManifestFile *pFile;

................................................................................


/*
** If the "manifest" setting is true, then automatically generate
** files named "manifest" and "manifest.uuid" containing, respectively,
** the text of the manifest and the artifact ID of the manifest.
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid",
** "manifest.tags", or "manifest.symlinks".
*/
void manifest_to_disk(int vid){
  char *zManFile;
  Blob manifest;
  Blob taglist;
  Blob symlinklist;
  int flg;

  flg = db_get_manifest_setting();

  if( flg & MFESTFLG_RAW ){
    blob_zero(&manifest);
    content_get(vid, &manifest);
................................................................................
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
      zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
  if( flg & MFESTFLG_SYMLINKS ){
    blob_zero(&symlinklist);
    zManFile = mprintf("%smanifest.symlinks", g.zLocalRoot);
    get_checkin_symlinklist(vid, &symlinklist);
    blob_write_to_file(&symlinklist, zManFile);
    free(zManFile);
    blob_reset(&symlinklist);
  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.symlinks'") ){
      zManFile = mprintf("%smanifest.symlinks", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
}

/*
** Find the branch name and all symbolic tags for a particular check-in
** identified by "rid".
**
** The branch name is actually only extracted if this procedure is run
................................................................................
    zName = db_column_text(&stmt, 0);
    blob_appendf(pOut, "tag %s\n", zName);
  }
  db_reset(&stmt);
  db_finalize(&stmt);
}

/*
** Store into "pOut" a sorted list of all symlinks in a checkin "rid".  Each
** entry in the list is the full name of the symlink (not the name of its
** target) followed by a newline.
*/
void get_checkin_symlinklist(int rid, Blob *pOut){
  Manifest *pManifest = manifest_get(rid, CFTYPE_MANIFEST, 0);
  ManifestFile *pFile;
  blob_reset(pOut);
  manifest_file_rewind(pManifest);
  while( (pFile = manifest_file_next(pManifest, 0)) ){
    if( pFile->zPerm && strstr(pFile->zPerm, "l") ){
      blob_appendf(pOut, "%s\n", pFile->zName);
    }
  }
  manifest_destroy(pManifest);
}

/*
** COMMAND: checkout*
** COMMAND: co*
**
** Usage: %fossil checkout ?VERSION | --latest? ?OPTIONS?
**    or: %fossil co ?VERSION | --latest? ?OPTIONS?

Changes to src/db.c.

2473
2474
2475
2476
2477
2478
2479
2480
2481
2482

2483
2484
2485
2486
2487
2488
2489
....
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505

2506
2507
2508
2509
2510
2511
2512
....
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}

#if INTERFACE
/* Manifest generation flags */
#define MFESTFLG_RAW  0x01
#define MFESTFLG_UUID 0x02
#define MFESTFLG_TAGS 0x04

#endif /* INTERFACE */

/*
** Get the manifest setting.  For backwards compatibility first check if the
** value is a boolean.  If it's not a boolean, treat each character as a flag
** to enable a manifest type.  This system puts certain boundary conditions on
** which letters can be used to represent flags (any permutation of flags must
................................................................................
    return 0;
  }else if( is_truth(zVal) ){
    return MFESTFLG_RAW|MFESTFLG_UUID;
  }
  flg = 0;
  while( *zVal ){
    switch( *zVal ){
      case 'r': flg |= MFESTFLG_RAW;  break;
      case 'u': flg |= MFESTFLG_UUID; break;
      case 't': flg |= MFESTFLG_TAGS; break;

    }
    zVal++;
  }
  return flg;
}


................................................................................
** The value is the primary branch for the project.
*/
/*
** SETTING: manifest         width=5 versionable
** If enabled, automatically create files "manifest" and "manifest.uuid"
** in every checkout.
**
** Optionally use combinations of characters 'r' for "manifest",
** 'u' for "manifest.uuid" and 't' for "manifest.tags".  The SQLite
** and Fossil repositories both require manifests.
*/
/*
** SETTING: max-loadavg      width=25 default=0.0
** Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
** are disallowed if the system load average goes above this
** value.  "0.0" means no limit.  This only works on unix.
** Only local settings of this value make a difference since







|
|
|
>







 







|
|
|
>







 







|
|
|







2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
....
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
....
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}

#if INTERFACE
/* Manifest generation flags */
#define MFESTFLG_RAW      0x01
#define MFESTFLG_UUID     0x02
#define MFESTFLG_TAGS     0x04
#define MFESTFLG_SYMLINKS 0x08
#endif /* INTERFACE */

/*
** Get the manifest setting.  For backwards compatibility first check if the
** value is a boolean.  If it's not a boolean, treat each character as a flag
** to enable a manifest type.  This system puts certain boundary conditions on
** which letters can be used to represent flags (any permutation of flags must
................................................................................
    return 0;
  }else if( is_truth(zVal) ){
    return MFESTFLG_RAW|MFESTFLG_UUID;
  }
  flg = 0;
  while( *zVal ){
    switch( *zVal ){
      case 'r': flg |= MFESTFLG_RAW;      break;
      case 'u': flg |= MFESTFLG_UUID;     break;
      case 't': flg |= MFESTFLG_TAGS;     break;
      case 'l': flg |= MFESTFLG_SYMLINKS; break;
    }
    zVal++;
  }
  return flg;
}


................................................................................
** The value is the primary branch for the project.
*/
/*
** SETTING: manifest         width=5 versionable
** If enabled, automatically create files "manifest" and "manifest.uuid"
** in every checkout.
**
** Optionally use combinations of characters 'r' for "manifest", 'u' for
** "manifest.uuid", 't' for "manifest.tags", and 'l' for "manifest.symlinks".
** The SQLite and Fossil repositories both require manifests.
*/
/*
** SETTING: max-loadavg      width=25 default=0.0
** Some CPU-intensive web pages (ex: /zip, /tarball, /blame)
** are disallowed if the system load average goes above this
** value.  "0.0" means no limit.  This only works on unix.
** Only local settings of this value make a difference since

Changes to src/tar.c.

512
513
514
515
516
517
518





519
520
521
522
523
524
525
...
540
541
542
543
544
545
546










547
548
549
550
551
552
553
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }






      if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
        if( eflg & MFESTFLG_RAW ){
          blob_append(&filename, "manifest", -1);
          zName = blob_str(&filename);
        }
        if( eflg & MFESTFLG_RAW ) {
................................................................................
        blob_zero(&tagslist);
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        tar_add_file(zName, &tagslist, 0, mTime);
        blob_reset(&tagslist);










      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;







>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.symlinks"))
       && !glob_match(pExclude, "manifest.symlinks")
       && (flg & MFESTFLG_SYMLINKS) ){
        eflg |= MFESTFLG_SYMLINKS;
      }

      if( eflg & (MFESTFLG_RAW|MFESTFLG_UUID) ){
        if( eflg & MFESTFLG_RAW ){
          blob_append(&filename, "manifest", -1);
          zName = blob_str(&filename);
        }
        if( eflg & MFESTFLG_RAW ) {
................................................................................
        blob_zero(&tagslist);
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        tar_add_file(zName, &tagslist, 0, mTime);
        blob_reset(&tagslist);
      }
      if( eflg & MFESTFLG_SYMLINKS ){
        Blob symlinklist;
        blob_zero(&symlinklist);
        get_checkin_symlinklist(rid, &symlinklist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.symlinks", -1);
        zName = blob_str(&filename);
        tar_add_file(zName, &symlinklist, 0, mTime);
        blob_reset(&symlinklist);
      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;

Changes to src/zip.c.

369
370
371
372
373
374
375





376
377
378
379
380
381
382
...
395
396
397
398
399
400
401











402
403
404
405
406
407
408
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }






      if( eflg & MFESTFLG_RAW ){
        blob_append(&filename, "manifest", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        sterilize_manifest(&mfile);
        zip_add_file(zName, &mfile, 0);
................................................................................
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        zip_add_file(zName, &tagslist, 0);
        blob_reset(&tagslist);











      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;







>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
        eflg |= MFESTFLG_UUID;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.tags"))
       && !glob_match(pExclude, "manifest.tags")
       && (flg & MFESTFLG_TAGS) ){
        eflg |= MFESTFLG_TAGS;
      }
      if( (pInclude==0 || glob_match(pInclude, "manifest.symlinks"))
       && !glob_match(pExclude, "manifest.symlinks")
       && (flg & MFESTFLG_SYMLINKS) ){
        eflg |= MFESTFLG_SYMLINKS;
      }

      if( eflg & MFESTFLG_RAW ){
        blob_append(&filename, "manifest", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        sterilize_manifest(&mfile);
        zip_add_file(zName, &mfile, 0);
................................................................................
        get_checkin_taglist(rid, &tagslist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.tags", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        zip_add_file(zName, &tagslist, 0);
        blob_reset(&tagslist);
      }
      if( eflg & MFESTFLG_SYMLINKS ){
        Blob symlinklist;
        blob_zero(&symlinklist);
        get_checkin_symlinklist(rid, &symlinklist);
        blob_resize(&filename, nPrefix);
        blob_append(&filename, "manifest.symlinks", -1);
        zName = blob_str(&filename);
        zip_add_folders(zName);
        zip_add_file(zName, &symlinklist, 0);
        blob_reset(&symlinklist);
      }
    }
    manifest_file_rewind(pManifest);
    while( (pFile = manifest_file_next(pManifest,0))!=0 ){
      int fid;
      if( pInclude!=0 && !glob_match(pInclude, pFile->zName) ) continue;
      if( glob_match(pExclude, pFile->zName) ) continue;

Changes to www/changes.wiki.

28
29
30
31
32
33
34


35
36
37
38
39
40
41
  *  Correct the [/help?cmd=/doc|/doc] page to support read-only repositories.
  *  Correct [/help?cmd=/zip|/zip], [/help?cmd=/tarball|/tarball],
     [/help?cmd=zip|zip], and [/help?cmd=tarball|tarball] pages and commands to
     honor the versioned manifest setting when outside of an open checkout
     directory.
  *  The admin-log and access-log settings are now on by default for
     new repositories.


  *  Update the built-in SQLite to version 3.20.1.

<a name='v2_3'></a>
<h2>Changes for Version 2.3 (2017-07-21)</h2>

  *  Update the built-in SQLite to version 3.20.0 (beta).
  *  Update internal Unicode character tables, used in regular expression







>
>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  *  Correct the [/help?cmd=/doc|/doc] page to support read-only repositories.
  *  Correct [/help?cmd=/zip|/zip], [/help?cmd=/tarball|/tarball],
     [/help?cmd=zip|zip], and [/help?cmd=tarball|tarball] pages and commands to
     honor the versioned manifest setting when outside of an open checkout
     directory.
  *  The admin-log and access-log settings are now on by default for
     new repositories.
  *  Add support for the "l" flag to the "manifest" setting to enable creation
     of a file "manifest.symlinks" which lists the names of all symlinks.
  *  Update the built-in SQLite to version 3.20.1.

<a name='v2_3'></a>
<h2>Changes for Version 2.3 (2017-07-21)</h2>

  *  Update the built-in SQLite to version 3.20.0 (beta).
  *  Update internal Unicode character tables, used in regular expression