Fossil

Check-in [c2b1bc68]
Login

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

Overview
Comment:merged trunk [1f498a6ef2].
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: c2b1bc686d9d3e70c6a0cca24cc1850fedc5e29d
User & Date: stephan 2011-09-20 16:48:26.048
Context
2011-09-20
16:58
fossil_warning() is now a no-op in JSON mode, to avoid corrupting the output. ... (check-in: 6ce6b5e6 user: stephan tags: json)
16:48
merged trunk [1f498a6ef2]. ... (check-in: c2b1bc68 user: stephan tags: json)
16:45
more minor internal cleanups. s/g.isCGI/g.isHTTP/ to avoid confusion later on. ... (check-in: 9adc95c4 user: stephan tags: json)
2011-09-19
20:16
Remove obsolete files ... (check-in: 1f498a6e user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Deleted ci_cvs.txt.
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
===============================================================================

First experimental codes ...

tools/import-cvs.tcl
tools/lib/rcsparser.tcl

No actual import, right now only working on getting csets right. The
code uses CVSROOT/history as foundation, and augments that with data
from the individual RCS files (commit messages).

Statistics of a run ...
	3516 csets.

	1545 breaks on user change
	 558 breaks on file duplicate
	  13 breaks on branch/trunk change
	1402 breaks on commit message change

Time statistics ...
	3297 were processed in <= 1 seconds (93.77%)
	 217 were processed in between 2 seconds and 14 minutes.
	   1 was  processed in ~41 minutes
	   1 was  processed in ~22 hours

Time fuzz - Differences between csets range from 0 seconds to 66
days. Needs stats analysis to see if there is an obvious break. Even
so the times within csets and between csets overlap a great deal,
making time a bad criterium for cset separation, IMHO.

Leaving that topic, back to the current cset separator ...

It has a problem:
	The history file is not starting at the root!

Examples:
	The first three changesets are

	=============================/user
	M {Wed Nov 22 09:28:49 AM PST 2000} ericm 1.4 tcllib/modules/ftpd/ChangeLog
	M {Wed Nov 22 09:28:49 AM PST 2000} ericm 1.7 tcllib/modules/ftpd/ftpd.tcl
	files: 2
	delta: 0
	range: 0 seconds
	=============================/cmsg
	M {Wed Nov 29 02:14:33 PM PST 2000} ericm 1.3 tcllib/aclocal.m4
	files: 1
	delta: 
	range: 0 seconds
	=============================/cmsg
	M {Sun Feb 04 12:28:35 AM PST 2001} ericm 1.9 tcllib/modules/mime/ChangeLog
	M {Sun Feb 04 12:28:35 AM PST 2001} ericm 1.12 tcllib/modules/mime/mime.tcl
	files: 2
	delta: 0
	range: 0 seconds

All csets modify files which already have several revisions. We have
no csets from before that in the history, but these csets are in the
RCS files.

I wonder, is SF maybe removing old entries from the history when it
grows too large ?

This also affects incremental import ... I cannot assume that the
history always grows. It may shrink ... I cannot keep an offset, will
have to record the time of the last entry, or even the full entry
processed last, to allow me to skip ahead to anything not known yet.

I might have to try to implement the algorithm outlined below,
matching the revision trees of the individual RCS files to each other
to form the global tree of revisions. Maybe we can use the history to
help in the matchup, for the parts where we do have it.

Wait. This might be easier ... Take the delta information from the RCS
files and generate a fake history ... Actually, this might even allow
us to create a total history ... No, not quite, the merge entries the
actual history may contain will be missing. These we can mix in from
the actual history, as much as we have.

Still, lets try that, a fake history, and then run this script on it
to see if/where are differences.

===============================================================================


Notes about CVS import, regarding CVS.

- Problem: CVS does not really track changesets, but only individual
  revisions of files. To recover changesets it is necessary to look at
  author, branch, timestamp information, and the commit messages. Even
  so this is only heuristic, not foolproof.

  Existing tool: cvsps.

  Processes the output of 'cvs log' to recover changesets. Problem:
  Sees only a linear list of revisions, does not see branchpoints,
  etc. Cannot use the tree structure to help in making the decisions.

- Problem: CVS does not track merge-points at all. Recovery through
  heuristics is brittle at best, looking for keywords in commit
  messages which might indicate that a branch was merged with some
  other.


Ideas regarding an algorithm to recover changesets.

Key feature: Uses the per-file revision trees to help in uncovering
the underlying changesets and global revision tree G.

The per-file revision tree for a file X is in essence the global
revision tree with all nodes not pertaining to X removed from it. In
the reverse this allows us to built up the global revision tree from
the per-file trees by matching nodes to each other and extending.

Start with the per file revision tree of a single file as initial
approximation of the global tree. All nodes of this tree refer to the
revision of the file belonging to it, and through that the file
itself. At each step the global tree contains the nodes for a finite
set of files, and all nodes in the tree refer to revisions of all
files in the set, making the mapping total.

To add a file X to the tree take the per-file revision tree R and
performs the following actions:

- For each node N in R use the tuple <author, branch, commit message>
  to identify a set of nodes in G which may match N. Use the timestamp
  to locate the node nearest in time.

- This process will leave nodes in N unmapped. If there are unmapped
  nodes which have no neighbouring mapped nodes we have to
  abort.

  Otherwise take the nodes which have mapped neighbours. Trace the
  edges and see which of these nodes are connected in the local
  tree. Then look at the identified neighbours and trace their
  connections.

  If two global nodes have a direct connection, but a multi-edge
  connection in the local tree insert global nodes mapping to the
  local nodes and map them together. This expands the global tree to
  hold the revisions added by the new file.

  Otherwise, both sides have multi-edge connections then abort. This
  looks like a merge of two different branches, but there are no such
  in CVS ... Wait ... sort the nodes over time and fit the new nodes
  in between the other nodes, per the timestamps. We have overlapping
  / alternating changes to one file and others.

  A last possibility is that a node is only connected to a mapped
  parent. This may be a new branch, or again an alternating change on
  the given line. Symbols on the revisions will help to map this.

- We now have an extended global tree which incorporates the revisions
  of the new file. However new nodes will refer only to the new file,
  and old nodes may not refer to the new file. This has to be fixed,
  as all nodes have to refer to all files.

  Run over the tree and look at each parent/child pair. If a file is
  not referenced in the child, but the parent, then copy a reference
  to the file revision on the parent forward to the child. This
  signals that the file did not change in the given revision.

- After all files have been integrated in this manner we have global
  revision tree capturing all changesets, including the unchanged
  files per changeset.


This algorithm has to be refined to also take Attic/ files into
account.

-------------------------------------------------------------------------

Two archive files mapping to the same user file. How are they
interleaved ?

(a)	sqlite/src/os_unix.h,v
(b)	sqlite/src/Attic/os_unix.h,v

Problem: Max version of (a) is 1.9
	 Max version of (b) is 1.11
	 cvs co 1.10 -> no longer in the repository.

This seems to indicate that the non-Attic file is relevant.

--------------------------------------------------------------------------

tcllib - more problems - tklib/pie.tcl,v -

invalid change text in
/home/aku/Projects/Tcl/Fossil/Devel/Examples/cvs-tcllib/tklib/modules/tkpiechart/pie.tcl,v

Possibly braces ?
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































Deleted ci_fossil.txt.
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

To perform CVS imports for fossil we need at least the ability to
parse CVS files, i.e. RCS files, with slight differences.

For the general architecture of the import facility we have two major
paths to choose between.

One is to use an external tool which processes a cvs repository and
drives fossil through its CLI to insert the found changesets.

The other is to integrate the whole facility into the fossil binary
itself.

I dislike the second choice. It may be faster, as the implementation
can use all internal functionality of fossil to perform the import,
however it will also bloat the binary with functionality not needed
most of the time. Which becomes especially obvious if more importers
are to be written, like for monotone, bazaar, mercurial, bitkeeper,
git, SVN, Arc, etc. Keeping all this out of the core fossil binary is
IMHO more beneficial in the long term, also from a maintenance point
of view. The tools can evolve separately. Especially important for CVS
as it will have to deal with lots of broken repositories, all
different.

However, nothing speaks against looking for common parts in all
possible import tools, and having these in the fossil core, as a
general backend all importer may use. Something like that has already
been proposed: The deconstruct|reconstruct methods. For us, actually
only reconstruct is important. Taking an unordered collection of files
(data, and manifests) it generates a proper fossil repository.  With
that method implemented all import tools only have to generate the
necessary collection and then leave the main work of filling the
database to fossil itself.

The disadvantage of this method is however that it will gobble up a
lot of temporary space in the filesystem to hold all unique revisions
of all files in their expanded form.

It might be worthwhile to consider an extension of 'reconstruct' which
is able to incrementally add a set of files to an existing fossil
repository already containing revisions. In that case the import tool
can be changed to incrementally generate the collection for a
particular revision, import it, and iterate over all revisions in the
origin repository. This is of course also dependent on the origin
repository itself, how well it supports such incremental export.

This also leads to a possible method for performing the import using
only existing functionality ('reconstruct' has not been implemented
yet). Instead generating an unordered collection for each revision
generate a properly setup workspace, simply commit it. This will
require use of rm, add and update methods as well, to remove old and
enter new files, and point the fossil repository to the correct parent
revision from the new revision is derived.

The relative efficiency (in time) of these incremental methods versus
importing a complete collection of files encoding the entire origin
repository however is not clear.

----------------------------------

reconstruct

The core logic for handling content is in the file "content.c", in
particular the functions 'content_put' and 'content_deltify'. One of
the main users of these functions is in the file "checkin.c", see the
function 'commit_cmd'.

The logic is clear. The new modified files are simply stored without
delta-compression, using 'content_put'. And should fosssil have an id
for the _previous_ revision of the committed file it uses
'content_deltify' to convert the already stored data for that revision
into a delta with the just stored new revision as origin.

In other words, fossil produces reverse deltas, with leaf revisions
stored just zip-compressed (plain) and older revisions using both zip-
and delta-compression.

Of note is that the underlying logic in 'content_deltify' gives up on
delta compression if the involved files are either not large enough,
or if the achieved compression factor was not high enough. In that
case the old revision of the file is left plain.

The scheme can thus be called a 'truncated reverse delta'.

The manifest is created and committed after the modified files. It
uses the same logic as for the regular files. The new leaf is stored
plain, and storage of the parent manifest is modified to be a delta
with the current as origin.

Further note that for a checkin of a merge result oonly the primary
parent is modified in that way. The secondary parent, the one merged
into the current revision is not touched. I.e. from the storage layer
point of view this revision is still a leaf and the data is kept
stored plain, not delta-compressed.



Now the "reconstruct" can be done like so:

- Scan the files in the indicated directory, and look for a manifest.

- When the manifest has been found parse its contents and follow the
  chain of parent links to locate the root manifest (no parent).

- Import the files referenced by the root manifest, then the manifest
  itself. This can be done using a modified form of the 'commit_cmd'
  which does not have to construct a manifest on its own from vfile,
  vmerge, etc.

- After that recursively apply the import of the previous step to the
  children of the root, and so on.

For an incremental "reconstruct" the collection of files would not be
a single tree with a root, but a forest, and the roots to look for are
not manifests without parent, but with a parent which is already
present in the repository. After one such root has been found and
processed the unprocessed files have to be searched further for more
roots, and only if no such are found anymore will the remaining files
be considered as superfluous.

We can use the functions in "manifest.c" for the parsing and following
the parental chain.

Hm. But we have no direct child information. So the above algorithm
has to be modified, we have to scan all manifests before we start
importing, and we have to create a reverse index, from manifest to
children so that we can perform the import from root to leaves.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































Deleted cvs2fossil.txt.
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66

Known problems and areas to work on
===================================

*	Not yet able to handle the specification of multiple projects
	for one CVS repository. I.e. I can, for example, import all of
	tcllib, or a single subproject of tcllib, like tklib, but not
	multiple sub-projects in one go.

*	Consider to rework the breaker- and sort-passes so that they
        do not need all changesets as objects in memory.

	Current memory consumption after all changesets are loaded:

	bwidget		 6971627    6.6
	cvs-memchan	 4634049    4.4
	cvs-sqlite	45674501   43.6
	cvs-trf		 8781289    8.4
	faqs		 2835116    2.7
	libtommath	 4405066    4.2
	mclistbox	 3350190    3.2 
	newclock	 5020460    4.8
	oocore		 4064574    3.9
	sampleextension	 4729932    4.5
	tclapps		 8482135    8.1
	tclbench	 4116887    3.9
	tcl_bignum	 2545192    2.4
	tclconfig	 4105042    3.9
	tcllib		31707688   30.2
	tcltutorial	 3512048    3.3
	tcl	       109926382  104.8
	thread		 8953139    8.5
	tklib		13935220   13.3
	tk		66149870   63.1
	widget		 2625609    2.5

*	Look at the dependencies on external packages and consider
	which of them can be moved into the importer, either as a
	simple utility command, or wholesale.

	struct::list
		assign, map, reverse, filter

		Very few and self-contained commands.

	struct::set
		size, empty, contains, add, include, exclude,
		intersect, subsetof

		Most of the core commands.

	fileutil
		cat, appendToFile, writeFile,
		tempfile, stripPath, test

	fileutil::traverse
		In toto

	struct::graph
		In toto

	snit
		In toto

	sqlite3
		In toto
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































Deleted kktodo.wiki.
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66
67
68
69
<h3>kkinnell</h3>

.plan -- <i>Fossil, the DG</i> Bwahahahaha! The cover art could be an <i>homo erectus</i> skull lying on some COBOL code...

  1.  Command line interface reference docs
     <ul>
         <li> <font color="#bb4466">Finish initial pages.</font></li>
	 <li> Start on tech-spec (serious, not "chatty") reference pages.</li>
	 <li> Edit, edit, edit.</li>
     </ul>

  2.  Support docs
     <ul>
	 <li>Basic explanation of Distributed SCM.</i>
	 <li>Tutorial
	 <ul>
	     <li>Silly source.  Start with existing dir struct.</li>
	     <li>Repository.  Creatiing and populating.</li>
	     <li>Where?  Local, Intranet, Internet.</li>
	     <li>Who? Project size defined by size of code base versus
	     number of developers.  Size matters.</li>
	     <li>How?
	     <ul>
	         <li>Open, close, commit, checkout, update, merge.</li>
	     </ul>
	     </li>
	     <li>Hmmm.  Experimenting.</li>
	     <ul>
	         <li>The road less travelled, or where'd that
		 fork come from?</li>
	     </ul>
	     <li>Oops!  Going back in time.</li>
	     <ul>
	         <li>Versions</li>
		 <ul>
		     <li>What <i>is</i> a version?</li>
		     <li>Is it a "version" or a "tag"?</li>
		     <li>DSCM redux: Revisionist versioning.</li>
		 </ul>
	     </ul>
	 </ul>
	 </li>
         <li>Basic explanation of <i>merge</i>.
	 <ol>
	     <li>Leaves, branches and baselines: We want a shrubbery!</li>
	     <li><i>update</i> merges vs. <i>merge</i> merges.
	     All merges are equal, but some are more equal than others.</li>
	 </ol>
	 </li>
     </ul>

  3.  Configuration

  42.  General
     <ul>
	 <li>Co-ordinate style and tone with drh, other devs. (documentation
         standard?  yuck.)</li>
     </ul>

  *  Tips & tricks.

  *  <b>Fossil</b> and <b>Sqlite</b>
     <ul>
         <li>Get a word in for Mrinal Kant's
	 <a href="http://code.google.com/p/sqlite-manager/">SQLite Manager</a>
	 XUL app.  Great tool.</li>
     </ul>

  *  Th (code groveling &#91;and code groveling {and code groveling ... } ... &#93; ... )
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































Deleted rse-notes.txt.
1
2
3
4
5
6
7
8
9
10
11
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
From: "Ralf S. Engelschall"
Date: October 18, 2008 1:40:53 PM EDT
To: drh@hwaci.com
Subject: Some Fossil Feedback

I've today looked at your Fossil project (latest version from your
repository). That's a _really_ interesting and very promising DVCS.
While I looked around and tested it, I stumbled over some issues I want
to share with you:

o No tarball

  You currently still do not provide any tarballs of the Fossil sources.
  Sure, you are still hacking wild on the code and one can on-the-fly
  fetch a ZIP archive, but that's a manual process. For packagers (like
  me in the OpenPKG project) this is very nasty and just means that
  Fossil will usually still not be packaged. As a result it will be not
  spreaded as much as possible and this way you still do not get as much
  as possible feedback. Hence, I recommend that you let daily snapshot
  tarballs (or ZIP files) be rolled. This would be great.

