sqlite_authors: add missing expansion
[sqlite-export.git] / README.txt
blob5c6a0c84610d0079cb1b08f77c8b6a0fc1b16fdf
1 Exporting SQLite to Git
2 =======================
4 As of the [SQLite 3.28.0 release][1] there now exists an official Git
5 mirror of the SQLite software at <https://github.com/sqlite/sqlite>.
7 As of the [Fossil 2.9 release][2] on 2019-07-13, a new `fossil git
8 export` command provides the ability to export a Fossil repository
9 to git.
11 This project continues to provide an alternative mechanism to export
12 a fossil project to Git.  The new fossil 2.9 and later `fossil git export`
13 command produces a git repository that more-or-less matches one
14 created by using this project's `--trailer` and `--manifest` options
15 but without providing any mapping of user IDs to real user names.
17 Method        | User Names | Options    | Repository
18 :------------ | :--------- | :--------- | :----------
19 fossil 2.9    | left as ID | N/A        | FossilOrigin-Name trailers and manifests
20 sqlite-export | mapped     | <none>     | No notes, trailer lines or manifest files
21 sqlite-export | mapped     | --notes    | refs/notes/fossil records fossil check-in
22 sqlite-export | mapped     | --trailer  | FossilOrigin-Name trailer line added
23 sqlite-export | mapped     | --manifest | manifest and manifest.uuid files added
25 In fact, any of the three options (`--notes`, `--trailer`, `--manifest`)
26 may be used with this sqlite-export project in any combination to
27 produce the desired output repository with whatever "extras" are
28 desired or not.
30 Repository                 | Producer      | Extras
31 :------------------------- | :------------ | :-----
32 [$GH/sqlite/sqlite][3]     | fossil 2.9+   | no user mapping, always trailers and manifests
33 [$repo/sqlite][4]          | sqlite-export | users mapped, fossil origin in refs/notes/fossil
34 [$repo/sqlite-manifest][5] | sqlite-export | users mapped, trailers and manifests (no notes)
35 [$GH/mackyle/sqlite][6]    | sqlite-export | mirror of [$repo/sqlite][4]
37 The [$repo/sqlite][4] repository and its [$GH/mackyle/sqlite][6]
38 mirror are maintained using this project and the `--notes` option.
40 The [$repo/sqlite-manifest][5] repository is maintained using this
41 project and both the `--trailer` and `--manifest` options but _not_
42 the `--notes` option and should be substantially similar to [the
43 official git mirror of SQLite ($GH/sqlite/sqlite)][3] except that
44 user ids have been mapped to user names.
46 [1]: https://www.sqlite.org/releaselog/3_28_0.html
47 [2]: https://fossil-scm.org/home/doc/trunk/www/changes.wiki#v2_9
48 [3]: https://github.com/sqlite/sqlite.git
49 [4]: https://repo.or.cz/sqlite.git
50 [5]: https://repo.or.cz/sqlite/sqlite-manifest.git
51 [6]: https://github.com/mackyle/sqlite
54 Exporting to git with Fossil prior to 2.9
55 -----------------------------------------
57 _Reminder_
59 >  Fossil version 2.9 and later directly supports exporting the SQLite
60    fossil repository to git.  There's no reason to use this project
61    if that export process meets your needs.  See the [fossil 2.9
62    release notes][2] for details.
64 Theoretically exporting with fossil prior to version 2.9 is as simple as:
66   > `fossil export --git | git fast-import`
68 Unfortunately it doesn't work that way and that's what this project is all
69 about.
72 Quick Start
73 -----------
75 _Note_
77 >  Run the `build` script with the `-h` option to see some examples of
78    possible arguments.  Any arguments passed to the `build` script are passed
79    along to the fossil `configure` script during the build process.  Most
80    systems will not require any arguments be passed to the `build` script.
82 1. Run the script `build` to fetch and build a suitable fossil tool and a
83    `git-export-filter` tool.
85 2. Run the script `import` (maybe with the `--notes` and/or other options)
86    to create an `sqlite.git` Git clone of the <https://sqlite.org/src> fossil
87    sources.  (May take up to 60 minutes.)
89 3. See the "Building" section at the bottom of this README to "make" SQLite.
92 Fossil Issues
93 -------------
95 There are two problems with fossil export:
97 1. fossil versions starting with 1.18 mangle export branch and tag names to
98    avoid including characters git does not allow.  The problem is that many
99    more characters are mangled than needed so that a tag like `version-1.18`
100    is converted to `version_1_18` unnecessarily.
102 2. fossil versions after 1.18 produce a Git fast-import data stream that
103    causes `git fast-import` to fail with a fatal error.
106 The Tag Problem
107 ---------------
109 The fossil change that introduces tag mangling is here:
111   > <https://www.fossil-scm.org/index.html/info/b707622f29>
113 It was a well-intentioned change as previously invalid Git names would be
114 exported, but it went way, way too far.  In fact, the actual Git rules about
115 allowable characters in names are:
117   1. Characters with an ASCII value less than or equal to 32 are not allowed
118   2. The character with an ASCII value of 0x7F is not allowed
119   3. The characters '~', '^', ':', '\', '*', '?', and '[' are not allowed
120   4. The character '/' is a separator and is not allowed within a name
121   5. The name may not start with '.' or end with '.'
122   6. The name may not end with '.lock'
123   7. The name may not contain the '..' sequence
124   8. The name may not contain the '@{' sequence
125   9. If multiple components are used (separated by '/'), no empty '' components
127 A patch is included in the file `patches/export_c_patch_diff.txt` that allows
128 the full diversity of git names to be used and should be applied to the fossil
129 `src/export.c` file of fossil version 2.1 before building fossil.  It also adds
130 an optional --notes option to the fossil export --git command that if given
131 will add a note in the refs/notes/fossil namespace to each commit giving the
132 original fossil check-in hash for the commit.  Furthermore, it also provides a
133 new --use-done-feature option (see `git help fast-import`) and makes sure there
134 aren't any whitespace issues with commit messages by transforming CRLF into
135 just LF and making sure the only whitespace at the end is a single LF.
137 There may be updates coming to the official fossil release to address this
138 name mangling problem, but as of fossil 2.1 they have yet to make it into any
139 official fossil release.
142 The Export Problem
143 ------------------
145 The fossil change that introduces the export problem is here:
147   > <https://www.fossil-scm.org/index.html/info/bc8d368b66>
149 There is even a ticket about this "timewarp" export issue here:
151   > <https://www.fossil-scm.org/index.html/info/4013b0a81a>
153 This issue affects the `sqlite`, `sqlite_docsrc` and `fossil` repositories
154 making it impossible to export them from fossil and import them into Git with
155 a current version of fossil.
158 Let's do the Time Warp Again
159 ----------------------------
161 The fossil ticket linked to in the above "The Export Problem" section talks
162 about "timewarps".  These are simply check-ins with a timestamp that is earlier
163 than at least one of their parents (merges have two parents, most others one).
165 Fossil doesn't much like these.  The Git fast-import format is a "streamy"
166 format that, while it allows back references to things earlier in the stream,
167 does not allow forward references to future, prospective data.  Fossil likes
168 to output its fast-import stream in check-in date order.  And there you see
169 the issue.  If a "timewarp" is present then children get put out before their
170 parents arrive, and Git rudely ends the fast-import operation when this occurs.
172 All three of the primary fossil repositories (SQLite, SQLite Docs, Fossil) have
173 at least one "timewarp" in them.
175 Fossil versions 1.18 and earlier produce a usable fast-import stream not
176 because it orders the output check-ins correctly in spite of the "timewarp",
177 but because it outputs all data for each check-in rather than outputting only
178 differences from the parent(s).  So while the output isn't really correct, it
179 is accepted by Git and when outside the "timewarp" portion of the history,
180 the converted Git commits have exactly the correct set of sources, so it's
181 really not much more than a minor annoyance when reviewing very tiny parts
182 of older history in the repository.
184 Starting with fossil version 1.19 this all changed.  Now, whenever possible,
185 the exported Git fast-import stream only includes "changes" from a check-in's
186 parent(s).  With a sloppy ordering based only on check-in timestamp and in
187 the presence of "timewarps", children get put out before their parent(s) arrive
188 with the ensuing Git rudeness.  While, on the surface, this seems like a good
189 change (and it brought the ability to do incremental exports), full exports
190 seem to take somewhat longer overall now.
192 Then on 2017-02-23, they "shattered it" <https://shattered.it/>.
194 Shortly thereafter fossil version 2.0 came out supporting additional hash
195 functions.  And on 2017-03-12 the official SQLite fossil repository got its
196 first check-in using the new hash function.  Versions of fossil prior to 2.0
197 cannot deal with these new hash function values.
199 Now you see the problem.  Fossil version 1.18 can no longer be used (even with
200 its technically incorrect output) as it cannot understand the new hash values.
201 But fossil versions 1.19 and later (including 2.0) cannot be used either since
202 they produce a completely unacceptable fast-import stream in the presence of
203 any "timewarps".
205 But, curiosity is a harsh mistress.  The topological ordering problem was
206 solved even for fossil 1.18 in a satisfactory way some time ago but never
207 published to avoid causing all the Git refs values to be force-updated.
208 Correcting the misordering caused by the "timewarps" alters the DAG (directed
209 acyclic graph) of check-in ancestry and that trickles down to all the children
210 causing all of their `commit` hash values to change even though the sources they
211 refer to remain completely unchanged.
213 As of 2017-03-12 there really isn't a choice anymore.
215 A GPL version 2 (or later) patch is included to address this in the file
216 `patches/export_topo_patch_diff.txt` that provides a guaranteed topological
217 ordering to the exported fast-import stream.  When it's built into fossil,
218 that version of fossil becomes also covered by the GPL.  The repository data
219 fossil maintains is unaffected by fossil's license(s) so having a GPL-covered
220 fossil binary should not really affect anyone.
223 Fossil Sources
224 --------------
226 A .tar.gz archive of the fossil 2.1 sources may be fetched from:
228   > <https://fossil-scm.org/index.html/uv/fossil-src-2.1.tar.gz>
229   
230 The downloaded .tar.gz file should have these size and hash values:
232   > size:   4802504 bytes  
233   > md5:    9f32b23cecb092d42cdf11bf003ebf8d  
234   > sha1:   7c7387efb4c0016de6e836dba6f7842246825678  
235   > sha256: 85dcdf10d0f1be41eef53839c6faaa73d2498a9a140a89327cfb092f23cfef05
237 The `archives` subdirectory contains a copy of this .tar.gz file and it will
238 be used by the `build` script to create a `fossil` executable that reports its
239 version as `2.1+export ` to confirm that it contains the export fixes.
242 Git Fast Import Issues
243 ----------------------
245 The Git fast-import facility does not provide a means to filter the incoming
246 data stream to adjust user names (fossil export data only includes the user
247 login name as the email address) nor a means to adjust branch/tag names
248 (fossil exports a 'trunk' branch where Git expects a 'master' branch and fossil
249 also exports what are essentially lightweight tags as annotated tags).
251 To deal with these issues, the `git-export-filter` utility is used.
253 It can be found at:
255   > <https://repo.or.cz/git-export-filter.git>
257 The included `sqlite_authors` file is used with the `git-export-filter` tool to
258 supply real user names and email addresses.  Also note that the `sqlite_authors`
259 file also works for the <https://sqlite.org/docsrc> fossil repository as well.
262 The Final Solution
263 ------------------
265 After building a patched version of fossil 2.1 as described above and the
266 `git-export-filter` utility, a Git repository of the SQLite sources can be
267 created like so (which is what the `import --notes` script does):
269   >     fossil clone https://sqlite.org/src sqlite.fsl
270   >     git --git-dir=sqlite.git init --bare
271   >     fossil export --git --notes sqlite.fsl |
272   >     git-export-filter --authors-file sqlite_authors --require-authors \
273   >       --trunk-is-master --convert-tagger tagger |
274   >     git --git-dir=sqlite.git fast-import
276 The above will create the `sqlite.git` Git repository that is a clone of the
277 SQLite sources from the SQLite fossil respository <https://sqlite.org/src>
278 (note that only sources are cloned, not tickets or wiki pages or events).
280 The provided `build` script will attempt to download the necessary sources,
281 patch them and build suitable `fossil` and `git-export-filter` executable files.
282 It will pass along any arguments directly to the fossil `configure` script.
283 Run the `build` script with the `-h` option for examples (most systems will not
284 require any arguments be passed to the `build` script).
286 The provided `import` script will then attempt to clone the SQLite sources
287 and convert them into an `sqlite.git` repository.  It may be run again to update
288 the `sqlite.git` repository with new changes.  It accepts the `--notes` option
289 (which is recommended) to enable generation of the `refs/notes/fossil` notes
290 containing the original fossil check-in hash.  It also accepts the `--trailer`
291 and `--manifest` options which may be used in any combination with or without
292 the `--notes` option.
294 The initial run of the `import` script may take up to 60 minutes on a fast
295 machine, and subsequent runs of `import` even on a fast machine will still,
296 unfortunately, take some time.  The CPU will be pounded in either case.
298 **IMPORTANT**
300 Options passed to the `import` script are *not* remembered, so make sure to
301 pass the same options, (e.g. `--notes`) to the `import` script every time it's
302 run if it's being used to update a previously exported Git repository or you
303 may end up with out-of-date notes and/or mismatched trailer/manifest commits.
306 Options
307 -------
309 There are new options provided by the patch files for the `fossil export`
310 command.  As a convenience, they may be given to the `import` script which
311 will just pass them on to the `fossil export` command.
313 `--notes`
315 >   Included with the export tags patch a new fossil export option `--notes` is
316 >   provided that adds a Git commit note to the `refs/notes/fossil` namespace
317 >   which contains the original fossil check-in hash for each fossil checkin
318 >   exported to Git.  Use `git log --notes=fossil` to see these notes.
320 `--trailer`
322 >   Included with the export tags patch a new fossil export option `--trailer`
323 >   is provided that adds a "FossilOrigin-Name:" trailer line to each commit
324 >   created in the git repository that includes the original fossil check-in
325 >   hash for that commit.
327 `--manifest`
329 >   Included with the export tags patch a new fossil export option `--manifest`
330 >   is provided that causes every commit created in the git repository to
331 >   include a `manifest` and `manifest.uuid` file.  Use of this option will
332 >   increase the size of the generated git repository by approximately 25%.
334 `--use-done-feature`
336 >   Included with the export tags patch a new fossil export option
337 >   `--use-done-feature` is provided that includes the `feature done` and
338 >   `done` commands at the beginning and end respectively of the exported
339 >   fast-import stream.  This can help avoid partial imports.  See the
340 >   `git help fast-import` description of the ``--done`` option and the
341 >   `git help fast-export` description of the ``--use-done-feature`` option.
344 Building
345 --------
347 **QUICKLY**
349  1. Clone/checkout the new `sqlite.git` repository into a new working tree
351  2. Run the `create-fossil-manifest` script from this repository with the
352     current working directory set to the new working tree created in (1)
354  3. Now run the `configure` script in the new working tree created in (1)
356  4. Now run `make` in the new working tree created in (1)
358 **DETAILS**
360 Ideally, simply cloning from the new `sqlite.git` repository would allow one to
361 then build SQLite by simply using `make` (or `configure` and `make`).
363 Unfortunately, this is not the case, the make will fail with a message about
364 no rule to make the files `manifest` and/or `manifest.uuid` unless the
365 `--manifest` option was passed to the `import` script.
367 Both the SQLite sources and the Fossil sources require two fossil vcs specific
368 files to be created (`manifest` and `manifest.uuid`) in order for make to be
369 successful.  When the `--manifest` option is passed to the `import` script
370 these files are added to every commit in the generated git repository which
371 increases the repository size by roughly 25%.
373 The `manifest.uuid` file simply contains the hash of the current checkout
374 and while a real `manifest` file contains a bunch of information, the only
375 thing that need be present is a line containing the UTC ISO date preceded
376 by 'D '.
378 The `create-fossil-manifest` script takes care of creating these files and
379 should be run with the current working directory set to the top-level of the
380 git clone's working directory if the `--manifest` option was _NOT_ passed to
381 the `import` script.
383 Any time the HEAD commit changes, the `create-fossil-manifest` script should
384 be run to update the `manifest` and `manifest.uuid` files (only if the
385 `--manifest` option was _NOT_ passed to the `import` script) before next
386 running make or the output of the `sqlite_source_id()` function will be
387 incorrect.