Fossil

Check-in [7c30266a45]
Login

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

Overview
Comment:replaced 'checkin' with 'check-in' in code-comment, inline command help-text, SQL-statement comment, fatal error messages and some non-functional webpage-content
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | ml-jb-doc-typos
Files: files | file ages | folders
SHA1: 7c30266a4558d6569653f8ca0f2b6885a10a75af
User & Date: michai 2015-02-28 10:11:25.272
Context
2015-02-28
18:24
changed 'localtime' to 'local time' in WWW-docs, and other typo Closed-Leaf check-in: 83656a4dfd user: michai tags: ml-jb-doc-typos
10:11
replaced 'checkin' with 'check-in' in code-comment, inline command help-text, SQL-statement comment, fatal error messages and some non-functional webpage-content check-in: 7c30266a45 user: michai tags: ml-jb-doc-typos
08:39
fixed some typos suggested in private email check-in: 34f6402847 user: michai tags: ml-jb-doc-typos
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/add.c.
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
**    or: %fossil mv|rename OLDNAME... DIR
**
** Move or rename one or more files or directories within the repository tree.
** You can either rename a file or directory or move it to another subdirectory.
**
** This command does NOT rename or move the files on disk.  This command merely
** records the fact that filenames have changed so that appropriate notations
** can be made at the next commit/checkin.
**
** Options:
**   --case-sensitive <BOOL> Override the case-sensitive setting.
**
** See also: changes, status
*/
void mv_cmd(void){







|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
**    or: %fossil mv|rename OLDNAME... DIR
**
** Move or rename one or more files or directories within the repository tree.
** You can either rename a file or directory or move it to another subdirectory.
**
** This command does NOT rename or move the files on disk.  This command merely
** records the fact that filenames have changed so that appropriate notations
** can be made at the next commit/check-in.
**
** Options:
**   --case-sensitive <BOOL> Override the case-sensitive setting.
**
** See also: changes, status
*/
void mv_cmd(void){
Changes to src/browse.c.
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
  }else{
    zClass = mprintf("file");
  }
  return zClass;
}

/*
** SQL used to compute the age of all files in checkin :ckin whose
** names match :glob
*/
static const char zComputeFileAgeSetup[] =
@ CREATE TABLE IF NOT EXISTS temp.fileage(
@   fnid INTEGER PRIMARY KEY,
@   fid INTEGER,
@   mid INTEGER,







|







871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
  }else{
    zClass = mprintf("file");
  }
  return zClass;
}

/*
** SQL used to compute the age of all files in check-in :ckin whose
** names match :glob
*/
static const char zComputeFileAgeSetup[] =
@ CREATE TABLE IF NOT EXISTS temp.fileage(
@   fnid INTEGER PRIMARY KEY,
@   fid INTEGER,
@   mid INTEGER,
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
@  ORDER BY event.mtime ASC;
;

/*
** Look at all file containing in the version "vid".  Construct a
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that checkin. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){
  Stmt q;
  db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
  db_prepare(&q, zComputeFileAgeRun  /*works-like:"constant"*/);
  db_bind_int(&q, ":ckin", vid);







|







911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
@  ORDER BY event.mtime ASC;
;

/*
** Look at all file containing in the version "vid".  Construct a
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that check-in. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){
  Stmt q;
  db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
  db_prepare(&q, zComputeFileAgeRun  /*works-like:"constant"*/);
  db_bind_int(&q, ":ckin", vid);
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  db_finalize(&q);
}

/*
** WEBPAGE:  fileage
**
** Parameters:
**   name=VERSION   Selects the checkin version (default=tip).
**   glob=STRING    Only shows files matching this glob pattern
**                  (e.g. *.c or *.txt).
**   showid         Show RID values for debugging
*/
void fileage_page(void){
  int rid;
  const char *zName;
  const char *zGlob;
  const char *zUuid;
  const char *zNow;            /* Time of checkin */
  int showId = PB("showid");
  Stmt q1, q2;
  double baseTime;
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  zName = P("name");
  if( zName==0 ) zName = "tip";







|









|







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
  db_finalize(&q);
}

/*
** WEBPAGE:  fileage
**
** Parameters:
**   name=VERSION   Selects the check-in version (default=tip).
**   glob=STRING    Only shows files matching this glob pattern
**                  (e.g. *.c or *.txt).
**   showid         Show RID values for debugging
*/
void fileage_page(void){
  int rid;
  const char *zName;
  const char *zGlob;
  const char *zUuid;
  const char *zNow;            /* Time of check-in */
  int showId = PB("showid");
  Stmt q1, q2;
  double baseTime;
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  zName = P("name");
  if( zName==0 ) zName = "tip";
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  @ <h2>Files in
  @ %z(href("%R/info/%!S",zUuid))[%S(zUuid)]</a>
  if( zGlob && zGlob[0] ){
    @ that match "%h(zGlob)" and
  }
  @ ordered by check-in time</h2>
  @
  @ <p>Times are relative to the checkin time for
  @ %z(href("%R/ci/%!S",zUuid))[%S(zUuid)]</a> which is
  @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
  @
  @ <div class='fileage'><table>
  @ <tr><th>Time</th><th>Files</th><th>Check-in</th></tr>
  db_prepare(&q1,
    "SELECT event.mtime, event.objid, blob.uuid,\n"







|







1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  @ <h2>Files in
  @ %z(href("%R/info/%!S",zUuid))[%S(zUuid)]</a>
  if( zGlob && zGlob[0] ){
    @ that match "%h(zGlob)" and
  }
  @ ordered by check-in time</h2>
  @
  @ <p>Times are relative to the check-in time for
  @ %z(href("%R/ci/%!S",zUuid))[%S(zUuid)]</a> which is
  @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
  @
  @ <div class='fileage'><table>
  @ <tr><th>Time</th><th>Files</th><th>Check-in</th></tr>
  db_prepare(&q1,
    "SELECT event.mtime, event.objid, blob.uuid,\n"
Changes to src/bundle.c.
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    blob_reset(&hash);
  }
  db_end_transaction(0);
  db_finalize(&q);
}

/*
** Identify a subsection of the checkin tree using command-line switches.
** There must be one of the following switch available:
**
**     --branch BRANCHNAME          All checkins on the most recent
**                                  instance of BRANCHNAME
**     --from TAG1 [--to TAG2]      Checkin TAG1 and all primary descendants
**                                  up to and including TAG2
**     --checkin TAG                Checkin TAG only
**
** Store the RIDs for all applicable checkins in the zTab table that 
** should already exist.  Invoke fossil_fatal() if any kind of error is
** seen.
*/
void subtree_from_arguments(const char *zTab){
  const char *zBr;
  const char *zFrom;
  const char *zTo;







|


|

|

|

|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    blob_reset(&hash);
  }
  db_end_transaction(0);
  db_finalize(&q);
}