o UUID

  Under http://www.fossil-scm.org/index.html/doc/tip/www/concepts.wiki
  you describe the concepts and you clearly name the artifact ID a
  "UUID" and even say that this is a "Universally Unique Identifier".
  Unfortunately, a UUID is a 128-bit entity standardized by the ISO
  (under ISO/IEC 11578:1996) and IETF (under RFC-4122) and hence it is
  *VERY MUCH* confusing and unclean that your 160-bit SHA1-based ID is
  called "UUID" in Fossil.

  I *STRONGLY* recommend you to either use real UUIDs (128-bit
  entities, where a UUID of version 5 even is SHA1-based!) or you name
  your 160-bit SHA1 entities differently (perhaps AID for "Artifact
  Identifier"?).

o "fossil cgi <script>"

  Currently we have only "fossil cgi <script>" where <script> contains
  "repository: <file>". This is a neat idea and should be kept. But
  this way one cannot easily host multiple repositories over this
  CGI interface without creating such a script for every individual
  repository.

  Perhaps a "fossil cgi --repository <file>" would help here, as this
  way one can use a generic CGI script which first figures out the
  name <name> of the individual project and then runs "fossil cgi
  --repository /path/to/repositories/<name>.db". But perhaps I'm just
  overlooking something and this is already possible...

o "fossil db <operation>"

  In Monotone DVCS we have a "mtn db" command for the low-level SQLite
  database manipulations. For instance a "mtn --db=<monotone-repository>
  db dump" is more or less equal to a "sqlite3 <monotone-repository>
  .dump". A "mtn --db=<monotone-repository> db exec '<SQL>'" is equal
  "echo '<SQL>' | sqlite3 <monotone-repository>", etc. The point is
  that the DVCS user usually has no SQLite CLI at hand but as the DVCS
  already contains more or less the complete SQLite it is very useful to
  also include the SQLite CLI functionality and wire it into the DVCS
  CLI via a "db" command.

o "fossil version"

  Mostly all VCS I know if either support a command "version" or a
  command-line option "--version" or most of the time even both. Please
  output the "This is fossil version [9e80dc66cf] 2008-10-18 13:03:36"
  there (at least additionally) instead of at the end of "fossil help".

o "--port" vs. "-port"

  In the "fossil help server" there is "--port" while under
  http://www.fossil-scm.org/index.html/doc/tip/www/quickstart.wiki there
  is "-port". I personally like GNU-long-style options "--xxxx" more
  than the CC-style options "-xxx". But anyway, independent which one is
  correct (well, perhaps both even work) only one should be documented
  to avoid confusion.

o User creation on the CLI

  There is "fossil user new ?USERNAME?" which interactively prompts
  for the capabilities and the password -- even from the TTY and not
  from STDIN. One needs "fossil user new ?USERNAME? ?CAPABILITIES?
  ?PASSWORD?" to be able to create a repository in batch without having
  to hack the user into the "user" table via the SQLite CLI. Similar:
  the "fossil user password USERNAME" should be actually "fossil user
  password USERNAME ?PASSWORD?", please.

o "-R <repository"

  There is the "-R" option for specifiying the repository. But it is
  a sub-command option and not a global option. And on "fossil ui" or
  "fossil server" it even is an argument and not an option. This is
  confusing. Every time one has to figure out how to set the repository
  on the CLI. Monotone simply uses a *global* option "--db" and that's
  it. So, I recommend that Fossil also uses a single global option
  "--repository"/"-R" instead of a command-specific option. Sure, not
  all commands might require a repository, but IMHO it is better to
  ignore the global option there than having to figure out every time
  how the repository has to be specified.

o Setup pages

  When hitting "Apply changes" on any setup page, one keeps staying on
  this page. Sure, that's what an "apply" button usually is about. But
  I at least would have liked to see a button (either instead of the
  "apply changes" or at least in addition) which applies the changes and
  goes back to the setup main page (from where one usually come).

o _FOSSIL_

    Very nice idea to use another SQLite database for the _FOSSIL_
    control file. BUT: Why "_FOSSIL_"? CVS's "CVS" directory was ugly for
    decades. Today we have ".svn", ".git", ".hg" and "_MTN"/".mtn" to get
    rid of those ugly control files or directories of the DVCS! Sure,
    dot-files are disliked by Windows people. But that's no problem, one
    can accept "_XXX" in addition to ".XXX" easily, of course.

    So, I really would like to see the file "_FOSSIL_" to be renamed
    to ".fossil" under Unix and "_fossil" under Windows or (if the
    upper-case is important to you) ".FOSSIL" and "_FOSSIL". But to see
    an ugly "_FOSSIL_" at the top of every source tree is really rather
    boring for Unix people!

o "fossil open", "fossil checkout", "fossil update".

  I'm personally confused that "fossil open" is what "checkout" does in
  other DVCS and that "checkout" is just a variant of "update". Hmmm...
  for me it looks at least one should be eleminated to reduce confusion.
  The difference between checkout and update could become an option of
  a single option. And the remaining to perhaps better should be either
  "open" + "update" or "checkout" + "update". Well, perhaps I'm still
  not understanding Fossil enough. But I can only tell that I got rather
  confused.

o "fossil commit"

  There is "fossil commit" but no short-hand "fossil ci". But there
  is "fossil status" and even just "fossil st" which clearly shows
  that Fossil allows abbreviations or at least prefix-matching on the
  commands. Sure, "ci" is not a prefix of "commit" but mostly all VCS
  support the good old RCS/CVS "ci" and similar aliases. So I recommend
  that Fossil does not only alias matching, but also provides aliases:
  "ci" for "commit", "co" for "checkout", "log" for "timeline", etc.
  Sorry, having to type the long "fossil commit" every time is too long
  for us Unix hackers ;-)

  Additionally, Fossil seems to use GnuPG when installed and --nosign is
  not specified. Hmm... two questions arise here for me: 1. should the
  use of a cryptographically strong signature really be just _optional_
  (Monotone for instance RSA signs every commit) and 2. is GnuPG here
  really the right tool (Monotone does a plain RSA signing and is even
  able to leverage a running SSH agent for the operation -- something
  which is very cool both under Unix with "ssh-agent" and under Windows
  with "pagent"). OTOH, GnuPG 2.x supports a gpg-agent, so this might be
  no longer a big issue. But Fossil should document this a little bit
  futher: how to create the necessary GnuPG key, how to setup gpg-agent,
  etc.

