Fossil SCM
Added a new "multiple origin servers" section to the gitusers doc to replace the obsolete one just removed. This not only shows off Fossil's new "fossil remote add" feature set, it acts as a sort of white paper comparing Git to Fossil in a common use case scenario.
Commit
e3cef726f2c273f4047b933940ba712f58da296bfd93f9b955315f348df32861
Parent
2306f8164def9e2…
1 file changed
+165
+165
| --- www/gitusers.md | ||
| +++ www/gitusers.md | ||
| @@ -249,5 +249,170 @@ | ||
| 249 | 249 | |
| 250 | 250 | fossil mv --hard old-name new-name |
| 251 | 251 | |
| 252 | 252 | [mv]: /help?cmd=mv |
| 253 | 253 | [rm]: /help?cmd=rm |
| 254 | + | |
| 255 | + | |
| 256 | +<a id="morigin"></a> | |
| 257 | +## Multiple "origin" Servers | |
| 258 | + | |
| 259 | +In this final section of the document, we’ll go into a lot more detail | |
| 260 | +to illustrate the points above, not just give a quick summary of this | |
| 261 | +single difference. | |
| 262 | + | |
| 263 | +Consider a common use case — at the time of this writing, during the | |
| 264 | +COVID-19 pandemic — where you’re working from home a lot, going into the | |
| 265 | +office maybe one part-day a week. Let us also say you have no remote | |
| 266 | +access back into the work LAN, such as because your site IT is paranoid | |
| 267 | +about security. You may still want off-machine backups of your commits, | |
| 268 | +so what you want is the ability to quickly switch between the “home” and | |
| 269 | +“work” remote repositories, with your laptop acting as a kind of | |
| 270 | +[sneakernet][sn] link between the big development server at the office | |
| 271 | +and your family’s home NAS. | |
| 272 | + | |
| 273 | +### Git Method | |
| 274 | + | |
| 275 | +We first need to clone the work repo down to our laptop, so we can work on it | |
| 276 | +at home: | |
| 277 | + | |
| 278 | + git clone https://dev-server.example.com/repo | |
| 279 | + cd repo | |
| 280 | + git remote rename origin work | |
| 281 | + | |
| 282 | +The last command is optional, strictly speaking. We could continue to | |
| 283 | +use Git’s default name for the work repo’s origin — sensibly enough | |
| 284 | +called “`origin`” — but it makes later commands harder to understand, so | |
| 285 | +we rename it here. This will also make the parallel with Fossil easier | |
| 286 | +to draw. | |
| 287 | + | |
| 288 | +The first time we go home after this, we have to reverse-clone the work | |
| 289 | +repo up to the NAS: | |
| 290 | + | |
| 291 | + ssh my-nas.local 'git init --bare /SHARES/dayjob/repo.git' | |
| 292 | + git push --all ssh://my-nas.local//SHARES/dayjob/repo.git | |
| 293 | + | |
| 294 | +Now we can tell Git that there is a second origin, a “home” repo in | |
| 295 | +addition to the named “work” repo we set up earlier: | |
| 296 | + | |
| 297 | + git remote add home ssh://my-nas.local//SHARES/dayjob/repo.git | |
| 298 | + git config master.remote home | |
| 299 | + | |
| 300 | +We don’t have to push or pull because the remote repo is a complete | |
| 301 | +clone of the repo on the laptop at this point, so we can just get to | |
| 302 | +work now, committing along the way to get our work safely off-machine | |
| 303 | +and onto the NAS, like so: | |
| 304 | + | |
| 305 | + git add | |
| 306 | + git commit | |
| 307 | + git push | |
| 308 | + | |
| 309 | +We didn’t need to give a remote name on the push because we told it the | |
| 310 | +new upstream is the home NAS earlier. | |
| 311 | + | |
| 312 | +Now Friday comes along, and one of your office-mates needs a feature | |
| 313 | +you’re working on. You agree to come into the office later that | |
| 314 | +afternoon to sync up via the dev server: | |
| 315 | + | |
| 316 | + git push work master # send your changes from home up | |
| 317 | + git pull work master # get your coworkers’ changes | |
| 318 | + | |
| 319 | +Because we didn’t use `--set-upstream/-u` here, we have to name the | |
| 320 | +“work” origin explicitly in these commands. (This also shows Git’s | |
| 321 | +unwillingness to sync branch names, covered elsewhere in this document.) | |
| 322 | + | |
| 323 | +### Fossil Method | |
| 324 | + | |
| 325 | +Now we’re going to do the same thing as above using Fossil. We’ve broken | |
| 326 | +the commands up into blocks corresponding to those above for comparison. | |
| 327 | +We start the same way, cloning the work repo down to the laptop: | |
| 328 | + | |
| 329 | + mkdir repo | |
| 330 | + cd repo | |
| 331 | + fossil open https://dev-server.example.com/repo | |
| 332 | + fossil remote add work https://dev-server.example.com/repo | |
| 333 | + | |
| 334 | +Unlike Git, Fossil’s “clone and open” feature doesn’t create the | |
| 335 | +directory for you, so we need an extra `mkdir` call here that isn’t | |
| 336 | +needed in the Git case. This is an indirect reflection of Fossil’s | |
| 337 | +[multiple working directories](#mwd) design philosophy: its | |
| 338 | +[`open` command][open] requires that you either issue it in an empty | |
| 339 | +directory or one containing a prior closed checkout. In exchange for | |
| 340 | +this extra command, we get the advantage of Fossil’s | |
| 341 | +[superior handling][shwmd] of multiple working directories. To get the | |
| 342 | +full power of this feature, you’d switch from the “`fossil open URI`” | |
| 343 | +command form to the separate clone-and-open form shown in | |
| 344 | +[the quick start guide][qs], which adds one more command. | |
| 345 | + | |
| 346 | +We can’t spin the longer final command as a trade-off giving us extra | |
| 347 | +power, though: the simple fact is, Fossil currently has no short command | |
| 348 | +to rename an existing remote. Worse, unlike with Git, we can’t just keep | |
| 349 | +using the default remote name because Fossil uses that slot in its | |
| 350 | +configuration database to store the *current* remote name, so on | |
| 351 | +switching from work to home, the home URL will overwrite the work URL if | |
| 352 | +we don’t give it an explicit name first. | |
| 353 | + | |
| 354 | +Keep these costs in perspective, however: they’re one-time setup costs, | |
| 355 | +easily amortized to insignificance by the shorter day-to-day commands | |
| 356 | +below. | |
| 357 | + | |
| 358 | +On first beginning to work from home, we reverse-clone the Fossil repo | |
| 359 | +up to the NAS: | |
| 360 | + | |
| 361 | + rsync repo.fossil my-nas.local:/SHARES/dayjob/ | |
| 362 | + | |
| 363 | +Now we’re beginning to see the advantage of Fossil’s simpler model, | |
| 364 | +relative the tricky “`git init && git push`” sequence above. It’d be | |
| 365 | +four commands instead of two if you weren’t clever enough to pack the | |
| 366 | +init into an `ssh` command, and unless you’re well versed with Git, | |
| 367 | +you’ll probably forget to give the `--bare` option the first time, | |
| 368 | +adding more commands as you blow the first attempt away and try again. | |
| 369 | +Contrast the Fossil alternative, which is almost impossible to get | |
| 370 | +wrong: copy this to that. *Done.* | |
| 371 | + | |
| 372 | +We’re relying on the `rsync` feature that creates up to one level of | |
| 373 | +missing directory (here, `dayjob/`) on the remote. If you know in | |
| 374 | +advance that the remote directory already exists, you could use a | |
| 375 | +slightly shorter `scp` command instead. Even with the extra 2 characters | |
| 376 | +in the `rsync` form, it’s much shorter because a Fossil repository is a | |
| 377 | +single SQLite database file, not a tree containing a pile of assorted | |
| 378 | +files. Because of this, it works reliably without any of [the caveats | |
| 379 | +inherent in using `rsync` to clone a Git repo][grsync]. | |
| 380 | + | |
| 381 | +Now we set up the second remote, which is again simpler in the Fossil | |
| 382 | +case: | |
| 383 | + | |
| 384 | + fossil remote add home ssh://my-nas.local//SHARES/dayjob/repo.fossil | |
| 385 | + fossil remote home | |
| 386 | + | |
| 387 | +The first command is nearly identical to the Git version, but the second | |
| 388 | +is considerably simpler. And to be fair, you won’t find that second | |
| 389 | +command in all Git tutorials: the more common one we found with web | |
| 390 | +searches is “`git push --set-upstream home master`”. Not only is it | |
| 391 | +longer, it’s wasteful to do it that way in the example above because | |
| 392 | +we’re working with a just-created remote clone of the local repo, so | |
| 393 | +doing this via “push” makes Git do pointless extra work. | |
| 394 | + | |
| 395 | +Where Fossil really wins is in the next step, making the initial commit | |
| 396 | +from home: | |
| 397 | + | |
| 398 | + fossil ci | |
| 399 | + | |
| 400 | +It’s one short command for Fossil instead of three for Git — or two if | |
| 401 | +you abbreviate it as “`git commit -a && git push`” — because of Fossil’s | |
| 402 | +[autosync feature](#autosync) feature and deliberate omission of a | |
| 403 | +[staging feature](#staging). | |
| 404 | + | |
| 405 | +The “Friday afternoon sync-up” case is simpler, too: | |
| 406 | + | |
| 407 | + fossil remote work | |
| 408 | + fossil sync | |
| 409 | + | |
| 410 | +Back at home, it’s even simpler: we can do away with the second command, | |
| 411 | +saying just “`fossil remote home`” because the sync will happen as part | |
| 412 | +of the next commit, thanks once again to Fossil’s autosync feature. | |
| 413 | + | |
| 414 | +[grsync]: https://stackoverflow.com/q/1398018/142454 | |
| 415 | +[open]: /help?cmd=open | |
| 416 | +[qs]: ./quickstart.wiki | |
| 417 | +[shwmd]: ./fossil-v-git.wiki#checkouts | |
| 418 | +[sn]: https://en.wikipedia.org/wiki/Sneakernet | |
| 254 | 419 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -249,5 +249,170 @@ | |
| 249 | |
| 250 | fossil mv --hard old-name new-name |
| 251 | |
| 252 | [mv]: /help?cmd=mv |
| 253 | [rm]: /help?cmd=rm |
| 254 |
| --- www/gitusers.md | |
| +++ www/gitusers.md | |
| @@ -249,5 +249,170 @@ | |
| 249 | |
| 250 | fossil mv --hard old-name new-name |
| 251 | |
| 252 | [mv]: /help?cmd=mv |
| 253 | [rm]: /help?cmd=rm |
| 254 | |
| 255 | |
| 256 | <a id="morigin"></a> |
| 257 | ## Multiple "origin" Servers |
| 258 | |
| 259 | In this final section of the document, we’ll go into a lot more detail |
| 260 | to illustrate the points above, not just give a quick summary of this |
| 261 | single difference. |
| 262 | |
| 263 | Consider a common use case — at the time of this writing, during the |
| 264 | COVID-19 pandemic — where you’re working from home a lot, going into the |
| 265 | office maybe one part-day a week. Let us also say you have no remote |
| 266 | access back into the work LAN, such as because your site IT is paranoid |
| 267 | about security. You may still want off-machine backups of your commits, |
| 268 | so what you want is the ability to quickly switch between the “home” and |
| 269 | “work” remote repositories, with your laptop acting as a kind of |
| 270 | [sneakernet][sn] link between the big development server at the office |
| 271 | and your family’s home NAS. |
| 272 | |
| 273 | ### Git Method |
| 274 | |
| 275 | We first need to clone the work repo down to our laptop, so we can work on it |
| 276 | at home: |
| 277 | |
| 278 | git clone https://dev-server.example.com/repo |
| 279 | cd repo |
| 280 | git remote rename origin work |
| 281 | |
| 282 | The last command is optional, strictly speaking. We could continue to |
| 283 | use Git’s default name for the work repo’s origin — sensibly enough |
| 284 | called “`origin`” — but it makes later commands harder to understand, so |
| 285 | we rename it here. This will also make the parallel with Fossil easier |
| 286 | to draw. |
| 287 | |
| 288 | The first time we go home after this, we have to reverse-clone the work |
| 289 | repo up to the NAS: |
| 290 | |
| 291 | ssh my-nas.local 'git init --bare /SHARES/dayjob/repo.git' |
| 292 | git push --all ssh://my-nas.local//SHARES/dayjob/repo.git |
| 293 | |
| 294 | Now we can tell Git that there is a second origin, a “home” repo in |
| 295 | addition to the named “work” repo we set up earlier: |
| 296 | |
| 297 | git remote add home ssh://my-nas.local//SHARES/dayjob/repo.git |
| 298 | git config master.remote home |
| 299 | |
| 300 | We don’t have to push or pull because the remote repo is a complete |
| 301 | clone of the repo on the laptop at this point, so we can just get to |
| 302 | work now, committing along the way to get our work safely off-machine |
| 303 | and onto the NAS, like so: |
| 304 | |
| 305 | git add |
| 306 | git commit |
| 307 | git push |
| 308 | |
| 309 | We didn’t need to give a remote name on the push because we told it the |
| 310 | new upstream is the home NAS earlier. |
| 311 | |
| 312 | Now Friday comes along, and one of your office-mates needs a feature |
| 313 | you’re working on. You agree to come into the office later that |
| 314 | afternoon to sync up via the dev server: |
| 315 | |
| 316 | git push work master # send your changes from home up |
| 317 | git pull work master # get your coworkers’ changes |
| 318 | |
| 319 | Because we didn’t use `--set-upstream/-u` here, we have to name the |
| 320 | “work” origin explicitly in these commands. (This also shows Git’s |
| 321 | unwillingness to sync branch names, covered elsewhere in this document.) |
| 322 | |
| 323 | ### Fossil Method |
| 324 | |
| 325 | Now we’re going to do the same thing as above using Fossil. We’ve broken |
| 326 | the commands up into blocks corresponding to those above for comparison. |
| 327 | We start the same way, cloning the work repo down to the laptop: |
| 328 | |
| 329 | mkdir repo |
| 330 | cd repo |
| 331 | fossil open https://dev-server.example.com/repo |
| 332 | fossil remote add work https://dev-server.example.com/repo |
| 333 | |
| 334 | Unlike Git, Fossil’s “clone and open” feature doesn’t create the |
| 335 | directory for you, so we need an extra `mkdir` call here that isn’t |
| 336 | needed in the Git case. This is an indirect reflection of Fossil’s |
| 337 | [multiple working directories](#mwd) design philosophy: its |
| 338 | [`open` command][open] requires that you either issue it in an empty |
| 339 | directory or one containing a prior closed checkout. In exchange for |
| 340 | this extra command, we get the advantage of Fossil’s |
| 341 | [superior handling][shwmd] of multiple working directories. To get the |
| 342 | full power of this feature, you’d switch from the “`fossil open URI`” |
| 343 | command form to the separate clone-and-open form shown in |
| 344 | [the quick start guide][qs], which adds one more command. |
| 345 | |
| 346 | We can’t spin the longer final command as a trade-off giving us extra |
| 347 | power, though: the simple fact is, Fossil currently has no short command |
| 348 | to rename an existing remote. Worse, unlike with Git, we can’t just keep |
| 349 | using the default remote name because Fossil uses that slot in its |
| 350 | configuration database to store the *current* remote name, so on |
| 351 | switching from work to home, the home URL will overwrite the work URL if |
| 352 | we don’t give it an explicit name first. |
| 353 | |
| 354 | Keep these costs in perspective, however: they’re one-time setup costs, |
| 355 | easily amortized to insignificance by the shorter day-to-day commands |
| 356 | below. |
| 357 | |
| 358 | On first beginning to work from home, we reverse-clone the Fossil repo |
| 359 | up to the NAS: |
| 360 | |
| 361 | rsync repo.fossil my-nas.local:/SHARES/dayjob/ |
| 362 | |
| 363 | Now we’re beginning to see the advantage of Fossil’s simpler model, |
| 364 | relative the tricky “`git init && git push`” sequence above. It’d be |
| 365 | four commands instead of two if you weren’t clever enough to pack the |
| 366 | init into an `ssh` command, and unless you’re well versed with Git, |
| 367 | you’ll probably forget to give the `--bare` option the first time, |
| 368 | adding more commands as you blow the first attempt away and try again. |
| 369 | Contrast the Fossil alternative, which is almost impossible to get |
| 370 | wrong: copy this to that. *Done.* |
| 371 | |
| 372 | We’re relying on the `rsync` feature that creates up to one level of |
| 373 | missing directory (here, `dayjob/`) on the remote. If you know in |
| 374 | advance that the remote directory already exists, you could use a |
| 375 | slightly shorter `scp` command instead. Even with the extra 2 characters |
| 376 | in the `rsync` form, it’s much shorter because a Fossil repository is a |
| 377 | single SQLite database file, not a tree containing a pile of assorted |
| 378 | files. Because of this, it works reliably without any of [the caveats |
| 379 | inherent in using `rsync` to clone a Git repo][grsync]. |
| 380 | |
| 381 | Now we set up the second remote, which is again simpler in the Fossil |
| 382 | case: |
| 383 | |
| 384 | fossil remote add home ssh://my-nas.local//SHARES/dayjob/repo.fossil |
| 385 | fossil remote home |
| 386 | |
| 387 | The first command is nearly identical to the Git version, but the second |
| 388 | is considerably simpler. And to be fair, you won’t find that second |
| 389 | command in all Git tutorials: the more common one we found with web |
| 390 | searches is “`git push --set-upstream home master`”. Not only is it |
| 391 | longer, it’s wasteful to do it that way in the example above because |
| 392 | we’re working with a just-created remote clone of the local repo, so |
| 393 | doing this via “push” makes Git do pointless extra work. |
| 394 | |
| 395 | Where Fossil really wins is in the next step, making the initial commit |
| 396 | from home: |
| 397 | |
| 398 | fossil ci |
| 399 | |
| 400 | It’s one short command for Fossil instead of three for Git — or two if |
| 401 | you abbreviate it as “`git commit -a && git push`” — because of Fossil’s |
| 402 | [autosync feature](#autosync) feature and deliberate omission of a |
| 403 | [staging feature](#staging). |
| 404 | |
| 405 | The “Friday afternoon sync-up” case is simpler, too: |
| 406 | |
| 407 | fossil remote work |
| 408 | fossil sync |
| 409 | |
| 410 | Back at home, it’s even simpler: we can do away with the second command, |
| 411 | saying just “`fossil remote home`” because the sync will happen as part |
| 412 | of the next commit, thanks once again to Fossil’s autosync feature. |
| 413 | |
| 414 | [grsync]: https://stackoverflow.com/q/1398018/142454 |
| 415 | [open]: /help?cmd=open |
| 416 | [qs]: ./quickstart.wiki |
| 417 | [shwmd]: ./fossil-v-git.wiki#checkouts |
| 418 | [sn]: https://en.wikipedia.org/wiki/Sneakernet |
| 419 |