/*
** Identify a subsection of the check-in tree using command-line switches.
** There must be one of the following switch available:
**
**     --branch BRANCHNAME          All check-ins on the most recent
**                                  instance of BRANCHNAME
**     --from TAG1 [--to TAG2]      Check-in TAG1 and all primary descendants
**                                  up to and including TAG2
**     --checkin TAG                Check-in TAG only
**
** Store the RIDs for all applicable check-ins in the zTab table that 
** should already exist.  Invoke fossil_fatal() if any kind of error is
** seen.
*/
void subtree_from_arguments(const char *zTab){
  const char *zBr;
  const char *zFrom;
  const char *zTo;
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
}

/*
** COMMAND: test-subtree
**
** Usage: %fossil test-subtree ?OPTIONS?
**
** Show the subset of checkins that match the supplied options.  This
** command is used to test the subtree_from_options() subroutine in the
** implementation and does not really have any other practical use that
** we know of.
**
** Options:
**    --branch BRANCH           Include only checkins on BRANCH
**    --from TAG                Start the subtree at TAG
**    --to TAG                  End the subtree at TAG
**    --checkin TAG             The subtree is the single checkin TAG
**    --all                     Include FILE and TAG artifacts
**    --exclusive               Include FILES exclusively on checkins
*/
void test_subtree_cmd(void){
  int bAll = find_option("all",0,0)!=0;
  int bExcl = find_option("exclusive",0,0)!=0;
  db_find_and_open_repository(0,0);
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE tobundle(rid INTEGER PRIMARY KEY);");







|





|


|

|







252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
}

/*
** COMMAND: test-subtree
**
** Usage: %fossil test-subtree ?OPTIONS?
**
** Show the subset of check-ins that match the supplied options.  This
** command is used to test the subtree_from_options() subroutine in the
** implementation and does not really have any other practical use that
** we know of.
**
** Options:
**    --branch BRANCH           Include only check-ins on BRANCH
**    --from TAG                Start the subtree at TAG
**    --to TAG                  End the subtree at TAG
**    --checkin TAG             The subtree is the single check-in TAG
**    --all                     Include FILE and TAG artifacts
**    --exclusive               Include FILES exclusively on check-ins
*/
void test_subtree_cmd(void){
  int bAll = find_option("all",0,0)!=0;
  int bExcl = find_option("exclusive",0,0)!=0;
  db_find_and_open_repository(0,0);
  db_begin_transaction();
  db_multi_exec("CREATE TEMP TABLE tobundle(rid INTEGER PRIMARY KEY);");
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
}