o "fossil diff"

  There is "Usage: fossil diff|gdiff ?-i? ?-r REVISION? FILE...". Two
  questions arise: Why do I have to specify a "FILE"? I would expect
  that a simple "fossil diff" recursively shows a "diff" of all changed
  files in the source tree. Additionally, how does one do a diff between
  two particular revisions (one seems to be not able to specifiy "-r"
  twice).

o "manifest" / "manifest.uuid"

  Above I was already bothered by the _FOSSIL_ file, but now that I
  played with Fossil I see that "manifest" and "manifest.uuid" files
  showed up in my source tree. Why is this not implicitly in the
  database and instead externally represented in the source tree.
  Hmmm... then I recommend that you use a .fossil *DIRECTORY*, place
  the control file into .fossil/control (or whatever) and the manifest
  stuff into .fossil/manifest and .fossil/manifest.uuid. But please do
  not clutter the top-level of the source three with control data of the
  DVCS.

o "fossil mv"

  There is "fossil add" and "fossil rm", but no "fossil mv". Hopefully
  this doesn't mean a file move is an "add" and a "remove" bundle, as
  this way Fossil would have trouble to know that the file was renamed
  and hence the full history tracking of a file seems to be broken.

o "fossil changes" vs. "fossil status"

  Finally, I got confused by the "fossil changes" and "fossil status"
  commands. "fossil status" seems to be a super-set of "fossil changes".
  Looks a little bit less orthogonal than necessary. I would remove
  "fossil changes" or at least do not show the file details on "fossil
  status".

