1# How To Mirror A Fossil Repository On GitHub
2
3Beginning with Fossil version 2.9, you can mirror a Fossil-based
4project on GitHub (with [limitations](./mirrorlimitations.md))
5by following these steps:
6
7<ol>
8<li><p>Create an account on GitHub if you do not have one already.  Log
9    into that account.
10
11<li><p>Create a new project.  GitHub will ask you if you want to prepopulate
12    your project with various things like a README file.  Answer "no" to
13    everything.  You want a completely blank project.  GitHub will then
14    supply you with a URL for your project that will look something
15    like this:
16
17<blockquote>
18https://github.com/username/project.git
19</blockquote>
20
21<li><p>Back on your workstation, move to a checkout for your Fossil
22    project and type:
23
24<blockquote>
25<pre>$ fossil git export /path/to/git/repo --autopush \
26  https://<font color="orange">username</font>:<font color="red">password</font>@github.com/username/project.git</pre>
27</blockquote>
28
29<p>   In place of the <code>/path/to...</code> argument above, put in
30      some directory name that is <i>outside</i> of your Fossil checkout. If
31      you keep multiple Fossil checkouts in a directory of their own,
32      consider using <code>../git-mirror</code> to place the Git export
33      mirror alongside them, for example.  Fossil will create this
34      directory if necessary.  This directory will become a Git
35      repository that holds a translation of your Fossil repository.
36
37<p>   The <code>--autopush</code> option tells Fossil that you want to
38      push the Git translation up to GitHub every time it is updated.
39
40<p>   The URL parameter is the same as the one GitHub gave you, but with
41      your GitHub <font color="orange">username</font> and <font
42      color="red">password</font> added.
43
44<p>   If your GitHub account uses two-factor authentication (2FA), you
45      will have to <a href="https://github.com/settings/tokens">generate
46      a personal access token</a> and use that in place of your actual
47      password in the URL. This token should have “repo” scope enabled,
48      only.
49
50<p>   You can also run the command above outside of any open checkout of
51      your project by supplying the “<code>-R&nbsp;repository</code>”
52      option.
53
54<li><p>Get some coffee.  Depending on the size of your project, the
55       initial "<code>fossil git export</code>" command in the previous
56       step might run for several minutes.
57
58<li><p>And you are done!  Assuming everything worked, your project is now
59    mirrored on GitHub.
60
61<li><p>Whenever you update your project, simply run this command to update
62    the mirror:
63
64<blockquote>
65<pre>$ fossil git export</pre>
66</blockquote>
67
68
69<p>   Unlike with the first time you ran that command, you don’t need
70      the remaining arguments, because Fossil remembers those things.
71      Subsequent mirror updates should usually happen in a fraction of
72      a second.
73
74<li><p>To see the status of your mirror, run:
75
76<blockquote>
77<pre>$ fossil git status</pre>
78</blockquote>
79</ol>
80
81## Notes:
82
83  *  Unless you specify --force, the mirroring only happens if the Fossil
84     repo has changed, with Fossil reporting "no changes", because Fossil
85     does not care about the success or failure of the mirror run. If a mirror
86     run failed (for example, due to an incorrect password, or a transient
87     error at github.com), Fossil will not retry until there has been a repo
88     change or --force is supplied.
89
90  *  The mirroring is one-way.  If you check in changes on GitHub, those
91     changes will not be reabsorbed by Fossil.  There are technical problems
92     that make a two-way mirror all but impossible. (This is not to be
93     confused with the ability to import a Fossil mirror from Github back
94     into a Fossil repository. That works, but it is not a mirror.)
95
96     This also means that you cannot accept pull requests on GitHub.
97
98  *  The "`fossil git export`" command creates subprocesses that run "`git`"
99     commands, so you must have Git installed on your machine for any
100     of this to work.
101
102  *  The Git repository will have an extra unmanaged top-level directory named
103     "`.mirror_state`" that contains one or more files.  Those files are
104     used to store the intermediate state of the translation so that
105     subsequent invocations of "`fossil git export`" will know where you
106     left off the last time and what new content needs to be moved over into
107     Git.  Be careful not to mess with the `.mirror_state` directory or
108     any of its contents.  Do not put those files under Git management.  Do
109     not edit or delete them.
110
111  *  The name of the "trunk" branch is automatically translated into "master"
112     in the Git mirror unless you give the `--mainbranch` option,
113     added in Fossil 2.14.
114
115  *  Only check-ins and simple tags are translated to Git.  Git does not
116     support wiki or tickets or unversioned content or any of the other
117     features of Fossil that make it so convenient to use, so those other
118     elements cannot be mirrored in Git.
119
120  *  In Git, all tags must be unique.  If your Fossil repository has the
121     same tag on two or more check-ins, the tag will only be preserved on
122     the chronologically newest check-in.
123
124  *  There is a
125     [long list of restrictions](https://git-scm.com/docs/git-check-ref-format)
126     on tag and branch names in Git.  If any of your Fossil tag or branch names
127     violate these rules, then the names are translated prior to being exported
128     to Git.  The translation usually involves converting the offending characters
129     into underscores.
130
131  *  If your Fossil user contact info is not set and this repository was not
132     initially [imported from Git](./inout.wiki), `fossil git export` will
133     construct a generic `user@noemail.net` for the Git *committer* and *author*
134     email fields of each commit. However, Fossil will first attempt to parse an
135     email address from your user contact info, which can be set through a
136     Fossil [UI][ui] browser window or with the [`user contact`][usercmd]
137     subcommand on the command line. Alternatively, if this repository was
138     previously imported from Git using the [`--attribute`][attr] option, the
139     [`fx_git`][fxgit] table will be queried for correspondent email addresses.
140     Only if neither of these methods produce a user specified email will the
141     abovementioned generic address be used.
142
143[attr]: /help?cmd=import
144[fxgit]: ./inout.wiki#fx_git
145[ui]: /help?cmd=ui
146[usercmd]: /help?cmd=user
147
148
149## <a id='ex1'></a>Example GitHub Mirrors
150
151As of this writing (2019-03-16) Fossil’s own repository is mirrored
152on GitHub at:
153
154>
155<https://github.com/drhsqlite/fossil-mirror>
156
157In addition, an official Git mirror of SQLite is available:
158
159>
160<https://github.com/sqlite/sqlite>
161
162The Fossil source repositories for these mirrors are at
163<https://www2.fossil-scm.org/fossil> and <https://www2.sqlite.org/src>,
164respectively.  Both repositories are hosted on the same VM at
165[Linode](https://www.linode.com).  On that machine, there is a
166[cron job](https://linux.die.net/man/8/cron)
167that runs at 17 minutes after the hour, every hour that does:
168
169>
170    /usr/bin/fossil sync -u -R /home/www/fossil/fossil.fossil
171    /usr/bin/fossil sync -R /home/www/fossil/sqlite.fossil
172    /usr/bin/fossil git export -R /home/www/fossil/fossil.fossil
173    /usr/bin/fossil git export -R /home/www/fossil/sqlite.fossil
174
175The initial two "sync" commands pull in changes from the primary
176Fossil repositories for Fossil and SQLite.  The last two lines
177export the changes to Git and push the results up to GitHub.
178