/* fossil bundle purge BUNDLE
**
** Try to undo a prior "bundle import BUNDLE".
**
** If the --force option is omitted, then this will only work if
** there have been no checkins or tags added that use the import.
**
** This routine never removes content that is not already in the bundle
** so the bundle serves as a backup.  The purge can be undone using
** "fossil bundle import BUNDLE".
*/
static void bundle_purge_cmd(void){
  int bForce = find_option("force",0,0)!=0;
  int bTest = find_option("test",0,0)!=0;  /* Undocumented --test option */
  const char *zFile = g.argv[3];
  verify_all_options();
  if ( g.argc!=4 ) usage("purge BUNDLE ?OPTIONS?");
  bundle_attach_file(zFile, "b1", 0);
  db_begin_transaction();

  /* Find all checkins of the bundle */
  db_multi_exec(
    "CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY);"
    "INSERT OR IGNORE INTO ok SELECT blob.rid FROM bblob, blob, plink"
    " WHERE bblob.uuid=blob.uuid"
    "   AND plink.cid=blob.rid;"
  );

  /* Check to see if new checkins have been committed to checkins in
  ** the bundle.  Do not allow the purge if that is true and if --force
  ** is omitted.
  */
  if( !bForce ){
    Stmt q;
    int n = 0;
    db_prepare(&q,
      "SELECT cid FROM plink WHERE pid IN ok AND cid NOT IN ok"
    );
    while( db_step(&q)==SQLITE_ROW ){
      whatis_rid(db_column_int(&q,0),0);
      fossil_print("%.78c\n", '-');
      n++;
    }
    db_finalize(&q);
    if( n>0 ){
      fossil_fatal("checkins above are derived from checkins in the bundle.");
    }
  }

  /* Find all files associated with those check-ins that are used
  ** nowhere else. */
  find_checkin_associates("ok", 1);

  /* Check to see if any associated files are not in the bundle.  Issue
  ** an error if there are any, unless --force is used.
  */
  if( !bForce ){
    db_multi_exec(
       "CREATE TEMP TABLE err1(rid INTEGER PRIMARY KEY);"
       "INSERT INTO err1 "
       " SELECT blob.rid FROM ok CROSS JOIN blob"
       "     WHERE blob.rid=ok.rid"
       "       AND blob.uuid NOT IN (SELECT uuid FROM bblob);"
    );
    if( db_changes() ){
      describe_artifacts_to_stdout("IN err1", 0);
      fossil_fatal("artifacts above associated with bundle checkins "
                   " are not in the bundle");
    }else{
      db_multi_exec("DROP TABLE err1;");
    }
  }

  if( bTest ){







|














|







|
















|




















|







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
}

/* fossil bundle purge BUNDLE
**
** Try to undo a prior "bundle import BUNDLE".
**
** If the --force option is omitted, then this will only work if
** there have been no check-ins or tags added that use the import.
**
** This routine never removes content that is not already in the bundle
** so the bundle serves as a backup.  The purge can be undone using
** "fossil bundle import BUNDLE".
*/
static void bundle_purge_cmd(void){
  int bForce = find_option("force",0,0)!=0;
  int bTest = find_option("test",0,0)!=0;  /* Undocumented --test option */
  const char *zFile = g.argv[3];
  verify_all_options();
  if ( g.argc!=4 ) usage("purge BUNDLE ?OPTIONS?");
  bundle_attach_file(zFile, "b1", 0);
  db_begin_transaction();

  /* Find all check-ins of the bundle */
  db_multi_exec(
    "CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY);"
    "INSERT OR IGNORE INTO ok SELECT blob.rid FROM bblob, blob, plink"
    " WHERE bblob.uuid=blob.uuid"
    "   AND plink.cid=blob.rid;"
  );

  /* Check to see if new check-ins have been committed to check-ins in
  ** the bundle.  Do not allow the purge if that is true and if --force
  ** is omitted.
  */
  if( !bForce ){
    Stmt q;
    int n = 0;
    db_prepare(&q,
      "SELECT cid FROM plink WHERE pid IN ok AND cid NOT IN ok"
    );
    while( db_step(&q)==SQLITE_ROW ){
      whatis_rid(db_column_int(&q,0),0);
      fossil_print("%.78c\n", '-');
      n++;
    }
    db_finalize(&q);
    if( n>0 ){
      fossil_fatal("check-ins above are derived from check-ins in the bundle.");
    }
  }

  /* Find all files associated with those check-ins that are used
  ** nowhere else. */
  find_checkin_associates("ok", 1);

  /* Check to see if any associated files are not in the bundle.  Issue
  ** an error if there are any, unless --force is used.
  */
  if( !bForce ){
    db_multi_exec(
       "CREATE TEMP TABLE err1(rid INTEGER PRIMARY KEY);"
       "INSERT INTO err1 "
       " SELECT blob.rid FROM ok CROSS JOIN blob"
       "     WHERE blob.rid=ok.rid"
       "       AND blob.uuid NOT IN (SELECT uuid FROM bblob);"
    );
    if( db_changes() ){
      describe_artifacts_to_stdout("IN err1", 0);
      fossil_fatal("artifacts above associated with bundle check-ins "
                   " are not in the bundle");
    }else{
      db_multi_exec("DROP TABLE err1;");
    }
  }

  if( bTest ){
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
**      consecutively on standard output.  This subcommand was designed
**      for testing and introspection of bundles and is not something
**      commonly used.
**
**   fossil bundle export BUNDLE ?OPTIONS?
**
**      Generate a new bundle, in the file named BUNDLE, that contains a
**      subset of the checkins in the repository (usually a single branch)
**      described by the --branch, --from, --to, and/or --checkin options,
**      at least one of which is required.  If BUNDLE already exists, the
**      specified content is added to the bundle.
**
**         --branch BRANCH            Package all check-ins on BRANCH.
**         --from TAG1 --to TAG2      Package checkins between TAG1 and TAG2.
**         --checkin TAG              Package the single checkin TAG
**         --standalone               Do no use delta-encoding against
**                                      artifacts not in the bundle
**
**   fossil bundle extend BUNDLE
**
**      The BUNDLE must already exist.  This subcommand adds to the bundle
**      any checkins that are descendants of checkins already in the bundle,
**      and any tags that apply to artifacts in the bundle.
**
**   fossil bundle import BUNDLE ?--publish?
**
**      Import all content from BUNDLE into the repository.  By default, the
**      imported files are private and will not sync.  Use the --publish
**      option makes the import public.
**
**   fossil bundle ls BUNDLE
**
**      List the contents of BUNDLE on standard output
**
**   fossil bundle purge BUNDLE
**
**      Remove from the repository all files that are used exclusively 
**      by checkins in BUNDLE.  This has the effect of undoing a
**      "fossil bundle import".
**
** SUMMARY:
**   fossil bundle append BUNDLE FILE...              Add files to BUNDLE
**   fossil bundle cat BUNDLE UUID...                 Extract file from BUNDLE
**   fossil bundle export BUNDLE ?OPTIONS?            Create a new BUNDLE
**          --branch BRANCH --from TAG1 --to TAG2       Checkins to include
**          --checkin TAG                               Use only checkin TAG
**          --standalone                                Omit dependencies
**   fossil bundle extend BUNDLE                      Update with newer content
**   fossil bundle import BUNDLE ?OPTIONS?            Import a bundle
**          --publish                                   Publish the import
**          --force                                     Cross-repo import
**   fossil bundle ls BUNDLE                          List content of a bundle
**   fossil bundle purge BUNDLE                       Undo an import







|





|
|






|















|






|
|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
**      consecutively on standard output.  This subcommand was designed
**      for testing and introspection of bundles and is not something
**      commonly used.
**
**   fossil bundle export BUNDLE ?OPTIONS?
**
**      Generate a new bundle, in the file named BUNDLE, that contains a
**      subset of the check-ins in the repository (usually a single branch)
**      described by the --branch, --from, --to, and/or --checkin options,
**      at least one of which is required.  If BUNDLE already exists, the
**      specified content is added to the bundle.
**
**         --branch BRANCH            Package all check-ins on BRANCH.
**         --from TAG1 --to TAG2      Package check-ins between TAG1 and TAG2.
**         --checkin TAG              Package the single check-in TAG
**         --standalone               Do no use delta-encoding against
**                                      artifacts not in the bundle
**
**   fossil bundle extend BUNDLE
**
**      The BUNDLE must already exist.  This subcommand adds to the bundle
**      any check-ins that are descendants of check-ins already in the bundle,
**      and any tags that apply to artifacts in the bundle.
**
**   fossil bundle import BUNDLE ?--publish?
**
**      Import all content from BUNDLE into the repository.  By default, the
**      imported files are private and will not sync.  Use the --publish
**      option makes the import public.
**
**   fossil bundle ls BUNDLE
**
**      List the contents of BUNDLE on standard output
**
**   fossil bundle purge BUNDLE
**
**      Remove from the repository all files that are used exclusively 
**      by check-ins in BUNDLE.  This has the effect of undoing a
**      "fossil bundle import".
**
** SUMMARY:
**   fossil bundle append BUNDLE FILE...              Add files to BUNDLE
**   fossil bundle cat BUNDLE UUID...                 Extract file from BUNDLE
**   fossil bundle export BUNDLE ?OPTIONS?            Create a new BUNDLE
**          --branch BRANCH --from TAG1 --to TAG2       Check-ins to include
**          --checkin TAG                               Use only check-in TAG
**          --standalone                                Omit dependencies
**   fossil bundle extend BUNDLE                      Update with newer content
**   fossil bundle import BUNDLE ?OPTIONS?            Import a bundle
**          --publish                                   Publish the import
**          --force                                     Cross-repo import
**   fossil bundle ls BUNDLE                          List content of a bundle
**   fossil bundle purge BUNDLE                       Undo an import
Changes to src/checkin.c.
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
**    --mimetype MIMETYPE        mimetype of check-in comment
**    -n|--dry-run               If given, display instead of run actions
**    --no-warnings              omit all warnings about file contents
**    --nosign                   do not attempt to sign this commit with gpg
**    --private                  do not sync changes and their descendants
**    --sha1sum                  verify file status using SHA1 hashing rather
**                               than relying on file mtimes
**    --tag TAG-NAME             assign given tag TAG-NAME to the checkin
**
** See also: branch, changes, checkout, extras, sync
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */







|







1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
**    --mimetype MIMETYPE        mimetype of check-in comment
**    -n|--dry-run               If given, display instead of run actions
**    --no-warnings              omit all warnings about file contents
**    --nosign                   do not attempt to sign this commit with gpg
**    --private                  do not sync changes and their descendants
**    --sha1sum                  verify file status using SHA1 hashing rather
**                               than relying on file mtimes
**    --tag TAG-NAME             assign given tag TAG-NAME to the check-in
**
** See also: branch, changes, checkout, extras, sync
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
  }

  /*
  ** Do not allow a commit against a closed leaf unless the commit
  ** ends up on a different branch.
  */
  if(
      /* parent checkin has the "closed" tag... */
      db_exists("SELECT 1 FROM tagxref"
                " WHERE tagid=%d AND rid=%d AND tagtype>0",
                TAG_CLOSED, vid)
      /* ... and the new checkin has no --branch option or the --branch
      ** option does not actually change the branch */
   && (sCiInfo.zBranch==0
       || db_exists("SELECT 1 FROM tagxref"
                    " WHERE tagid=%d AND rid=%d AND tagtype>0"
                    "   AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
  ){
    fossil_fatal("cannot commit against a closed leaf");







|



|







1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
  }

  /*
  ** Do not allow a commit against a closed leaf unless the commit
  ** ends up on a different branch.
  */
  if(
      /* parent check-in has the "closed" tag... */
      db_exists("SELECT 1 FROM tagxref"
                " WHERE tagid=%d AND rid=%d AND tagtype>0",
                TAG_CLOSED, vid)
      /* ... and the new check-in has no --branch option or the --branch
      ** option does not actually change the branch */
   && (sCiInfo.zBranch==0
       || db_exists("SELECT 1 FROM tagxref"
                    " WHERE tagid=%d AND rid=%d AND tagtype>0"
                    "   AND value=%Q", TAG_BRANCH, vid, sCiInfo.zBranch))
  ){
    fossil_fatal("cannot commit against a closed leaf");
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
      pBaseline = pParent;
    }
    if( pBaseline ){
      Blob delta;
      create_manifest(&delta, zBaselineUuid, pBaseline, vid, &sCiInfo, &szD);
      /*
      ** At this point, two manifests have been constructed, either of
      ** which would work for this checkin.  The first manifest (held
      ** in the "manifest" variable) is a baseline manifest and the second
      ** (held in variable named "delta") is a delta manifest.  The
      ** question now is: which manifest should we use?
      **
      ** Let B be the number of F-cards in the baseline manifest and
      ** let D be the number of F-cards in the delta manifest, plus one for
      ** the B-card.  (B is held in the szB variable and D is held in the







|







1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
      pBaseline = pParent;
    }
    if( pBaseline ){
      Blob delta;
      create_manifest(&delta, zBaselineUuid, pBaseline, vid, &sCiInfo, &szD);
      /*
      ** At this point, two manifests have been constructed, either of
      ** which would work for this check-in.  The first manifest (held
      ** in the "manifest" variable) is a baseline manifest and the second
      ** (held in variable named "delta") is a delta manifest.  The
      ** question now is: which manifest should we use?
      **
      ** Let B be the number of F-cards in the baseline manifest and
      ** let D be the number of F-cards in the delta manifest, plus one for
      ** the B-card.  (B is held in the szB variable and D is held in the
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
    " 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
    ** of the manifest file).
    */
    vfile_aggregate_checksum_repository(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      vfile_compare_repository_to_disk(nvid);
      fossil_fatal("working checkout does not match what would have ended "
                   "up in the repository:  %b versus %b",







|







1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
    " 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 check-in started (and stored as the R record
    ** of the manifest file).
    */
    vfile_aggregate_checksum_repository(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      vfile_compare_repository_to_disk(nvid);
      fossil_fatal("working checkout does not match what would have ended "
                   "up in the repository:  %b versus %b",
Changes to src/db.c.
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
** their associated permissions will not be copied; however, the system
** default users "anonymous", "nobody", "reader", "developer", and their
** associated permissions will be copied.
**
** Options:
**    --template      FILE      copy settings from repository file
**    --admin-user|-A USERNAME  select given USERNAME as admin user
**    --date-override DATETIME  use DATETIME as time of the initial checkin
**                              (default: do not create an initial checkin)
**
** See also: clone
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */







|
|







1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
** their associated permissions will not be copied; however, the system
** default users "anonymous", "nobody", "reader", "developer", and their
** associated permissions will be copied.
**
** Options:
**    --template      FILE      copy settings from repository file
**    --admin-user|-A USERNAME  select given USERNAME as admin user
**    --date-override DATETIME  use DATETIME as time of the initial check-in
**                              (default: do not create an initial check-in)
**
** See also: clone
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */
Changes to src/descendants.c.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
** already exist.  Load this table with the RID of all
** check-ins that are leaves which are descended from
** check-in iBase.
**
** A "leaf" is a check-in that has no children in the same branch.
** There is a separate permanent table LEAF that contains all leaves
** in the tree.  This routine is used to compute a subset of that
** table consisting of leaves that are descended from a single checkin.
**
** The closeMode flag determines behavior associated with the "closed"
** tag:
**
**    closeMode==0       Show all leaves regardless of the "closed" tag.
**
**    closeMode==1       Show only leaves without the "closed" tag.







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
** already exist.  Load this table with the RID of all
** check-ins that are leaves which are descended from
** check-in iBase.
**
** A "leaf" is a check-in that has no children in the same branch.
** There is a separate permanent table LEAF that contains all leaves
** in the tree.  This routine is used to compute a subset of that
** table consisting of leaves that are descended from a single check-in.
**
** The closeMode flag determines behavior associated with the "closed"
** tag:
**
**    closeMode==0       Show all leaves regardless of the "closed" tag.
**
**    closeMode==1       Show only leaves without the "closed" tag.
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
}

/*
** COMMAND: descendants*
**
** Usage: %fossil descendants ?CHECKIN? ?OPTIONS?
**
** Find all leaf descendants of the checkin specified or if the argument
** is omitted, of the checkin currently checked out.
**
** Options:
**    -R|--repository FILE       Extract info from repository FILE
**    -W|--width <num>           Width of lines (default is to auto-detect).
**                               Must be >20 or 0 (= no limit, resulting in a
**                               single line per entry).
**







|
|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
}

/*
** COMMAND: descendants*
**
** Usage: %fossil descendants ?CHECKIN? ?OPTIONS?
**
** Find all leaf descendants of the check-in specified or if the argument
** is omitted, of the check-in currently checked out.
**
** Options:
**    -R|--repository FILE       Extract info from repository FILE
**    -W|--width <num>           Width of lines (default is to auto-detect).
**                               Must be >20 or 0 (= no limit, resulting in a
**                               single line per entry).
**
Changes to src/diff.c.
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
** COMMAND: praise
**
** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
**
** Output the text of a file with markings to show when each line of
** the file was last modified.  The "annotate" command shows line numbers
** and omits the username.  The "blame" and "praise" commands show the user
** who made each checkin and omits the line number.
**
** Options:
**   --filevers                 Show file version numbers rather than check-in versions
**   -l|--log                   List all versions analyzed
**   -n|--limit N               Only look backwards in time by N versions
**   -w|--ignore-all-space      Ignore white space when comparing lines
**   -Z|--ignore-trailing-space Ignore whitespace at line end







|







2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
** COMMAND: praise
**
** %fossil (annotate|blame|praise) ?OPTIONS? FILENAME
**
** Output the text of a file with markings to show when each line of
** the file was last modified.  The "annotate" command shows line numbers
** and omits the username.  The "blame" and "praise" commands show the user
** who made each check-in and omits the line number.
**
** Options:
**   --filevers                 Show file version numbers rather than check-in versions
**   -l|--log                   List all versions analyzed
**   -n|--limit N               Only look backwards in time by N versions
**   -w|--ignore-all-space      Ignore white space when comparing lines
**   -Z|--ignore-trailing-space Ignore whitespace at line end
Changes to src/doc.c.
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
      if( seenClass ) return 1;
    }
  }
  return seenClass;
}

/*
** Look for a file named zName in the checkin with RID=vid.  Load the content
** of that file into pContent and return the RID for the file.  Or return 0
** if the file is not found or could not be loaded.
*/
int doc_load_content(int vid, const char *zName, Blob *pContent){
  int rid;   /* The RID of the file being loaded */
  if( !db_table_exists("repository","vcache") ){
    db_multi_exec(
      "CREATE TABLE IF NOT EXISTS vcache(\n"
      "  vid INTEGER,         -- checkin ID\n"
      "  fname TEXT,          -- filename\n"
      "  rid INTEGER,         -- artifact ID\n"
      "  PRIMARY KEY(vid,fname)\n"
      ") WITHOUT ROWID"
    );
  }
  if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){







|








|







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
      if( seenClass ) return 1;
    }
  }
  return seenClass;
}

/*
** Look for a file named zName in the check-in with RID=vid.  Load the content
** of that file into pContent and return the RID for the file.  Or return 0
** if the file is not found or could not be loaded.
*/
int doc_load_content(int vid, const char *zName, Blob *pContent){
  int rid;   /* The RID of the file being loaded */
  if( !db_table_exists("repository","vcache") ){
    db_multi_exec(
      "CREATE TABLE IF NOT EXISTS vcache(\n"
      "  vid INTEGER,         -- check-in ID\n"
      "  fname TEXT,          -- filename\n"
      "  rid INTEGER,         -- artifact ID\n"
      "  PRIMARY KEY(vid,fname)\n"
      ") WITHOUT ROWID"
    );
  }
  if( !db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
** then FILE is completely replaced by "404.md" and tried.  If that is
** not found, then a default 404 screen is generated.
*/
void doc_page(void){
  const char *zName;                /* Argument to the /doc page */
  const char *zOrigName = "?";      /* Original document name */
  const char *zMime;                /* Document MIME type */
  char *zCheckin = "tip";           /* The checkin holding the document */
  int vid = 0;                      /* Artifact of checkin */
  int rid = 0;                      /* Artifact of file */
  int i;                            /* Loop counter */
  Blob filebody;                    /* Content of the documentation file */
  Blob title;                       /* Document title */
  int nMiss = (-1);                 /* Failed attempts to find the document */
  static const char *const azSuffix[] = {
     "index.html", "index.wiki", "index.md"







|
|







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
** then FILE is completely replaced by "404.md" and tried.  If that is
** not found, then a default 404 screen is generated.
*/
void doc_page(void){
  const char *zName;                /* Argument to the /doc page */
  const char *zOrigName = "?";      /* Original document name */
  const char *zMime;                /* Document MIME type */
  char *zCheckin = "tip";           /* The check-in holding the document */
  int vid = 0;                      /* Artifact of check-in */
  int rid = 0;                      /* Artifact of file */
  int i;                            /* Loop counter */
  Blob filebody;                    /* Content of the documentation file */
  Blob title;                       /* Document title */
  int nMiss = (-1);                 /* Failed attempts to find the document */
  static const char *const azSuffix[] = {
     "index.html", "index.wiki", "index.md"
Changes to src/foci.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This routine implements an SQLite virtual table that gives all of the
** files associated with a single checkin.
**
** The filename "foci" is short for "Files Of CheckIn".
**
** Usage example:
**
**    CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;
**                      -- ^^^^--- important!
**    SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk');
**
** The symbolic_name_to_rid('trunk') function finds the BLOB.RID value 
** corresponding to the 'trunk' tag.  Then the files_of_checkin virtual table
** decodes the manifest defined by that BLOB and returns all files described
** by that manifest.  The "schema" for the temp.foci table is:
**
**     CREATE TABLE files_of_checkin(
**       checkinID    INTEGER,    -- RID for the checkin manifest
**       filename     TEXT,       -- Name of a file
**       uuid         TEXT,       -- SHA1 hash of the file
**       previousName TEXT,       -- Name of the file in previous checkin
**       perm         TEXT        -- Permissions on the file
**     );
**
*/
#include "config.h"
#include "foci.h"
#include <assert.h>

/*
** The schema for the virtual table:
*/
static const char zFociSchema[] =
@ CREATE TABLE files_of_checkin(
@  checkinID    INTEGER,    -- RID for the checkin manifest
@  filename     TEXT,       -- Name of a file
@  uuid         TEXT,       -- SHA1 hash of the file
@  previousName TEXT,       -- Name of the file in previous checkin
@  perm         TEXT        -- Permissions on the file
@ );
;

#if INTERFACE
/*
** The subclasses of sqlite3_vtab  and sqlite3_vtab_cursor tables







|















|


|













|


|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This routine implements an SQLite virtual table that gives all of the
** files associated with a single check-in.
**
** The filename "foci" is short for "Files Of CheckIn".
**
** Usage example:
**
**    CREATE VIRTUAL TABLE temp.foci USING files_of_checkin;
**                      -- ^^^^--- important!
**    SELECT * FROM foci WHERE checkinID=symbolic_name_to_rid('trunk');
**
** The symbolic_name_to_rid('trunk') function finds the BLOB.RID value 
** corresponding to the 'trunk' tag.  Then the files_of_checkin virtual table
** decodes the manifest defined by that BLOB and returns all files described
** by that manifest.  The "schema" for the temp.foci table is:
**
**     CREATE TABLE files_of_checkin(
**       checkinID    INTEGER,    -- RID for the check-in manifest
**       filename     TEXT,       -- Name of a file
**       uuid         TEXT,       -- SHA1 hash of the file
**       previousName TEXT,       -- Name of the file in previous check-in
**       perm         TEXT        -- Permissions on the file
**     );
**
*/
#include "config.h"
#include "foci.h"
#include <assert.h>

/*
** The schema for the virtual table:
*/
static const char zFociSchema[] =
@ CREATE TABLE files_of_checkin(
@  checkinID    INTEGER,    -- RID for the check-in manifest
@  filename     TEXT,       -- Name of a file
@  uuid         TEXT,       -- SHA1 hash of the file
@  previousName TEXT,       -- Name of the file in previous check-in
@  perm         TEXT        -- Permissions on the file
@ );
;

#if INTERFACE
/*
** The subclasses of sqlite3_vtab  and sqlite3_vtab_cursor tables
Changes to src/fusefs.c.
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
**
** This command uses the Fuse Filesystem to mount a directory at
** DIRECTORY that contains the content of all check-ins in the
** repository.  The names of files are DIRECTORY/checkins/VERSION/PATH
** where DIRECTORY is the root of the mount, VERSION is any valid
** check-in name (examples: "trunk" or "tip" or a tag or any unique
** prefix of a SHA1 hash, etc) and PATH is the pathname of the file
** in the checkin.  If DIRECTORY does not exist, then an attempt is
** made to create it.
**
** The DIRECTORY/checkins directory is not searchable so one cannot
** do "ls DIRECTORY/checkins" to get a listing of all possible checkin
** names.  There are countless variations on checkin names and it is
** impractical to list them all.  But all other directories are searchable
** and so the "ls" command will work everywhere else in the fusefs
** file hierarchy.
**
** The FuseFS typically only works on Linux, and then only on Linux
** systems that have the right kernel drivers and have install the
** appropriate support libraries.







|



|
|







293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
**
** This command uses the Fuse Filesystem to mount a directory at
** DIRECTORY that contains the content of all check-ins in the
** repository.  The names of files are DIRECTORY/checkins/VERSION/PATH
** where DIRECTORY is the root of the mount, VERSION is any valid
** check-in name (examples: "trunk" or "tip" or a tag or any unique
** prefix of a SHA1 hash, etc) and PATH is the pathname of the file
** in the check-in.  If DIRECTORY does not exist, then an attempt is
** made to create it.
**
** The DIRECTORY/checkins directory is not searchable so one cannot
** do "ls DIRECTORY/checkins" to get a listing of all possible check-in
** names.  There are countless variations on check-in names and it is
** impractical to list them all.  But all other directories are searchable
** and so the "ls" command will work everywhere else in the fusefs
** file hierarchy.
**
** The FuseFS typically only works on Linux, and then only on Linux
** systems that have the right kernel drivers and have install the
** appropriate support libraries.
Changes to src/graph.c.
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  }
  p->mxRail = -1;

  /* Purge merge-parents that are out-of-graph if descenders are not
  ** drawn.
  **
  ** Each node has one primary parent and zero or more "merge" parents.
  ** A merge parent is a prior checkin from which changes were merged into
  ** the current check-in.  If a merge parent is not in the visible section
  ** of this graph, then no arrows will be drawn for it, so remove it from
  ** the aParent[] array.
  */
  if( omitDescenders ){
    for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
      for(i=1; i<pRow->nParent; i++){







|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  }
  p->mxRail = -1;

  /* Purge merge-parents that are out-of-graph if descenders are not
  ** drawn.
  **
  ** Each node has one primary parent and zero or more "merge" parents.
  ** A merge parent is a prior check-in from which changes were merged into
  ** the current check-in.  If a merge parent is not in the visible section
  ** of this graph, then no arrows will be drawn for it, so remove it from
  ** the aParent[] array.
  */
  if( omitDescenders ){
    for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
      for(i=1; i<pRow->nParent; i++){
Changes to src/import.c.
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
    ** The XMARK table provides a mapping from fast-import "marks" and symbols
    ** into artifact ids (UUIDs - the 40-byte hex SHA1 hash of artifacts).
    ** Given any valid fast-import symbol, the corresponding fossil rid and
    ** uuid can found by searching against the xmark.tname field.
    **
    ** The XBRANCH table maps commit marks and symbols into the branch those
    ** commits belong to.  If xbranch.tname is a fast-import symbol for a
    ** checkin then xbranch.brnm is the branch that checkin is part of.
    **
    ** The XTAG table records information about tags that need to be applied
    ** to various branches after the import finishes.  The xtag.tcontent field
    ** contains the text of an artifact that will add a tag to a check-in.
    ** The git-fast-export file format might specify the same tag multiple
    ** times but only the last tag should be used.  And we do not know which
    ** occurrence of the tag is the last until the import finishes.







|







780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
    ** The XMARK table provides a mapping from fast-import "marks" and symbols
    ** into artifact ids (UUIDs - the 40-byte hex SHA1 hash of artifacts).
    ** Given any valid fast-import symbol, the corresponding fossil rid and
    ** uuid can found by searching against the xmark.tname field.
    **
    ** The XBRANCH table maps commit marks and symbols into the branch those
    ** commits belong to.  If xbranch.tname is a fast-import symbol for a
    ** check-in then xbranch.brnm is the branch that check-in is part of.
    **
    ** The XTAG table records information about tags that need to be applied
    ** to various branches after the import finishes.  The xtag.tcontent field
    ** contains the text of an artifact that will add a tag to a check-in.
    ** The git-fast-export file format might specify the same tag multiple
    ** times but only the last tag should be used.  And we do not know which
    ** occurrence of the tag is the last until the import finishes.
Changes to src/info.c.
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
void ci_page(void){
  Stmt q1, q2, q3;
  int rid;
  int isLeaf;
  int verboseFlag;     /* True to show diffs */
  int sideBySide;      /* True for side-by-side diffs */
  u64 diffFlags;       /* Flag parameter for text_diff() */
  const char *zName;   /* Name of the checkin to be displayed */
  const char *zUuid;   /* UUID of zName */
  const char *zParent; /* UUID of the parent checkin (if any) */
  const char *zRe;     /* regex parameter */
  ReCompiled *pRe = 0; /* regex */
  const char *zW;      /* URL param for ignoring whitespace */
  const char *zPage = "vinfo";  /* Page that shows diffs */
  const char *zPageHide = "ci"; /* Page that hides diffs */

  login_check_credentials();







|

|







515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
void ci_page(void){
  Stmt q1, q2, q3;
  int rid;
  int isLeaf;
  int verboseFlag;     /* True to show diffs */
  int sideBySide;      /* True for side-by-side diffs */
  u64 diffFlags;       /* Flag parameter for text_diff() */
  const char *zName;   /* Name of the check-in to be displayed */
  const char *zUuid;   /* UUID of zName */
  const char *zParent; /* UUID of the parent check-in (if any) */
  const char *zRe;     /* regex parameter */
  ReCompiled *pRe = 0; /* regex */
  const char *zW;      /* URL param for ignoring whitespace */
  const char *zPage = "vinfo";  /* Page that shows diffs */
  const char *zPageHide = "ci"; /* Page that hides diffs */

  login_check_credentials();
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  style_header("URL Error");
  @ <h1>Error</h1>
  @ <p>%h(z)</p>
  style_footer();
}

/*
** Find an checkin based on query parameter zParam and parse its
** manifest.  Return the number of errors.
*/
static Manifest *vdiff_parse_manifest(const char *zParam, int *pRid){
  int rid;

  *pRid = rid = name_to_rid_www(zParam);
  if( rid==0 ){
    const char *z = P(zParam);
    if( z==0 || z[0]==0 ){
      webpage_error("Missing \"%s\" query parameter.", zParam);
    }else{
      webpage_error("No such artifact: \"%s\"", z);
    }
    return 0;
  }
  if( !is_a_version(rid) ){
    webpage_error("Artifact %s is not a checkin.", P(zParam));
    return 0;
  }
  return manifest_get(rid, CFTYPE_MANIFEST, 0);
}

/*
** Output a description of a check-in







|
















|







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  style_header("URL Error");
  @ <h1>Error</h1>
  @ <p>%h(z)</p>
  style_footer();
}

/*
** Find an check-in based on query parameter zParam and parse its
** manifest.  Return the number of errors.
*/
static Manifest *vdiff_parse_manifest(const char *zParam, int *pRid){
  int rid;

  *pRid = rid = name_to_rid_www(zParam);
  if( rid==0 ){
    const char *z = P(zParam);
    if( z==0 || z[0]==0 ){
      webpage_error("Missing \"%s\" query parameter.", zParam);
    }else{
      webpage_error("No such artifact: \"%s\"", z);
    }
    return 0;
  }
  if( !is_a_version(rid) ){
    webpage_error("Artifact %s is not a check-in.", P(zParam));
    return 0;
  }
  return manifest_get(rid, CFTYPE_MANIFEST, 0);
}

/*
** Output a description of a check-in
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
  @ <blockquote><pre>
  hexdump(&content);
  @ </pre></blockquote>
  style_footer();
}

/*
** Attempt to lookup the specified checkin and file name into an rid.
*/
int artifact_from_ci_and_filename(
  const char *zCI,
  const char *zFilename
){
  int cirid;
  Manifest *pManifest;







|







1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
  @ <blockquote><pre>
  hexdump(&content);
  @ </pre></blockquote>
  style_footer();
}

/*
** Attempt to lookup the specified check-in and file name into an rid.
*/
int artifact_from_ci_and_filename(
  const char *zCI,
  const char *zFilename
){
  int cirid;
  Manifest *pManifest;
Changes to src/leaf.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to manage the "leaf" table of the
** repository.
**
** The LEAF table contains the rids for all leaves in the checkin DAG.
** A leaf is a checkin that has no children in the same branch.
*/
#include "config.h"
#include "leaf.h"
#include <assert.h>


/*







|
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to manage the "leaf" table of the
** repository.
**
** The LEAF table contains the rids for all leaves in the check-in DAG.
** A leaf is a check-in that has no children in the same branch.
*/
#include "config.h"
#include "leaf.h"
#include <assert.h>


/*
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

/*
** A bag of checkins whose leaf status needs to be checked.
*/
static Bag needToCheck;

/*
** Check to see if checkin "rid" is a leaf and either add it to the LEAF
** table if it is, or remove it if it is not.
*/
void leaf_check(int rid){
  static Stmt checkIfLeaf;
  static Stmt addLeaf;
  static Stmt removeLeaf;
  int rc;







|







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

/*
** A bag of checkins whose leaf status needs to be checked.
*/
static Bag needToCheck;

/*
** Check to see if check-in "rid" is a leaf and either add it to the LEAF
** table if it is, or remove it if it is not.
*/
void leaf_check(int rid){
  static Stmt checkIfLeaf;
  static Stmt addLeaf;
  static Stmt removeLeaf;
  int rc;
Changes to src/manifest.c.
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

      /*
      **     P <uuid> ...
      **
      ** Specify one or more other artifacts which are the parents of
      ** this artifact.  The first parent is the primary parent.  All
      ** others are parents by merge. Note that the initial empty
      ** checkin historically has an empty P-card, so empty P-cards
      ** must be accepted.
      */
      case 'P': {
        while( (zUuid = next_token(&x, &sz))!=0 ){
          if( sz!=UUID_SIZE ) SYNTAX("wrong size UUID on P-card");
          if( !validate16(zUuid, UUID_SIZE) )SYNTAX("invalid UUID on P-card");
          if( p->nParent>=p->nParentAlloc ){







|







676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

      /*
      **     P <uuid> ...
      **
      ** Specify one or more other artifacts which are the parents of
      ** this artifact.  The first parent is the primary parent.  All
      ** others are parents by merge. Note that the initial empty
      ** check-in historically has an empty P-card, so empty P-cards
      ** must be accepted.
      */
      case 'P': {
        while( (zUuid = next_token(&x, &sz))!=0 ){
          if( sz!=UUID_SIZE ) SYNTAX("wrong size UUID on P-card");
          if( !validate16(zUuid, UUID_SIZE) )SYNTAX("invalid UUID on P-card");
          if( p->nParent>=p->nParentAlloc ){
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
        break;
      }

      /*
      **     Q (+|-)<uuid> ?<uuid>?
      **
      ** Specify one or a range of checkins that are cherrypicked into
      ** this checkin ("+") or backed out of this checkin ("-").
      */
      case 'Q': {
        if( (zUuid=next_token(&x, &sz))==0 ) SYNTAX("missing UUID on Q-card");
        if( sz!=UUID_SIZE+1 ) SYNTAX("wrong size UUID on Q-card");
        if( zUuid[0]!='+' && zUuid[0]!='-' ){
          SYNTAX("Q-card does not begin with '+' or '-'");
        }







|







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
        break;
      }

      /*
      **     Q (+|-)<uuid> ?<uuid>?
      **
      ** Specify one or a range of checkins that are cherrypicked into
      ** this check-in ("+") or backed out of this check-in ("-").
      */
      case 'Q': {
        if( (zUuid=next_token(&x, &sz))==0 ) SYNTAX("missing UUID on Q-card");
        if( sz!=UUID_SIZE+1 ) SYNTAX("wrong size UUID on Q-card");
        if( zUuid[0]!='+' && zUuid[0]!='-' ){
          SYNTAX("Q-card does not begin with '+' or '-'");
        }
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    manifest_destroy(p);
    p = 0;
  }
  return p;
}

/*
** Given a checkin name, load and parse the manifest for that checkin.
** Throw a fatal error if anything goes wrong.
*/
Manifest *manifest_get_by_name(const char *zName, int *pRid){
  int rid;
  Manifest *p;

  rid = name_to_typed_rid(zName, "ci");
  if( !is_a_version(rid) ){
    fossil_fatal("no such checkin: %s", zName);
  }
  if( pRid ) *pRid = rid;
  p = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( p==0 ){
    fossil_fatal("cannot parse manifest for checkin: %s", zName);
  }
  return p;
}

/*
** COMMAND: test-parse-manifest
**







|








|




|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
    manifest_destroy(p);
    p = 0;
  }
  return p;
}

/*
** Given a check-in name, load and parse the manifest for that check-in.
** Throw a fatal error if anything goes wrong.
*/
Manifest *manifest_get_by_name(const char *zName, int *pRid){
  int rid;
  Manifest *p;

  rid = name_to_typed_rid(zName, "ci");
  if( !is_a_version(rid) ){
    fossil_fatal("no such check-in: %s", zName);
  }
  if( pRid ) *pRid = rid;
  p = manifest_get(rid, CFTYPE_MANIFEST, 0);
  if( p==0 ){
    fossil_fatal("cannot parse manifest for check-in: %s", zName);
  }
  return p;
}

/*
** COMMAND: test-parse-manifest
**
Changes to src/path.c.
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  int origName;        /* Original name of file */
  int curName;         /* Current name of the file */
  int newName;         /* Name of file in next version */
  NameChange *pNext;   /* List of all name changes */
};

/*
** Compute all file name changes that occur going from checkin iFrom
** to checkin iTo.
**
** The number of name changes is written into *pnChng.  For each name
** change, two integers are allocated for *piChng.  The first is the
** filename.fnid for the original name as seen in check-in iFrom and
** the second is for new name as it is used in check-in iTo.
**
** Space to hold *piChng is obtained from fossil_malloc() and should







|
|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  int origName;        /* Original name of file */
  int curName;         /* Current name of the file */
  int newName;         /* Name of file in next version */
  NameChange *pNext;   /* List of all name changes */
};

/*
** Compute all file name changes that occur going from check-in iFrom
** to check-in iTo.
**
** The number of name changes is written into *pnChng.  For each name
** change, two integers are allocated for *piChng.  The first is the
** filename.fnid for the original name as seen in check-in iFrom and
** the second is for new name as it is used in check-in iTo.
**
** Space to hold *piChng is obtained from fossil_malloc() and should
Changes to src/publish.c.
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
** Usage: %fossil publish ?--only? TAGS...
**
** Cause artifacts identified by TAGS... to be published (made non-private).
** This can be used (for example) to convert a private branch into a public
** branch, or to publish a bundle that was imported privately.
**
** If any of TAGS names a branch, then all checkins on the most recent
** instance of that branch are included, not just the most recent checkin.
**
** If any of TAGS name checkins then all files and tags associated with
** those checkins are also published automatically.  Except if the --only
** option is used, then only the specific artifacts identified by TAGS
** are published.
**
** If a TAG is already public, this command is a harmless no-op.







|







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
** Usage: %fossil publish ?--only? TAGS...
**
** Cause artifacts identified by TAGS... to be published (made non-private).
** This can be used (for example) to convert a private branch into a public
** branch, or to publish a bundle that was imported privately.
**
** If any of TAGS names a branch, then all checkins on the most recent
** instance of that branch are included, not just the most recent check-in.
**
** If any of TAGS name checkins then all files and tags associated with
** those checkins are also published automatically.  Except if the --only
** option is used, then only the specific artifacts identified by TAGS
** are published.
**
** If a TAG is already public, this command is a harmless no-op.
Changes to src/purge.c.
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  db_end_transaction(0);
  return peid;
}

/*
** The TEMP table named zTab contains RIDs for a set of checkins.  
**
** Check to see if any checkin in zTab is a baseline manifest for some
** delta manifest that is not in zTab.  Return true if zTab contains a
** baseline for a delta that is not in zTab.
**
** This is a database integrity preservation check.  The checkins in zTab
** are about to be deleted or otherwise made inaccessible.  This routine
** is checking to ensure that purging the checkins in zTab will not delete
** a baseline manifest out from under a delta.







|







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
  db_end_transaction(0);
  return peid;
}

/*
** The TEMP table named zTab contains RIDs for a set of checkins.  
**
** Check to see if any check-in in zTab is a baseline manifest for some
** delta manifest that is not in zTab.  Return true if zTab contains a
** baseline for a delta that is not in zTab.
**
** This is a database integrity preservation check.  The checkins in zTab
** are about to be deleted or otherwise made inaccessible.  This routine
** is checking to ensure that purging the checkins in zTab will not delete
** a baseline manifest out from under a delta.
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
      "SELECT 1 FROM plink WHERE baseid IN \"%w\" AND cid NOT IN \"%w\"",
      zTab, zTab);
  }
}


/*
** The TEMP table named zTab contains the RIDs for a set of checkin
** artifacts.  Expand this set (by adding new entries to zTab) to include
** all other artifacts that are used the set of checkins in
** the original list.
**
** If the bExclusive flag is true, then the set is only expanded by
** artifacts that are used exclusively by the checkins in the set.
** When bExclusive is false, then all artifacts used by the checkins







|







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
      "SELECT 1 FROM plink WHERE baseid IN \"%w\" AND cid NOT IN \"%w\"",
      zTab, zTab);
  }
}


/*
** The TEMP table named zTab contains the RIDs for a set of check-in
** artifacts.  Expand this set (by adding new entries to zTab) to include
** all other artifacts that are used the set of checkins in
** the original list.
**
** If the bExclusive flag is true, then the set is only expanded by
** artifacts that are used exclusively by the checkins in the set.
** When bExclusive is false, then all artifacts used by the checkins
Changes to src/search.c.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement a very simple search function
** against timeline comments, checkin content, wiki pages, and/or tickets.
**
** The search is full-text like in that it is looking for words and ignores
** punctuation and capitalization.  But it is more akin to "grep" in that
** it scans the entire corpus for the search, and it does not support the
** full functionality of FTS4.
*/
#include "config.h"







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement a very simple search function
** against timeline comments, check-in content, wiki pages, and/or tickets.
**
** The search is full-text like in that it is looking for words and ignores
** punctuation and capitalization.  But it is more akin to "grep" in that
** it scans the entire corpus for the search, and it does not support the
** full functionality of FTS4.
*/
#include "config.h"
Changes to src/tar.c.
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
    blob_reset(&file);
  }
  tar_finish(&zip);
  blob_write_to_file(&zip, g.argv[2]);
}

/*
** Given the RID for a checkin, construct a tarball containing
** all files in that checkin
**
** If RID is for an object that is not a real manifest, then the
** resulting tarball contains a single file which is the RID
** object.
**
** If the RID object does not exist in the repository, then
** pTar is zeroed.







|
|







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
    blob_reset(&file);
  }
  tar_finish(&zip);
  blob_write_to_file(&zip, g.argv[2]);
}

/*
** Given the RID for a check-in, construct a tarball containing
** all files in that check-in
**
** If RID is for an object that is not a real manifest, then the
** resulting tarball contains a single file which is the RID
** object.
**
** If the RID object does not exist in the repository, then
** pTar is zeroed.
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
  verify_all_options();

  if( g.argc!=4 ){
    usage("VERSION OUTPUTFILE");
  }
  rid = name_to_typed_rid(g.argv[2], "ci");
  if( rid==0 ){
    fossil_fatal("Checkin not found: %s", g.argv[2]);
    return;
  }

  if( zName==0 ){
    zName = db_text("default-name",
       "SELECT replace(%Q,' ','_') "
          " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "







|







556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
  verify_all_options();

  if( g.argc!=4 ){
    usage("VERSION OUTPUTFILE");
  }
  rid = name_to_typed_rid(g.argv[2], "ci");
  if( rid==0 ){
    fossil_fatal("Check-in not found: %s", g.argv[2]);
    return;
  }

  if( zName==0 ){
    zName = db_text("default-name",
       "SELECT replace(%Q,' ','_') "
          " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  blob_reset(&tarball);
}

/*
** WEBPAGE: tarball
** URL: /tarball/RID.tar.gz
**
** Generate a compressed tarball for a checkin.
** Return that tarball as the HTTP reply content.
**
** Optional URL Parameters:
**
** - name=NAME[.tar.gz] is base name of the output file. Defaults to
** something project/version-specific. The prefix of the name, up to
** the last '.', are used as the top-most directory name in the tar







|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
  blob_reset(&tarball);
}

/*
** WEBPAGE: tarball
** URL: /tarball/RID.tar.gz
**
** Generate a compressed tarball for a check-in.
** Return that tarball as the HTTP reply content.
**
** Optional URL Parameters:
**
** - name=NAME[.tar.gz] is base name of the output file. Defaults to
** something project/version-specific. The prefix of the name, up to
** the last '.', are used as the top-most directory name in the tar
Changes to src/th_main.c.
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  }else if( rid==0 ){
    Th_SetResult(interp, "name not found", -1);
  }
  return rid;
}

/*
** Attempt to lookup the specified checkin and file name into an rid.
** This function was copied from artifact_from_ci_and_filename() in
** info.c; however, it has been modified to report TH1 script errors
** instead of "fatal errors".
*/
int th1_artifact_from_ci_and_filename(
  Th_Interp *interp,
  const char *zCI,







|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  }else if( rid==0 ){
    Th_SetResult(interp, "name not found", -1);
  }
  return rid;
}

/*
** Attempt to lookup the specified check-in and file name into an rid.
** This function was copied from artifact_from_ci_and_filename() in
** info.c; however, it has been modified to report TH1 script errors
** instead of "fatal errors".
*/
int th1_artifact_from_ci_and_filename(
  Th_Interp *interp,
  const char *zCI,