Yours,
                                                                            Ralf S. Engelschall

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































Changes to src/sqlite3.c.
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.8"
#define SQLITE_VERSION_NUMBER 3007008
#define SQLITE_SOURCE_ID      "2011-09-17 17:29:20 b31a7d7db9040d8eedaf1ecd89ea0033f579d0f1"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.8"
#define SQLITE_VERSION_NUMBER 3007008
#define SQLITE_SOURCE_ID      "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
** Allowed values for the flags parameter to sqlite3PagerOpen().
**
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
*/
#define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
#define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
#define PAGER_MEMORY        0x0004    /* In-memory database */
#define PAGER_SORTER        0x0020    /* Accumulator in external merge sort */

/*
** Valid values for the second argument to sqlite3PagerLockingMode().
*/
#define PAGER_LOCKINGMODE_QUERY      -1
#define PAGER_LOCKINGMODE_NORMAL      0
#define PAGER_LOCKINGMODE_EXCLUSIVE   1







<







8645
8646
8647
8648
8649
8650
8651

8652
8653
8654
8655
8656
8657
8658
** Allowed values for the flags parameter to sqlite3PagerOpen().
**
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
*/
#define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
#define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
#define PAGER_MEMORY        0x0004    /* In-memory database */


/*
** Valid values for the second argument to sqlite3PagerLockingMode().
*/
#define PAGER_LOCKINGMODE_QUERY      -1
#define PAGER_LOCKINGMODE_NORMAL      0
#define PAGER_LOCKINGMODE_EXCLUSIVE   1
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
*/
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE_THREADSAFE==1,      /* bFullMutex */
   SQLITE_USE_URI,            /* bOpenUri */
   0x7ffffffe,                /* mxStrlen */
   100,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0},         /* m */
   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0},   /* pcache */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */







