Fossil SCM
Covered the difference between "git log" and "fossil timeline" in the gitusers doc; made several other improvements while in there.
Commit
f6ad6fb179b4075856c5133e902e1c15163fe15e702a632ed9481e9e4d045fdc
Parent
6a6fd6b911f2a33…
1 file changed
+93
-56
+93
-56
| --- www/gitusers.md | ||
| +++ www/gitusers.md | ||
| @@ -19,35 +19,44 @@ | ||
| 19 | 19 | [1]: https://fossil-scm.org/forum |
| 20 | 20 | |
| 21 | 21 | Specific suggestions on how to improve this document are also welcomed, |
| 22 | 22 | of course. |
| 23 | 23 | |
| 24 | + | |
| 25 | + | |
| 26 | +## <a id="term"></a> Terminology | |
| 27 | + | |
| 28 | +While we do try to explain Fossil-specific terminology inline here | |
| 29 | +as-needed, you may find it helpful to skim [the Fossil glossary][gloss]. | |
| 30 | +It will give you another take on our definitions here, and it may help | |
| 31 | +you to understand some of the other Fossil docs better. | |
| 32 | + | |
| 33 | + | |
| 34 | +---- | |
| 35 | + | |
| 24 | 36 | |
| 25 | 37 | <a id="mwd"></a> |
| 26 | 38 | ## Repositories And Checkouts Are Distinct |
| 27 | 39 | |
| 28 | 40 | A repository and a check-out are distinct concepts in Fossil, whereas |
| 29 | 41 | the two are collocated by default with Git. |
| 30 | 42 | |
| 31 | -A Fossil repository is a SQLite database in | |
| 32 | -which the entire history of a project is stored. A check-out is a | |
| 43 | +A Fossil repository is a SQLite database storing | |
| 44 | +the entire history of a project. A Fossil check-out is a | |
| 33 | 45 | directory that contains a snapshot of your project that you |
| 34 | 46 | are currently working on, extracted for you from that database by the |
| 35 | 47 | `fossil` program. |
| 36 | 48 | |
| 37 | -(See [the Fossil glossary][gloss] for more Fossil terms of art that may | |
| 38 | -be unfamiliar to a Git user.) | |
| 39 | - | |
| 40 | 49 | With Git, cloning a repository gets you what Fossil would call a |
| 41 | 50 | check-out directory with the repository stored in a `.git` subdirectory |
| 42 | -of that check-out. There are methods to get more working directories | |
| 51 | +of that check-out. There are methods to get additional working directories | |
| 43 | 52 | pointing at that same Git repository, but because it’s not designed into |
| 44 | 53 | the core concept of the tool, Git tutorials usually advocate a |
| 45 | 54 | switch-in-place working mode instead, so that is how most users end up |
| 46 | 55 | working with it. |
| 47 | 56 | |
| 48 | -Fossil can operate in the Git mode, switching between versions in a | |
| 57 | +You can use Fossil the same way, switching between versions in a | |
| 49 | 58 | single check-out directory: |
| 50 | 59 | |
| 51 | 60 | fossil clone https://example.com/repo /path/to/repo.fossil |
| 52 | 61 | mkdir work-dir |
| 53 | 62 | cd work-dir |
| @@ -54,32 +63,41 @@ | ||
| 54 | 63 | fossil open /path/to/repo.fossil |
| 55 | 64 | ...work on trunk... |
| 56 | 65 | fossil update my-other-branch # like “git checkout” |
| 57 | 66 | ...work on your other branch in the same directory... |
| 58 | 67 | |
| 59 | -As of Fossil 2.12, it can clone-and-open into a single directory, as Git | |
| 68 | +As of Fossil 2.12, you can ask it to clone-and-open into a single directory, as Git | |
| 60 | 69 | always has done: |
| 61 | 70 | |
| 62 | 71 | mkdir work-dir |
| 63 | 72 | cd work-dir |
| 64 | 73 | fossil open https://example.com/repo |
| 65 | 74 | |
| 66 | 75 | Now you have “trunk” open in `work-dir`, with the repo file stored as |
| 67 | 76 | `repo.fossil` in that same directory. |
| 68 | 77 | |
| 69 | -(Note that Fossil purposefully does not create the directory for you as | |
| 70 | -Git does, because this feature is an extension of | |
| 71 | -[the “open” command][open], which historically means “open in the | |
| 72 | -current directory” in Fossil. It would be wrong for Fossil to create a | |
| 73 | -subdirectory when passed a URI but not when passed any other parameter.) | |
| 78 | +You may be expecting [`fossil clone`][clone] to create a directory for | |
| 79 | +you like Git does, but because the repository is separate from the | |
| 80 | +working directory, it does not do that, on purpose: you have to tell it | |
| 81 | +where to store the repository file. | |
| 74 | 82 | |
| 75 | -The repository file can be named anything you want, with a single | |
| 83 | +The [`fossil open URI`][open] syntax is our compromise for users wanting | |
| 84 | +a clone-and-open command. But, because Fossil’s `open` command | |
| 85 | +historically opens into the current directory, and it won’t open a | |
| 86 | +repository into a non-empty directory by default — as of Fossil 2.12, | |
| 87 | +anyway — you have to create the directory manually and `cd` into it | |
| 88 | +before opening it. If `fossil open URI` worked like `git clone`, that | |
| 89 | +would mean `fossil open` has two different ways of working depending on | |
| 90 | +the argument, which is a non-Fossil sort of thing to do. We strive for | |
| 91 | +consistent behavior across commands and modes. | |
| 92 | + | |
| 93 | +The Fossil repository file can be named anything you want, with a single | |
| 76 | 94 | exception: if you’re going to use the [`fossil server DIRECTORY`][server] |
| 77 | 95 | feature, the repositories need to have a "`.fossil`" suffix. That aside, |
| 78 | 96 | you can follow any other convention that makes sense to you. |
| 79 | 97 | |
| 80 | -Many people choose to gather all of their Fossil repositories | |
| 98 | +Many Fossil users gather all of their Fossil repositories | |
| 81 | 99 | in a single directory on their machine, such as "`~/museum`" or |
| 82 | 100 | "`C:\Fossils`". This can help humans to keep their repositories |
| 83 | 101 | organized, but Fossil itself doesn't really care. (Why “museum”? |
| 84 | 102 | Because that is where one stores valuable fossils.) |
| 85 | 103 | |
| @@ -107,22 +125,23 @@ | ||
| 107 | 125 | “scratch” directory for experiments or brief bits of work you don’t want |
| 108 | 126 | to do in the other check-out directories, and a directory for testing a |
| 109 | 127 | user report of a bug in the trunk version as of last April Fool’s Day. |
| 110 | 128 | Each check-out operates independently of the others. |
| 111 | 129 | |
| 112 | -This working style is especially useful when programming in languages | |
| 130 | +This multiple-checkouts working style is especially useful when Fossil stores source code in programming languages | |
| 113 | 131 | where there is a “build” step that transforms source files into files |
| 114 | -you actually run or distribute. With Git, switching versions in a single | |
| 115 | -working tree means you have to rebuild all outputs from the source files | |
| 116 | -that differ between those versions. In the above Fossil working model, | |
| 132 | +you actually run or distribute. With Git’s typical switch-in-place workflow, | |
| 133 | +you have to rebuild all outputs from the source files | |
| 134 | +that differ between those versions whenever you switch versions. In the above Fossil working model, | |
| 117 | 135 | you switch versions with a “`cd`” command instead, so that you only have |
| 118 | 136 | to rebuild outputs from files you yourself change. |
| 119 | 137 | |
| 120 | 138 | This style is also useful when a check-out directory may be tied up with |
| 121 | 139 | some long-running process, as with the “test” example above, where you |
| 122 | 140 | might need to run an hours-long brute-force replication script to tickle |
| 123 | -a [Heisenbug][hb], forcing it to show itself. While that runs, you can “`cd ../trunk`” and get back | |
| 141 | +a [Heisenbug][hb], forcing it to show itself. While that runs, you can | |
| 142 | +open a new terminal tab, “`cd ../trunk`”, and get back | |
| 124 | 143 | to work. |
| 125 | 144 | |
| 126 | 145 | Git users may be initially confused by the `.fslckout` file at the root |
| 127 | 146 | of a check-out directory. |
| 128 | 147 | This is not the same thing as `.git`. It’s a per-checkout SQLite |
| @@ -135,31 +154,47 @@ | ||
| 135 | 154 | (In native Windows builds of Fossil, this file is called `_FOSSIL_` |
| 136 | 155 | instead to get around the historical 3-character extension limit with |
| 137 | 156 | certain legacy filesystems. “Native” here is a distinction to exclude |
| 138 | 157 | Cygwin and WSL builds, which use `.fslckout`.) |
| 139 | 158 | |
| 159 | +[clone]: /help?cmd=clone | |
| 140 | 160 | [close]: /help?cmd=close |
| 141 | 161 | [gloss]: ./whyusefossil.wiki#definitions |
| 142 | 162 | [hb]: https://en.wikipedia.org/wiki/Heisenbug |
| 143 | 163 | [open]: /help?cmd=open |
| 144 | 164 | [set]: /help?cmd=setting |
| 145 | 165 | [server]: /help?cmd=server |
| 146 | 166 | [stash]: /help?cmd=stash |
| 147 | 167 | [undo]: /help?cmd=undo |
| 148 | 168 | |
| 169 | + | |
| 170 | +## <a id="log"></a> Fossil’s Timeline is the “Log” | |
| 171 | + | |
| 172 | +Git users often need to use the `git log` command to grovel through | |
| 173 | +commit histories due to its [weak data model][wdm]. | |
| 174 | + | |
| 175 | +Fossil parses a huge amount of information out of commits that allow it | |
| 176 | +to produce its [timeline CLI][tlc] and [its `/timeline` web view][tlw], | |
| 177 | +which generally have the info you would have to manually extract from | |
| 178 | +`git log`. | |
| 179 | + | |
| 180 | +[tlc]: /help?cmd=timeline | |
| 181 | +[tlw]: /help?cmd=/timeline | |
| 182 | +[wdm]: ./fossil-v-git.wiki#durable | |
| 183 | + | |
| 149 | 184 | |
| 150 | 185 | <a id="staging"></a> |
| 151 | 186 | ## There Is No Staging Area |
| 152 | 187 | |
| 153 | 188 | Fossil omits the "Git index" or "staging area" concept. When you |
| 154 | 189 | type "`fossil commit`" _all_ changes in your check-out are committed, |
| 155 | 190 | automatically. There is no need for the "-a" option as with Git. |
| 156 | 191 | |
| 157 | -If you only want to commit just some of the changes, you can list the names | |
| 158 | -of the files you want to commit as arguments, like this: | |
| 192 | +If you only want to commit _some_ of the changes, list the names | |
| 193 | +of the files or directories you want to commit as arguments, like this: | |
| 159 | 194 | |
| 160 | - fossil commit src/main.c doc/readme.md | |
| 195 | + fossil commit src/feature.c doc/feature.md examples/feature | |
| 161 | 196 | |
| 162 | 197 | |
| 163 | 198 | <a id="bneed"></a> |
| 164 | 199 | ## Create Branches At Point Of Need, Rather Than Ahead of Need |
| 165 | 200 | |
| @@ -168,14 +203,16 @@ | ||
| 168 | 203 | |
| 169 | 204 | fossil commit --branch my-new-branch |
| 170 | 205 | |
| 171 | 206 | If that commit is successful, your local check-out directory is then |
| 172 | 207 | switched to the tip of that branch, so subsequent commits don’t need the |
| 173 | -“`--branch`” option. You have to switch back to the parent branch | |
| 174 | -explicitly, as with | |
| 208 | +“`--branch`” option. You simply say `fossil commit` again to continue | |
| 209 | +adding commits to the tip of that branch. | |
| 175 | 210 | |
| 176 | - fossil update trunk # return to parent, “trunk” in this case | |
| 211 | +To switch back to the parent branch, say something like: | |
| 212 | + | |
| 213 | + fossil update trunk # like “git checkout” | |
| 177 | 214 | |
| 178 | 215 | Fossil does also support the Git style, creating the branch ahead of |
| 179 | 216 | need: |
| 180 | 217 | |
| 181 | 218 | fossil branch new my-new-branch |
| @@ -202,27 +239,27 @@ | ||
| 202 | 239 | |
| 203 | 240 | <a id="autosync"></a> |
| 204 | 241 | ## Autosync |
| 205 | 242 | |
| 206 | 243 | Fossil’s [autosync][wflow] feature, normally enabled, has no |
| 207 | -equivalent in Git. If you want Fossil to behave like Git, you will turn | |
| 244 | +equivalent in Git. If you want Fossil to behave like Git, you can turn | |
| 208 | 245 | it off: |
| 209 | 246 | |
| 210 | 247 | fossil set autosync 0 |
| 211 | 248 | |
| 212 | -It’s better to understand what the feature does and why it is enabled by | |
| 249 | +However, it’s better to understand what the feature does and why it is enabled by | |
| 213 | 250 | default. |
| 214 | 251 | |
| 215 | 252 | When autosync is enabled, Fossil automatically pushes your changes |
| 216 | 253 | to the remote server whenever you "`fossil commit`", and it |
| 217 | 254 | pulls all remote changes down to your local clone of the repository as |
| 218 | 255 | part of a "`fossil update`". |
| 219 | 256 | This provides most of the advantages of a centralized version control |
| 220 | 257 | system while retaining the advantages of distributed version control: |
| 221 | 258 | |
| 222 | -1. Your work stays synced up with your coworkers as long as your | |
| 223 | - machine can connect to the remote repository, but at need, you can go | |
| 259 | +1. Your work stays synced up with your coworkers’ efforts as long as your | |
| 260 | + machine can connect to the remote repository. At need, you can go | |
| 224 | 261 | off-network and continue work atop the last version you sync’d with |
| 225 | 262 | the remote. |
| 226 | 263 | |
| 227 | 264 | 2. It provides immediate off-machine backup of your commits. Unlike |
| 228 | 265 | centralized version control, though, you can still work while |
| @@ -245,16 +282,17 @@ | ||
| 245 | 282 | [setup]: ./caps/admin-v-setup.md#apsu |
| 246 | 283 | [wflow]: ./concepts.wiki#workflow |
| 247 | 284 | |
| 248 | 285 | |
| 249 | 286 | <a id="syncall"></a> |
| 250 | -## Syncing Is All-Or-Nothing | |
| 287 | +## Sync Is All-Or-Nothing | |
| 251 | 288 | |
| 252 | 289 | Fossil does not support the concept of syncing, pushing, or pulling |
| 253 | -individual branches. When you sync/push/pull in Fossil, you sync/push/pull | |
| 254 | -everything: all branches, all wiki, all tickets, all forum posts, | |
| 255 | -all tags, all technotes… Everything. | |
| 290 | +individual branches. When you sync/push/pull in Fossil, you | |
| 291 | +sync/push/pull everything stored as artifacts in its hash tree: | |
| 292 | +branches, tags, wiki articles, tickets, forum posts, technotes… | |
| 293 | +[Almost everything][bu]. | |
| 256 | 294 | |
| 257 | 295 | Furthermore, branch *names* sync automatically in Fossil, not just the |
| 258 | 296 | content of those branches. This means this common Git command: |
| 259 | 297 | |
| 260 | 298 | git push origin master |
| @@ -365,29 +403,34 @@ | ||
| 365 | 403 | fossil mv --hard old-name new-name |
| 366 | 404 | |
| 367 | 405 | [mv]: /help?cmd=mv |
| 368 | 406 | [rm]: /help?cmd=rm |
| 369 | 407 | |
| 408 | + | |
| 409 | +---- | |
| 410 | + | |
| 370 | 411 | |
| 371 | 412 | <a id="morigin"></a> |
| 372 | 413 | ## Multiple "origin" Servers |
| 373 | 414 | |
| 374 | 415 | In this final section of the document, we’ll go into a lot more detail |
| 375 | 416 | to illustrate the points above, not just give a quick summary of this |
| 376 | 417 | single difference. |
| 377 | 418 | |
| 378 | -Consider a common use case — at the time of this writing, during the | |
| 419 | +Consider a common use case at the time of this writing — during the | |
| 379 | 420 | COVID-19 pandemic — where you’re working from home a lot, going into the |
| 380 | -office maybe one part-day a week. Let us also say you have no remote | |
| 421 | +office one part-day a week only to do things that have to be done | |
| 422 | +on-site at the office. Let us also say you have no remote | |
| 381 | 423 | access back into the work LAN, such as because your site IT is paranoid |
| 382 | -about security. You may still want off-machine backups of your commits, | |
| 383 | -so what you want is the ability to quickly switch between the “home” and | |
| 424 | +about security. You may still want off-machine backups of your commits | |
| 425 | +while working from home, | |
| 426 | +so you need the ability to quickly switch between the “home” and | |
| 384 | 427 | “work” remote repositories, with your laptop acting as a kind of |
| 385 | 428 | [sneakernet][sn] link between the big development server at the office |
| 386 | 429 | and your family’s home NAS. |
| 387 | 430 | |
| 388 | -### Git Method | |
| 431 | +#### Git Method | |
| 389 | 432 | |
| 390 | 433 | We first need to clone the work repo down to our laptop, so we can work on it |
| 391 | 434 | at home: |
| 392 | 435 | |
| 393 | 436 | git clone https://dev-server.example.com/repo |
| @@ -408,11 +451,11 @@ | ||
| 408 | 451 | |
| 409 | 452 | Realize that this is carefully optimized down to these two long |
| 410 | 453 | commands. In practice, typing these commands by hand, from memory, we’d |
| 411 | 454 | expect a normal user to need to give four or more commands here instead. |
| 412 | 455 | Packing the “`git init`” call into the “`ssh`” call is something more |
| 413 | -done in scripts and documentation examples than is done interactively, | |
| 456 | +often done in scripts and documentation examples than done interactively, | |
| 414 | 457 | which then necessitates a third command before the push, “`exit`”. |
| 415 | 458 | There’s also a good chance that you’ll forget the need for the `--bare` |
| 416 | 459 | option here to avoid a fatal complaint from Git that the laptop can’t |
| 417 | 460 | push into a non-empty repo. If you fall into this trap, among the many |
| 418 | 461 | that Git lays for newbies, you have to nuke the incorrectly initted |
| @@ -453,42 +496,36 @@ | ||
| 453 | 496 | This example also shows a consequence of that fact that |
| 454 | 497 | [Git doesn’t sync branch names](#syncall): you have to keep repeating |
| 455 | 498 | yourself, “master, master.” |
| 456 | 499 | |
| 457 | 500 | |
| 458 | -### Fossil Method | |
| 501 | +#### Fossil Method | |
| 459 | 502 | |
| 460 | 503 | Now we’re going to do the same thing as above using Fossil. We’ve broken |
| 461 | 504 | the commands up into blocks corresponding to those above for comparison. |
| 505 | + | |
| 462 | 506 | We start the same way, cloning the work repo down to the laptop: |
| 463 | 507 | |
| 464 | 508 | mkdir repo |
| 465 | 509 | cd repo |
| 466 | 510 | fossil open https://dev-server.example.com/repo |
| 467 | 511 | fossil remote add work https://dev-server.example.com/repo |
| 468 | 512 | |
| 469 | -Unlike Git, Fossil’s “clone and open” feature doesn’t create the | |
| 470 | -directory for you, so we need an extra `mkdir` call here that isn’t | |
| 471 | -needed in the Git case. This is an indirect reflection of Fossil’s | |
| 472 | -[multiple working directories](#mwd) design philosophy: its | |
| 473 | -[`open` command][open] requires that you either issue it in an empty | |
| 474 | -directory or one containing a prior closed check-out. In exchange for | |
| 475 | -this extra command, we get the advantage of Fossil’s | |
| 476 | -[superior handling][shwmd] of multiple working directories. To get the | |
| 477 | -full power of this feature, you’d switch from the “`fossil open URI`” | |
| 478 | -command form to the separate clone-and-open form shown in | |
| 479 | -[the quick start guide][qs], which adds one more command. | |
| 480 | - | |
| 481 | -We can’t spin the longer final command as a trade-off giving us extra | |
| 482 | -power, though: the simple fact is, Fossil currently has no short command | |
| 513 | +We’ve chosen the “`fossil open URI`” syntax here rather than separate | |
| 514 | +`clone` and `open` commands to make the parallel with Git clearer. [See | |
| 515 | +above](#mwd) for more on that topic. | |
| 516 | + | |
| 517 | +The final command is longer than the Git equivalent because | |
| 518 | +Fossil currently has no short command | |
| 483 | 519 | to rename an existing remote. Worse, unlike with Git, we can’t just keep |
| 484 | 520 | using the default remote name because Fossil uses that slot in its |
| 485 | 521 | configuration database to store the *current* remote name, so on |
| 486 | 522 | switching from work to home, the home URL will overwrite the work URL if |
| 487 | 523 | we don’t give it an explicit name first. |
| 488 | 524 | |
| 489 | -Keep these costs in perspective, however: they’re one-time setup costs, | |
| 525 | +So far, the Fossil commands are longer, but keep these costs in perspective: | |
| 526 | +they’re one-time setup costs, | |
| 490 | 527 | easily amortized to insignificance by the shorter day-to-day commands |
| 491 | 528 | below. |
| 492 | 529 | |
| 493 | 530 | On first beginning to work from home, we reverse-clone the Fossil repo |
| 494 | 531 | up to the NAS: |
| 495 | 532 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -19,35 +19,44 @@ | |
| 19 | [1]: https://fossil-scm.org/forum |
| 20 | |
| 21 | Specific suggestions on how to improve this document are also welcomed, |
| 22 | of course. |
| 23 | |
| 24 | |
| 25 | <a id="mwd"></a> |
| 26 | ## Repositories And Checkouts Are Distinct |
| 27 | |
| 28 | A repository and a check-out are distinct concepts in Fossil, whereas |
| 29 | the two are collocated by default with Git. |
| 30 | |
| 31 | A Fossil repository is a SQLite database in |
| 32 | which the entire history of a project is stored. A check-out is a |
| 33 | directory that contains a snapshot of your project that you |
| 34 | are currently working on, extracted for you from that database by the |
| 35 | `fossil` program. |
| 36 | |
| 37 | (See [the Fossil glossary][gloss] for more Fossil terms of art that may |
| 38 | be unfamiliar to a Git user.) |
| 39 | |
| 40 | With Git, cloning a repository gets you what Fossil would call a |
| 41 | check-out directory with the repository stored in a `.git` subdirectory |
| 42 | of that check-out. There are methods to get more working directories |
| 43 | pointing at that same Git repository, but because it’s not designed into |
| 44 | the core concept of the tool, Git tutorials usually advocate a |
| 45 | switch-in-place working mode instead, so that is how most users end up |
| 46 | working with it. |
| 47 | |
| 48 | Fossil can operate in the Git mode, switching between versions in a |
| 49 | single check-out directory: |
| 50 | |
| 51 | fossil clone https://example.com/repo /path/to/repo.fossil |
| 52 | mkdir work-dir |
| 53 | cd work-dir |
| @@ -54,32 +63,41 @@ | |
| 54 | fossil open /path/to/repo.fossil |
| 55 | ...work on trunk... |
| 56 | fossil update my-other-branch # like “git checkout” |
| 57 | ...work on your other branch in the same directory... |
| 58 | |
| 59 | As of Fossil 2.12, it can clone-and-open into a single directory, as Git |
| 60 | always has done: |
| 61 | |
| 62 | mkdir work-dir |
| 63 | cd work-dir |
| 64 | fossil open https://example.com/repo |
| 65 | |
| 66 | Now you have “trunk” open in `work-dir`, with the repo file stored as |
| 67 | `repo.fossil` in that same directory. |
| 68 | |
| 69 | (Note that Fossil purposefully does not create the directory for you as |
| 70 | Git does, because this feature is an extension of |
| 71 | [the “open” command][open], which historically means “open in the |
| 72 | current directory” in Fossil. It would be wrong for Fossil to create a |
| 73 | subdirectory when passed a URI but not when passed any other parameter.) |
| 74 | |
| 75 | The repository file can be named anything you want, with a single |
| 76 | exception: if you’re going to use the [`fossil server DIRECTORY`][server] |
| 77 | feature, the repositories need to have a "`.fossil`" suffix. That aside, |
| 78 | you can follow any other convention that makes sense to you. |
| 79 | |
| 80 | Many people choose to gather all of their Fossil repositories |
| 81 | in a single directory on their machine, such as "`~/museum`" or |
| 82 | "`C:\Fossils`". This can help humans to keep their repositories |
| 83 | organized, but Fossil itself doesn't really care. (Why “museum”? |
| 84 | Because that is where one stores valuable fossils.) |
| 85 | |
| @@ -107,22 +125,23 @@ | |
| 107 | “scratch” directory for experiments or brief bits of work you don’t want |
| 108 | to do in the other check-out directories, and a directory for testing a |
| 109 | user report of a bug in the trunk version as of last April Fool’s Day. |
| 110 | Each check-out operates independently of the others. |
| 111 | |
| 112 | This working style is especially useful when programming in languages |
| 113 | where there is a “build” step that transforms source files into files |
| 114 | you actually run or distribute. With Git, switching versions in a single |
| 115 | working tree means you have to rebuild all outputs from the source files |
| 116 | that differ between those versions. In the above Fossil working model, |
| 117 | you switch versions with a “`cd`” command instead, so that you only have |
| 118 | to rebuild outputs from files you yourself change. |
| 119 | |
| 120 | This style is also useful when a check-out directory may be tied up with |
| 121 | some long-running process, as with the “test” example above, where you |
| 122 | might need to run an hours-long brute-force replication script to tickle |
| 123 | a [Heisenbug][hb], forcing it to show itself. While that runs, you can “`cd ../trunk`” and get back |
| 124 | to work. |
| 125 | |
| 126 | Git users may be initially confused by the `.fslckout` file at the root |
| 127 | of a check-out directory. |
| 128 | This is not the same thing as `.git`. It’s a per-checkout SQLite |
| @@ -135,31 +154,47 @@ | |
| 135 | (In native Windows builds of Fossil, this file is called `_FOSSIL_` |
| 136 | instead to get around the historical 3-character extension limit with |
| 137 | certain legacy filesystems. “Native” here is a distinction to exclude |
| 138 | Cygwin and WSL builds, which use `.fslckout`.) |
| 139 | |
| 140 | [close]: /help?cmd=close |
| 141 | [gloss]: ./whyusefossil.wiki#definitions |
| 142 | [hb]: https://en.wikipedia.org/wiki/Heisenbug |
| 143 | [open]: /help?cmd=open |
| 144 | [set]: /help?cmd=setting |
| 145 | [server]: /help?cmd=server |
| 146 | [stash]: /help?cmd=stash |
| 147 | [undo]: /help?cmd=undo |
| 148 | |
| 149 | |
| 150 | <a id="staging"></a> |
| 151 | ## There Is No Staging Area |
| 152 | |
| 153 | Fossil omits the "Git index" or "staging area" concept. When you |
| 154 | type "`fossil commit`" _all_ changes in your check-out are committed, |
| 155 | automatically. There is no need for the "-a" option as with Git. |
| 156 | |
| 157 | If you only want to commit just some of the changes, you can list the names |
| 158 | of the files you want to commit as arguments, like this: |
| 159 | |
| 160 | fossil commit src/main.c doc/readme.md |
| 161 | |
| 162 | |
| 163 | <a id="bneed"></a> |
| 164 | ## Create Branches At Point Of Need, Rather Than Ahead of Need |
| 165 | |
| @@ -168,14 +203,16 @@ | |
| 168 | |
| 169 | fossil commit --branch my-new-branch |
| 170 | |
| 171 | If that commit is successful, your local check-out directory is then |
| 172 | switched to the tip of that branch, so subsequent commits don’t need the |
| 173 | “`--branch`” option. You have to switch back to the parent branch |
| 174 | explicitly, as with |
| 175 | |
| 176 | fossil update trunk # return to parent, “trunk” in this case |
| 177 | |
| 178 | Fossil does also support the Git style, creating the branch ahead of |
| 179 | need: |
| 180 | |
| 181 | fossil branch new my-new-branch |
| @@ -202,27 +239,27 @@ | |
| 202 | |
| 203 | <a id="autosync"></a> |
| 204 | ## Autosync |
| 205 | |
| 206 | Fossil’s [autosync][wflow] feature, normally enabled, has no |
| 207 | equivalent in Git. If you want Fossil to behave like Git, you will turn |
| 208 | it off: |
| 209 | |
| 210 | fossil set autosync 0 |
| 211 | |
| 212 | It’s better to understand what the feature does and why it is enabled by |
| 213 | default. |
| 214 | |
| 215 | When autosync is enabled, Fossil automatically pushes your changes |
| 216 | to the remote server whenever you "`fossil commit`", and it |
| 217 | pulls all remote changes down to your local clone of the repository as |
| 218 | part of a "`fossil update`". |
| 219 | This provides most of the advantages of a centralized version control |
| 220 | system while retaining the advantages of distributed version control: |
| 221 | |
| 222 | 1. Your work stays synced up with your coworkers as long as your |
| 223 | machine can connect to the remote repository, but at need, you can go |
| 224 | off-network and continue work atop the last version you sync’d with |
| 225 | the remote. |
| 226 | |
| 227 | 2. It provides immediate off-machine backup of your commits. Unlike |
| 228 | centralized version control, though, you can still work while |
| @@ -245,16 +282,17 @@ | |
| 245 | [setup]: ./caps/admin-v-setup.md#apsu |
| 246 | [wflow]: ./concepts.wiki#workflow |
| 247 | |
| 248 | |
| 249 | <a id="syncall"></a> |
| 250 | ## Syncing Is All-Or-Nothing |
| 251 | |
| 252 | Fossil does not support the concept of syncing, pushing, or pulling |
| 253 | individual branches. When you sync/push/pull in Fossil, you sync/push/pull |
| 254 | everything: all branches, all wiki, all tickets, all forum posts, |
| 255 | all tags, all technotes… Everything. |
| 256 | |
| 257 | Furthermore, branch *names* sync automatically in Fossil, not just the |
| 258 | content of those branches. This means this common Git command: |
| 259 | |
| 260 | git push origin master |
| @@ -365,29 +403,34 @@ | |
| 365 | fossil mv --hard old-name new-name |
| 366 | |
| 367 | [mv]: /help?cmd=mv |
| 368 | [rm]: /help?cmd=rm |
| 369 | |
| 370 | |
| 371 | <a id="morigin"></a> |
| 372 | ## Multiple "origin" Servers |
| 373 | |
| 374 | In this final section of the document, we’ll go into a lot more detail |
| 375 | to illustrate the points above, not just give a quick summary of this |
| 376 | single difference. |
| 377 | |
| 378 | Consider a common use case — at the time of this writing, during the |
| 379 | COVID-19 pandemic — where you’re working from home a lot, going into the |
| 380 | office maybe one part-day a week. Let us also say you have no remote |
| 381 | access back into the work LAN, such as because your site IT is paranoid |
| 382 | about security. You may still want off-machine backups of your commits, |
| 383 | so what you want is the ability to quickly switch between the “home” and |
| 384 | “work” remote repositories, with your laptop acting as a kind of |
| 385 | [sneakernet][sn] link between the big development server at the office |
| 386 | and your family’s home NAS. |
| 387 | |
| 388 | ### Git Method |
| 389 | |
| 390 | We first need to clone the work repo down to our laptop, so we can work on it |
| 391 | at home: |
| 392 | |
| 393 | git clone https://dev-server.example.com/repo |
| @@ -408,11 +451,11 @@ | |
| 408 | |
| 409 | Realize that this is carefully optimized down to these two long |
| 410 | commands. In practice, typing these commands by hand, from memory, we’d |
| 411 | expect a normal user to need to give four or more commands here instead. |
| 412 | Packing the “`git init`” call into the “`ssh`” call is something more |
| 413 | done in scripts and documentation examples than is done interactively, |
| 414 | which then necessitates a third command before the push, “`exit`”. |
| 415 | There’s also a good chance that you’ll forget the need for the `--bare` |
| 416 | option here to avoid a fatal complaint from Git that the laptop can’t |
| 417 | push into a non-empty repo. If you fall into this trap, among the many |
| 418 | that Git lays for newbies, you have to nuke the incorrectly initted |
| @@ -453,42 +496,36 @@ | |
| 453 | This example also shows a consequence of that fact that |
| 454 | [Git doesn’t sync branch names](#syncall): you have to keep repeating |
| 455 | yourself, “master, master.” |
| 456 | |
| 457 | |
| 458 | ### Fossil Method |
| 459 | |
| 460 | Now we’re going to do the same thing as above using Fossil. We’ve broken |
| 461 | the commands up into blocks corresponding to those above for comparison. |
| 462 | We start the same way, cloning the work repo down to the laptop: |
| 463 | |
| 464 | mkdir repo |
| 465 | cd repo |
| 466 | fossil open https://dev-server.example.com/repo |
| 467 | fossil remote add work https://dev-server.example.com/repo |
| 468 | |
| 469 | Unlike Git, Fossil’s “clone and open” feature doesn’t create the |
| 470 | directory for you, so we need an extra `mkdir` call here that isn’t |
| 471 | needed in the Git case. This is an indirect reflection of Fossil’s |
| 472 | [multiple working directories](#mwd) design philosophy: its |
| 473 | [`open` command][open] requires that you either issue it in an empty |
| 474 | directory or one containing a prior closed check-out. In exchange for |
| 475 | this extra command, we get the advantage of Fossil’s |
| 476 | [superior handling][shwmd] of multiple working directories. To get the |
| 477 | full power of this feature, you’d switch from the “`fossil open URI`” |
| 478 | command form to the separate clone-and-open form shown in |
| 479 | [the quick start guide][qs], which adds one more command. |
| 480 | |
| 481 | We can’t spin the longer final command as a trade-off giving us extra |
| 482 | power, though: the simple fact is, Fossil currently has no short command |
| 483 | to rename an existing remote. Worse, unlike with Git, we can’t just keep |
| 484 | using the default remote name because Fossil uses that slot in its |
| 485 | configuration database to store the *current* remote name, so on |
| 486 | switching from work to home, the home URL will overwrite the work URL if |
| 487 | we don’t give it an explicit name first. |
| 488 | |
| 489 | Keep these costs in perspective, however: they’re one-time setup costs, |
| 490 | easily amortized to insignificance by the shorter day-to-day commands |
| 491 | below. |
| 492 | |
| 493 | On first beginning to work from home, we reverse-clone the Fossil repo |
| 494 | up to the NAS: |
| 495 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -19,35 +19,44 @@ | |
| 19 | [1]: https://fossil-scm.org/forum |
| 20 | |
| 21 | Specific suggestions on how to improve this document are also welcomed, |
| 22 | of course. |
| 23 | |
| 24 | |
| 25 | |
| 26 | ## <a id="term"></a> Terminology |
| 27 | |
| 28 | While we do try to explain Fossil-specific terminology inline here |
| 29 | as-needed, you may find it helpful to skim [the Fossil glossary][gloss]. |
| 30 | It will give you another take on our definitions here, and it may help |
| 31 | you to understand some of the other Fossil docs better. |
| 32 | |
| 33 | |
| 34 | ---- |
| 35 | |
| 36 | |
| 37 | <a id="mwd"></a> |
| 38 | ## Repositories And Checkouts Are Distinct |
| 39 | |
| 40 | A repository and a check-out are distinct concepts in Fossil, whereas |
| 41 | the two are collocated by default with Git. |
| 42 | |
| 43 | A Fossil repository is a SQLite database storing |
| 44 | the entire history of a project. A Fossil check-out is a |
| 45 | directory that contains a snapshot of your project that you |
| 46 | are currently working on, extracted for you from that database by the |
| 47 | `fossil` program. |
| 48 | |
| 49 | With Git, cloning a repository gets you what Fossil would call a |
| 50 | check-out directory with the repository stored in a `.git` subdirectory |
| 51 | of that check-out. There are methods to get additional working directories |
| 52 | pointing at that same Git repository, but because it’s not designed into |
| 53 | the core concept of the tool, Git tutorials usually advocate a |
| 54 | switch-in-place working mode instead, so that is how most users end up |
| 55 | working with it. |
| 56 | |
| 57 | You can use Fossil the same way, switching between versions in a |
| 58 | single check-out directory: |
| 59 | |
| 60 | fossil clone https://example.com/repo /path/to/repo.fossil |
| 61 | mkdir work-dir |
| 62 | cd work-dir |
| @@ -54,32 +63,41 @@ | |
| 63 | fossil open /path/to/repo.fossil |
| 64 | ...work on trunk... |
| 65 | fossil update my-other-branch # like “git checkout” |
| 66 | ...work on your other branch in the same directory... |
| 67 | |
| 68 | As of Fossil 2.12, you can ask it to clone-and-open into a single directory, as Git |
| 69 | always has done: |
| 70 | |
| 71 | mkdir work-dir |
| 72 | cd work-dir |
| 73 | fossil open https://example.com/repo |
| 74 | |
| 75 | Now you have “trunk” open in `work-dir`, with the repo file stored as |
| 76 | `repo.fossil` in that same directory. |
| 77 | |
| 78 | You may be expecting [`fossil clone`][clone] to create a directory for |
| 79 | you like Git does, but because the repository is separate from the |
| 80 | working directory, it does not do that, on purpose: you have to tell it |
| 81 | where to store the repository file. |
| 82 | |
| 83 | The [`fossil open URI`][open] syntax is our compromise for users wanting |
| 84 | a clone-and-open command. But, because Fossil’s `open` command |
| 85 | historically opens into the current directory, and it won’t open a |
| 86 | repository into a non-empty directory by default — as of Fossil 2.12, |
| 87 | anyway — you have to create the directory manually and `cd` into it |
| 88 | before opening it. If `fossil open URI` worked like `git clone`, that |
| 89 | would mean `fossil open` has two different ways of working depending on |
| 90 | the argument, which is a non-Fossil sort of thing to do. We strive for |
| 91 | consistent behavior across commands and modes. |
| 92 | |
| 93 | The Fossil repository file can be named anything you want, with a single |
| 94 | exception: if you’re going to use the [`fossil server DIRECTORY`][server] |
| 95 | feature, the repositories need to have a "`.fossil`" suffix. That aside, |
| 96 | you can follow any other convention that makes sense to you. |
| 97 | |
| 98 | Many Fossil users gather all of their Fossil repositories |
| 99 | in a single directory on their machine, such as "`~/museum`" or |
| 100 | "`C:\Fossils`". This can help humans to keep their repositories |
| 101 | organized, but Fossil itself doesn't really care. (Why “museum”? |
| 102 | Because that is where one stores valuable fossils.) |
| 103 | |
| @@ -107,22 +125,23 @@ | |
| 125 | “scratch” directory for experiments or brief bits of work you don’t want |
| 126 | to do in the other check-out directories, and a directory for testing a |
| 127 | user report of a bug in the trunk version as of last April Fool’s Day. |
| 128 | Each check-out operates independently of the others. |
| 129 | |
| 130 | This multiple-checkouts working style is especially useful when Fossil stores source code in programming languages |
| 131 | where there is a “build” step that transforms source files into files |
| 132 | you actually run or distribute. With Git’s typical switch-in-place workflow, |
| 133 | you have to rebuild all outputs from the source files |
| 134 | that differ between those versions whenever you switch versions. In the above Fossil working model, |
| 135 | you switch versions with a “`cd`” command instead, so that you only have |
| 136 | to rebuild outputs from files you yourself change. |
| 137 | |
| 138 | This style is also useful when a check-out directory may be tied up with |
| 139 | some long-running process, as with the “test” example above, where you |
| 140 | might need to run an hours-long brute-force replication script to tickle |
| 141 | a [Heisenbug][hb], forcing it to show itself. While that runs, you can |
| 142 | open a new terminal tab, “`cd ../trunk`”, and get back |
| 143 | to work. |
| 144 | |
| 145 | Git users may be initially confused by the `.fslckout` file at the root |
| 146 | of a check-out directory. |
| 147 | This is not the same thing as `.git`. It’s a per-checkout SQLite |
| @@ -135,31 +154,47 @@ | |
| 154 | (In native Windows builds of Fossil, this file is called `_FOSSIL_` |
| 155 | instead to get around the historical 3-character extension limit with |
| 156 | certain legacy filesystems. “Native” here is a distinction to exclude |
| 157 | Cygwin and WSL builds, which use `.fslckout`.) |
| 158 | |
| 159 | [clone]: /help?cmd=clone |
| 160 | [close]: /help?cmd=close |
| 161 | [gloss]: ./whyusefossil.wiki#definitions |
| 162 | [hb]: https://en.wikipedia.org/wiki/Heisenbug |
| 163 | [open]: /help?cmd=open |
| 164 | [set]: /help?cmd=setting |
| 165 | [server]: /help?cmd=server |
| 166 | [stash]: /help?cmd=stash |
| 167 | [undo]: /help?cmd=undo |
| 168 | |
| 169 | |
| 170 | ## <a id="log"></a> Fossil’s Timeline is the “Log” |
| 171 | |
| 172 | Git users often need to use the `git log` command to grovel through |
| 173 | commit histories due to its [weak data model][wdm]. |
| 174 | |
| 175 | Fossil parses a huge amount of information out of commits that allow it |
| 176 | to produce its [timeline CLI][tlc] and [its `/timeline` web view][tlw], |
| 177 | which generally have the info you would have to manually extract from |
| 178 | `git log`. |
| 179 | |
| 180 | [tlc]: /help?cmd=timeline |
| 181 | [tlw]: /help?cmd=/timeline |
| 182 | [wdm]: ./fossil-v-git.wiki#durable |
| 183 | |
| 184 | |
| 185 | <a id="staging"></a> |
| 186 | ## There Is No Staging Area |
| 187 | |
| 188 | Fossil omits the "Git index" or "staging area" concept. When you |
| 189 | type "`fossil commit`" _all_ changes in your check-out are committed, |
| 190 | automatically. There is no need for the "-a" option as with Git. |
| 191 | |
| 192 | If you only want to commit _some_ of the changes, list the names |
| 193 | of the files or directories you want to commit as arguments, like this: |
| 194 | |
| 195 | fossil commit src/feature.c doc/feature.md examples/feature |
| 196 | |
| 197 | |
| 198 | <a id="bneed"></a> |
| 199 | ## Create Branches At Point Of Need, Rather Than Ahead of Need |
| 200 | |
| @@ -168,14 +203,16 @@ | |
| 203 | |
| 204 | fossil commit --branch my-new-branch |
| 205 | |
| 206 | If that commit is successful, your local check-out directory is then |
| 207 | switched to the tip of that branch, so subsequent commits don’t need the |
| 208 | “`--branch`” option. You simply say `fossil commit` again to continue |
| 209 | adding commits to the tip of that branch. |
| 210 | |
| 211 | To switch back to the parent branch, say something like: |
| 212 | |
| 213 | fossil update trunk # like “git checkout” |
| 214 | |
| 215 | Fossil does also support the Git style, creating the branch ahead of |
| 216 | need: |
| 217 | |
| 218 | fossil branch new my-new-branch |
| @@ -202,27 +239,27 @@ | |
| 239 | |
| 240 | <a id="autosync"></a> |
| 241 | ## Autosync |
| 242 | |
| 243 | Fossil’s [autosync][wflow] feature, normally enabled, has no |
| 244 | equivalent in Git. If you want Fossil to behave like Git, you can turn |
| 245 | it off: |
| 246 | |
| 247 | fossil set autosync 0 |
| 248 | |
| 249 | However, it’s better to understand what the feature does and why it is enabled by |
| 250 | default. |
| 251 | |
| 252 | When autosync is enabled, Fossil automatically pushes your changes |
| 253 | to the remote server whenever you "`fossil commit`", and it |
| 254 | pulls all remote changes down to your local clone of the repository as |
| 255 | part of a "`fossil update`". |
| 256 | This provides most of the advantages of a centralized version control |
| 257 | system while retaining the advantages of distributed version control: |
| 258 | |
| 259 | 1. Your work stays synced up with your coworkers’ efforts as long as your |
| 260 | machine can connect to the remote repository. At need, you can go |
| 261 | off-network and continue work atop the last version you sync’d with |
| 262 | the remote. |
| 263 | |
| 264 | 2. It provides immediate off-machine backup of your commits. Unlike |
| 265 | centralized version control, though, you can still work while |
| @@ -245,16 +282,17 @@ | |
| 282 | [setup]: ./caps/admin-v-setup.md#apsu |
| 283 | [wflow]: ./concepts.wiki#workflow |
| 284 | |
| 285 | |
| 286 | <a id="syncall"></a> |
| 287 | ## Sync Is All-Or-Nothing |
| 288 | |
| 289 | Fossil does not support the concept of syncing, pushing, or pulling |
| 290 | individual branches. When you sync/push/pull in Fossil, you |
| 291 | sync/push/pull everything stored as artifacts in its hash tree: |
| 292 | branches, tags, wiki articles, tickets, forum posts, technotes… |
| 293 | [Almost everything][bu]. |
| 294 | |
| 295 | Furthermore, branch *names* sync automatically in Fossil, not just the |
| 296 | content of those branches. This means this common Git command: |
| 297 | |
| 298 | git push origin master |
| @@ -365,29 +403,34 @@ | |
| 403 | fossil mv --hard old-name new-name |
| 404 | |
| 405 | [mv]: /help?cmd=mv |
| 406 | [rm]: /help?cmd=rm |
| 407 | |
| 408 | |
| 409 | ---- |
| 410 | |
| 411 | |
| 412 | <a id="morigin"></a> |
| 413 | ## Multiple "origin" Servers |
| 414 | |
| 415 | In this final section of the document, we’ll go into a lot more detail |
| 416 | to illustrate the points above, not just give a quick summary of this |
| 417 | single difference. |
| 418 | |
| 419 | Consider a common use case at the time of this writing — during the |
| 420 | COVID-19 pandemic — where you’re working from home a lot, going into the |
| 421 | office one part-day a week only to do things that have to be done |
| 422 | on-site at the office. Let us also say you have no remote |
| 423 | access back into the work LAN, such as because your site IT is paranoid |
| 424 | about security. You may still want off-machine backups of your commits |
| 425 | while working from home, |
| 426 | so you need the ability to quickly switch between the “home” and |
| 427 | “work” remote repositories, with your laptop acting as a kind of |
| 428 | [sneakernet][sn] link between the big development server at the office |
| 429 | and your family’s home NAS. |
| 430 | |
| 431 | #### Git Method |
| 432 | |
| 433 | We first need to clone the work repo down to our laptop, so we can work on it |
| 434 | at home: |
| 435 | |
| 436 | git clone https://dev-server.example.com/repo |
| @@ -408,11 +451,11 @@ | |
| 451 | |
| 452 | Realize that this is carefully optimized down to these two long |
| 453 | commands. In practice, typing these commands by hand, from memory, we’d |
| 454 | expect a normal user to need to give four or more commands here instead. |
| 455 | Packing the “`git init`” call into the “`ssh`” call is something more |
| 456 | often done in scripts and documentation examples than done interactively, |
| 457 | which then necessitates a third command before the push, “`exit`”. |
| 458 | There’s also a good chance that you’ll forget the need for the `--bare` |
| 459 | option here to avoid a fatal complaint from Git that the laptop can’t |
| 460 | push into a non-empty repo. If you fall into this trap, among the many |
| 461 | that Git lays for newbies, you have to nuke the incorrectly initted |
| @@ -453,42 +496,36 @@ | |
| 496 | This example also shows a consequence of that fact that |
| 497 | [Git doesn’t sync branch names](#syncall): you have to keep repeating |
| 498 | yourself, “master, master.” |
| 499 | |
| 500 | |
| 501 | #### Fossil Method |
| 502 | |
| 503 | Now we’re going to do the same thing as above using Fossil. We’ve broken |
| 504 | the commands up into blocks corresponding to those above for comparison. |
| 505 | |
| 506 | We start the same way, cloning the work repo down to the laptop: |
| 507 | |
| 508 | mkdir repo |
| 509 | cd repo |
| 510 | fossil open https://dev-server.example.com/repo |
| 511 | fossil remote add work https://dev-server.example.com/repo |
| 512 | |
| 513 | We’ve chosen the “`fossil open URI`” syntax here rather than separate |
| 514 | `clone` and `open` commands to make the parallel with Git clearer. [See |
| 515 | above](#mwd) for more on that topic. |
| 516 | |
| 517 | The final command is longer than the Git equivalent because |
| 518 | Fossil currently has no short command |
| 519 | to rename an existing remote. Worse, unlike with Git, we can’t just keep |
| 520 | using the default remote name because Fossil uses that slot in its |
| 521 | configuration database to store the *current* remote name, so on |
| 522 | switching from work to home, the home URL will overwrite the work URL if |
| 523 | we don’t give it an explicit name first. |
| 524 | |
| 525 | So far, the Fossil commands are longer, but keep these costs in perspective: |
| 526 | they’re one-time setup costs, |
| 527 | easily amortized to insignificance by the shorter day-to-day commands |
| 528 | below. |
| 529 | |
| 530 | On first beginning to work from home, we reverse-clone the Fossil repo |
| 531 | up to the NAS: |
| 532 |