|







12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
*/
SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
   1,                         /* bCoreMutex */
   SQLITE_THREADSAFE==1,      /* bFullMutex */
   SQLITE_USE_URI,            /* bOpenUri */
   0x7ffffffe,                /* mxStrlen */
   128,                       /* szLookaside */
   500,                       /* nLookaside */
   {0,0,0,0,0,0,0,0},         /* m */
   {0,0,0,0,0,0,0,0,0},       /* mutex */
   {0,0,0,0,0,0,0,0,0,0,0},   /* pcache */
   (void*)0,                  /* pHeap */
   0,                         /* nHeap */
   0, 0,                      /* mnHeap, mxHeap */
38149
38150
38151
38152
38153
38154
38155
38156
38157
38158
38159
38160
38161
38162
38163
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 hasSeenStress;           /* pagerStress() called one or more times */

  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine opertion.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe







<







38148
38149
38150
38151
38152
38153
38154

38155
38156
38157
38158
38159
38160
38161
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 memDb;                   /* True to inhibit all file I/O */


  /**************************************************************************
  ** The following block contains those class members that change during
  ** routine opertion.  Class members not in this block are either fixed
  ** when the pager is first created or else only change when there is a
  ** significant mode change (such as changing the page_size, locking_mode,
  ** or the journal_mode).  From another view, these class members describe
41704
41705
41706
41707
41708
41709
41710
41711
41712
41713
41714
41715
41716
41717
41718
  ** Spilling is also prohibited when in an error state since that could
  ** lead to database corruption.   In the current implementaton it 
  ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
  ** while in the error state, hence it is impossible for this routine to
  ** be called in the error state.  Nevertheless, we include a NEVER()
  ** test for the error state as a safeguard against future changes.
  */
  pPager->hasSeenStress = 1;
  if( NEVER(pPager->errCode) ) return SQLITE_OK;
  if( pPager->doNotSpill ) return SQLITE_OK;
  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
    return SQLITE_OK;
  }

  pPg->pDirty = 0;







<







41702
41703
41704
41705
41706
41707
41708

41709
41710
41711
41712
41713
41714
41715
  ** Spilling is also prohibited when in an error state since that could
  ** lead to database corruption.   In the current implementaton it 
  ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
  ** while in the error state, hence it is impossible for this routine to
  ** be called in the error state.  Nevertheless, we include a NEVER()
  ** test for the error state as a safeguard against future changes.
  */

  if( NEVER(pPager->errCode) ) return SQLITE_OK;
  if( pPager->doNotSpill ) return SQLITE_OK;
  if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
    return SQLITE_OK;
  }

  pPg->pDirty = 0;
Changes to src/sqlite3.h.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.8"
#define SQLITE_VERSION_NUMBER 3007008
#define SQLITE_SOURCE_ID      "2011-09-17 17:29:20 b31a7d7db9040d8eedaf1ecd89ea0033f579d0f1"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.8"
#define SQLITE_VERSION_NUMBER 3007008
#define SQLITE_SOURCE_ID      "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros